src/network/network.cpp
changeset 9420 8a38703928e8
parent 9413 7042a8ec3fa8
child 9428 1ba05b499957
equal deleted inserted replaced
9419:c5b9860081a1 9420:8a38703928e8
   214 {
   214 {
   215 	int lag = cs->last_frame_server - cs->last_frame;
   215 	int lag = cs->last_frame_server - cs->last_frame;
   216 	// This client has missed his ACK packet after 1 DAY_TICKS..
   216 	// This client has missed his ACK packet after 1 DAY_TICKS..
   217 	//  so we increase his lag for every frame that passes!
   217 	//  so we increase his lag for every frame that passes!
   218 	// The packet can be out by a max of _net_frame_freq
   218 	// The packet can be out by a max of _net_frame_freq
   219 	if (cs->last_frame_server + DAY_TICKS + _network_frame_freq < _frame_counter)
   219 	if (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq < _frame_counter)
   220 		lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _network_frame_freq);
   220 		lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq);
   221 
   221 
   222 	return lag;
   222 	return lag;
   223 }
   223 }
   224 
   224 
   225 
   225 
   330 /* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */
   330 /* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */
   331 void CheckMinPlayers()
   331 void CheckMinPlayers()
   332 {
   332 {
   333 	if (!_network_dedicated) return;
   333 	if (!_network_dedicated) return;
   334 
   334 
   335 	if (NetworkCountPlayers() < _network_min_players) {
   335 	if (NetworkCountPlayers() < _settings_client.network.min_players) {
   336 		if (_min_players_paused) return;
   336 		if (_min_players_paused) return;
   337 
   337 
   338 		_min_players_paused = true;
   338 		_min_players_paused = true;
   339 		DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
   339 		DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
   340 		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX);
   340 		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX);
   660 			}
   660 			}
   661 		}
   661 		}
   662 	}
   662 	}
   663 
   663 
   664 	/* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */
   664 	/* When the client was PRE_ACTIVE, the server was in pause mode, so unpause */
   665 	if (cs->status == STATUS_PRE_ACTIVE && _network_pause_on_join) {
   665 	if (cs->status == STATUS_PRE_ACTIVE && _settings_client.network.pause_on_join) {
   666 		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
   666 		DoCommandP(0, 0, 0, NULL, CMD_PAUSE);
   667 		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX);
   667 		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused", NETWORK_SERVER_INDEX);
   668 	}
   668 	}
   669 
   669 
   670 	cs->Destroy();
   670 	cs->Destroy();
   800 static bool NetworkListen()
   800 static bool NetworkListen()
   801 {
   801 {
   802 	SOCKET ls;
   802 	SOCKET ls;
   803 	struct sockaddr_in sin;
   803 	struct sockaddr_in sin;
   804 
   804 
   805 	DEBUG(net, 1, "Listening on %s:%d", _network_server_bind_ip_host, _network_server_port);
   805 	DEBUG(net, 1, "Listening on %s:%d", _settings_client.network.server_bind_ip, _settings_client.network.server_port);
   806 
   806 
   807 	ls = socket(AF_INET, SOCK_STREAM, 0);
   807 	ls = socket(AF_INET, SOCK_STREAM, 0);
   808 	if (ls == INVALID_SOCKET) {
   808 	if (ls == INVALID_SOCKET) {
   809 		ServerStartError("socket() on listen socket failed");
   809 		ServerStartError("socket() on listen socket failed");
   810 		return false;
   810 		return false;
   821 
   821 
   822 	if (!SetNonBlocking(ls)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
   822 	if (!SetNonBlocking(ls)) DEBUG(net, 0, "Setting non-blocking mode failed"); // XXX should this be an error?
   823 
   823 
   824 	sin.sin_family = AF_INET;
   824 	sin.sin_family = AF_INET;
   825 	sin.sin_addr.s_addr = _network_server_bind_ip;
   825 	sin.sin_addr.s_addr = _network_server_bind_ip;
   826 	sin.sin_port = htons(_network_server_port);
   826 	sin.sin_port = htons(_settings_client.network.server_port);
   827 
   827 
   828 	if (bind(ls, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
   828 	if (bind(ls, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
   829 		ServerStartError("bind() failed");
   829 		ServerStartError("bind() failed");
   830 		return false;
   830 		return false;
   831 	}
   831 	}
   921 		char host[NETWORK_HOSTNAME_LENGTH];
   921 		char host[NETWORK_HOSTNAME_LENGTH];
   922 		uint16 rport;
   922 		uint16 rport;
   923 
   923 
   924 		ttd_strlcpy(host, b, lengthof(host));
   924 		ttd_strlcpy(host, b, lengthof(host));
   925 
   925 
   926 		ttd_strlcpy(_network_default_ip, b, lengthof(_network_default_ip));
   926 		ttd_strlcpy(_settings_client.network.connect_to_ip, b, lengthof(_settings_client.network.connect_to_ip));
   927 		rport = NETWORK_DEFAULT_PORT;
   927 		rport = NETWORK_DEFAULT_PORT;
   928 
   928 
   929 		ParseConnectionString(&player, &port, host);
   929 		ParseConnectionString(&player, &port, host);
   930 		if (port != NULL) rport = atoi(port);
   930 		if (port != NULL) rport = atoi(port);
   931 
   931 
   959 {
   959 {
   960 	if (!_network_available) return false;
   960 	if (!_network_available) return false;
   961 
   961 
   962 	if (port == 0) return false;
   962 	if (port == 0) return false;
   963 
   963 
   964 	ttd_strlcpy(_network_last_host, host, sizeof(_network_last_host));
   964 	ttd_strlcpy(_settings_client.network.last_host, host, sizeof(_settings_client.network.last_host));
   965 	_network_last_port = port;
   965 	_settings_client.network.last_port = port;
   966 
   966 
   967 	NetworkDisconnect();
   967 	NetworkDisconnect();
   968 	NetworkUDPCloseAll();
   968 	NetworkUDPCloseAll();
   969 	NetworkInitialize();
   969 	NetworkInitialize();
   970 
   970 
   985 
   985 
   986 static void NetworkInitGameInfo()
   986 static void NetworkInitGameInfo()
   987 {
   987 {
   988 	NetworkClientInfo *ci;
   988 	NetworkClientInfo *ci;
   989 
   989 
   990 	ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
   990 	_network_game_info.clients_max    = _settings_client.network.max_clients;
   991 	ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
   991 	_network_game_info.companies_max  = _settings_client.network.max_companies;
   992 	ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_rcon_password));
   992 	_network_game_info.spectators_max = _settings_client.network.max_spectators;
   993 	if (_network_game_info.server_name[0] == '\0')
   993 	_network_game_info.server_lang    = _settings_client.network.server_lang;
       
   994 	ttd_strlcpy(_network_game_info.server_name, _settings_client.network.server_name, sizeof(_network_game_info.server_name));
       
   995 	ttd_strlcpy(_network_game_info.server_password, _settings_client.network.server_password, sizeof(_network_game_info.server_password));
       
   996 	ttd_strlcpy(_network_game_info.rcon_password, _settings_client.network.rcon_password, sizeof(_network_game_info.rcon_password));
       
   997 	if (StrEmpty(_network_game_info.server_name)) {
   994 		snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server");
   998 		snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server");
       
   999 	}
   995 
  1000 
   996 	ttd_strlcpy(_network_game_info.server_revision, _openttd_revision, sizeof(_network_game_info.server_revision));
  1001 	ttd_strlcpy(_network_game_info.server_revision, _openttd_revision, sizeof(_network_game_info.server_revision));
   997 
  1002 
   998 	// The server is a client too ;)
  1003 	// The server is a client too ;)
   999 	if (_network_dedicated) {
  1004 	if (_network_dedicated) {
  1012 	_network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
  1017 	_network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
  1013 	_network_game_info.map_width = MapSizeX();
  1018 	_network_game_info.map_width = MapSizeX();
  1014 	_network_game_info.map_height = MapSizeY();
  1019 	_network_game_info.map_height = MapSizeY();
  1015 	_network_game_info.map_set = _settings_game.game_creation.landscape;
  1020 	_network_game_info.map_set = _settings_game.game_creation.landscape;
  1016 
  1021 
  1017 	_network_game_info.use_password = (_network_server_password[0] != '\0');
  1022 	_network_game_info.use_password = !StrEmpty(_settings_client.network.server_password);
  1018 
  1023 
  1019 	// We use _network_client_info[MAX_CLIENT_INFO - 1] to store the server-data in it
  1024 	// We use _network_client_info[MAX_CLIENT_INFO - 1] to store the server-data in it
  1020 	//  The index is NETWORK_SERVER_INDEX ( = 1)
  1025 	//  The index is NETWORK_SERVER_INDEX ( = 1)
  1021 	ci = &_network_client_info[MAX_CLIENT_INFO - 1];
  1026 	ci = &_network_client_info[MAX_CLIENT_INFO - 1];
  1022 	memset(ci, 0, sizeof(*ci));
  1027 	memset(ci, 0, sizeof(*ci));
  1023 
  1028 
  1024 	ci->client_index = NETWORK_SERVER_INDEX;
  1029 	ci->client_index = NETWORK_SERVER_INDEX;
  1025 	ci->client_playas = _network_dedicated ? PLAYER_SPECTATOR : _local_player;
  1030 	ci->client_playas = _network_dedicated ? PLAYER_SPECTATOR : _local_player;
  1026 
  1031 
  1027 	ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
  1032 	ttd_strlcpy(ci->client_name, _settings_client.network.player_name, sizeof(ci->client_name));
  1028 	ttd_strlcpy(ci->unique_id, _network_unique_id, sizeof(ci->unique_id));
  1033 	ttd_strlcpy(ci->unique_id, _settings_client.network.network_id, sizeof(ci->unique_id));
  1029 }
  1034 }
  1030 
  1035 
  1031 bool NetworkServerStart()
  1036 bool NetworkServerStart()
  1032 {
  1037 {
  1033 	if (!_network_available) return false;
  1038 	if (!_network_available) return false;
  1039 	NetworkInitialize();
  1044 	NetworkInitialize();
  1040 	if (!NetworkListen()) return false;
  1045 	if (!NetworkListen()) return false;
  1041 
  1046 
  1042 	// Try to start UDP-server
  1047 	// Try to start UDP-server
  1043 	_network_udp_server = true;
  1048 	_network_udp_server = true;
  1044 	_network_udp_server = _udp_server_socket->Listen(_network_server_bind_ip, _network_server_port, false);
  1049 	_network_udp_server = _udp_server_socket->Listen(_network_server_bind_ip, _settings_client.network.server_port, false);
  1045 
  1050 
  1046 	_network_server = true;
  1051 	_network_server = true;
  1047 	_networking = true;
  1052 	_networking = true;
  1048 	_frame_counter = 0;
  1053 	_frame_counter = 0;
  1049 	_frame_counter_server = 0;
  1054 	_frame_counter_server = 0;
  1330 
  1335 
  1331 		// We first increase the _frame_counter
  1336 		// We first increase the _frame_counter
  1332 		_frame_counter++;
  1337 		_frame_counter++;
  1333 		// Update max-frame-counter
  1338 		// Update max-frame-counter
  1334 		if (_frame_counter > _frame_counter_max) {
  1339 		if (_frame_counter > _frame_counter_max) {
  1335 			_frame_counter_max = _frame_counter + _network_frame_freq;
  1340 			_frame_counter_max = _frame_counter + _settings_client.network.frame_freq;
  1336 			send_frame = true;
  1341 			send_frame = true;
  1337 		}
  1342 		}
  1338 
  1343 
  1339 		NetworkHandleLocalQueue();
  1344 		NetworkHandleLocalQueue();
  1340 
  1345 
  1380 
  1385 
  1381 	for (di = 0; di < 16; ++di)
  1386 	for (di = 0; di < 16; ++di)
  1382 		sprintf(hex_output + di * 2, "%02x", digest[di]);
  1387 		sprintf(hex_output + di * 2, "%02x", digest[di]);
  1383 
  1388 
  1384 	/* _network_unique_id is our id */
  1389 	/* _network_unique_id is our id */
  1385 	snprintf(_network_unique_id, sizeof(_network_unique_id), "%s", hex_output);
  1390 	snprintf(_settings_client.network.network_id, sizeof(_settings_client.network.network_id), "%s", hex_output);
  1386 }
  1391 }
  1387 
  1392 
  1388 void NetworkStartDebugLog(const char *hostname, uint16 port)
  1393 void NetworkStartDebugLog(const char *hostname, uint16 port)
  1389 {
  1394 {
  1390 	extern SOCKET _debug_socket;  // Comes from debug.c
  1395 	extern SOCKET _debug_socket;  // Comes from debug.c
  1427 	_network_last_advertise_frame = 0;
  1432 	_network_last_advertise_frame = 0;
  1428 	_network_need_advertise = true;
  1433 	_network_need_advertise = true;
  1429 	_network_advertise_retries = 0;
  1434 	_network_advertise_retries = 0;
  1430 
  1435 
  1431 	/* Load the ip from the openttd.cfg */
  1436 	/* Load the ip from the openttd.cfg */
  1432 	_network_server_bind_ip = inet_addr(_network_server_bind_ip_host);
  1437 	_network_server_bind_ip = inet_addr(_settings_client.network.server_bind_ip);
  1433 	/* And put the data back in it in case it was an invalid ip */
  1438 	/* And put the data back in it in case it was an invalid ip */
  1434 	snprintf(_network_server_bind_ip_host, sizeof(_network_server_bind_ip_host), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
  1439 	snprintf(_settings_client.network.server_bind_ip, sizeof(_settings_client.network.server_bind_ip), "%s", inet_ntoa(*(struct in_addr *)&_network_server_bind_ip));
  1435 
  1440 
  1436 	/* Generate an unique id when there is none yet */
  1441 	/* Generate an unique id when there is none yet */
  1437 	if (_network_unique_id[0] == '\0') NetworkGenerateUniqueId();
  1442 	if (StrEmpty(_settings_client.network.network_id)) NetworkGenerateUniqueId();
  1438 
  1443 
  1439 	{
  1444 	{
  1440 		byte cl_max = _network_game_info.clients_max;
  1445 		byte cl_max = _network_game_info.clients_max;
  1441 		byte cp_max = _network_game_info.companies_max;
  1446 		byte cp_max = _network_game_info.companies_max;
  1442 		byte sp_max = _network_game_info.spectators_max;
  1447 		byte sp_max = _network_game_info.spectators_max;