src/network/network.cpp
branchgamebalance
changeset 9895 7bd07f43b0e3
parent 6545 8fbeb8254bf3
child 6673 c3f85858d5e5
equal deleted inserted replaced
9894:70d78ac95d6c 9895:7bd07f43b0e3
    61 static byte _network_clients_connected = 0;
    61 static byte _network_clients_connected = 0;
    62 // The index counter for new clients (is never decreased)
    62 // The index counter for new clients (is never decreased)
    63 static uint16 _network_client_index = NETWORK_SERVER_INDEX + 1;
    63 static uint16 _network_client_index = NETWORK_SERVER_INDEX + 1;
    64 
    64 
    65 /* Some externs / forwards */
    65 /* Some externs / forwards */
    66 extern void StateGameLoop(void);
    66 extern void StateGameLoop();
    67 
    67 
    68 // Function that looks up the CI for a given client-index
    68 // Function that looks up the CI for a given client-index
    69 NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index)
    69 NetworkClientInfo *NetworkFindClientInfoFromIndex(uint16 client_index)
    70 {
    70 {
    71 	NetworkClientInfo *ci;
    71 	NetworkClientInfo *ci;
   115 	} else {
   115 	} else {
   116 		ttd_strlcpy(client_name, ci->client_name, size);
   116 		ttd_strlcpy(client_name, ci->client_name, size);
   117 	}
   117 	}
   118 }
   118 }
   119 
   119 
   120 byte NetworkSpectatorCount(void)
   120 byte NetworkSpectatorCount()
   121 {
   121 {
   122 	NetworkTCPSocketHandler *cs;
   122 	NetworkTCPSocketHandler *cs;
   123 	byte count = 0;
   123 	byte count = 0;
   124 
   124 
   125 	FOR_ALL_CLIENTS(cs) {
   125 	FOR_ALL_CLIENTS(cs) {
   299 
   299 
   300 	return GetString(buf, network_error_strings[err], last);
   300 	return GetString(buf, network_error_strings[err], last);
   301 }
   301 }
   302 
   302 
   303 /* Count the number of active clients connected */
   303 /* Count the number of active clients connected */
   304 static uint NetworkCountPlayers(void)
   304 static uint NetworkCountPlayers()
   305 {
   305 {
   306 	NetworkTCPSocketHandler *cs;
   306 	NetworkTCPSocketHandler *cs;
   307 	uint count = 0;
   307 	uint count = 0;
   308 
   308 
   309 	FOR_ALL_CLIENTS(cs) {
   309 	FOR_ALL_CLIENTS(cs) {
   315 }
   315 }
   316 
   316 
   317 static bool _min_players_paused = false;
   317 static bool _min_players_paused = false;
   318 
   318 
   319 /* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */
   319 /* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */
   320 void CheckMinPlayers(void)
   320 void CheckMinPlayers()
   321 {
   321 {
   322 	if (!_network_dedicated) return;
   322 	if (!_network_dedicated) return;
   323 
   323 
   324 	if (NetworkCountPlayers() < _network_min_players) {
   324 	if (NetworkCountPlayers() < _network_min_players) {
   325 		if (_min_players_paused) return;
   325 		if (_min_players_paused) return;
   335 		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX);
   335 		NetworkServer_HandleChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX);
   336 	}
   336 	}
   337 }
   337 }
   338 
   338 
   339 // Find all IP-aliases for this host
   339 // Find all IP-aliases for this host
   340 static void NetworkFindIPs(void)
   340 static void NetworkFindIPs()
   341 {
   341 {
   342 #if !defined(PSP)
   342 #if !defined(PSP)
   343 	int i;
   343 	int i;
   344 
   344 
   345 #if defined(BEOS_NET_SERVER) /* doesn't have neither getifaddrs or net/if.h */
   345 #if defined(BEOS_NET_SERVER) /* doesn't have neither getifaddrs or net/if.h */
   715 
   715 
   716 	return true;
   716 	return true;
   717 }
   717 }
   718 
   718 
   719 // For the server, to accept new clients
   719 // For the server, to accept new clients
   720 static void NetworkAcceptClients(void)
   720 static void NetworkAcceptClients()
   721 {
   721 {
   722 	struct sockaddr_in sin;
   722 	struct sockaddr_in sin;
   723 	NetworkTCPSocketHandler *cs;
   723 	NetworkTCPSocketHandler *cs;
   724 	uint i;
   724 	uint i;
   725 	bool banned;
   725 	bool banned;
   780 		DEREF_CLIENT_INFO(cs)->client_ip = sin.sin_addr.s_addr; // Save the IP of the client
   780 		DEREF_CLIENT_INFO(cs)->client_ip = sin.sin_addr.s_addr; // Save the IP of the client
   781 	}
   781 	}
   782 }
   782 }
   783 
   783 
   784 // Set up the listen socket for the server
   784 // Set up the listen socket for the server
   785 static bool NetworkListen(void)
   785 static bool NetworkListen()
   786 {
   786 {
   787 	SOCKET ls;
   787 	SOCKET ls;
   788 	struct sockaddr_in sin;
   788 	struct sockaddr_in sin;
   789 
   789 
   790 	DEBUG(net, 1, "Listening on %s:%d", _network_server_bind_ip_host, _network_server_port);
   790 	DEBUG(net, 1, "Listening on %s:%d", _network_server_bind_ip_host, _network_server_port);
   824 
   824 
   825 	return true;
   825 	return true;
   826 }
   826 }
   827 
   827 
   828 // Close all current connections
   828 // Close all current connections
   829 static void NetworkClose(void)
   829 static void NetworkClose()
   830 {
   830 {
   831 	NetworkTCPSocketHandler *cs;
   831 	NetworkTCPSocketHandler *cs;
   832 
   832 
   833 	FOR_ALL_CLIENTS(cs) {
   833 	FOR_ALL_CLIENTS(cs) {
   834 		if (!_network_server) {
   834 		if (!_network_server) {
   846 		NetworkUDPCloseAll();
   846 		NetworkUDPCloseAll();
   847 	}
   847 	}
   848 }
   848 }
   849 
   849 
   850 // Inits the network (cleans sockets and stuff)
   850 // Inits the network (cleans sockets and stuff)
   851 static void NetworkInitialize(void)
   851 static void NetworkInitialize()
   852 {
   852 {
   853 	NetworkTCPSocketHandler *cs;
   853 	NetworkTCPSocketHandler *cs;
   854 
   854 
   855 	_local_command_queue = NULL;
   855 	_local_command_queue = NULL;
   856 
   856 
   919 }
   919 }
   920 
   920 
   921 /* Generates the list of manually added hosts from NetworkGameList and
   921 /* Generates the list of manually added hosts from NetworkGameList and
   922  * dumps them into the array _network_host_list. This array is needed
   922  * dumps them into the array _network_host_list. This array is needed
   923  * by the function that generates the config file. */
   923  * by the function that generates the config file. */
   924 void NetworkRebuildHostList(void)
   924 void NetworkRebuildHostList()
   925 {
   925 {
   926 	uint i = 0;
   926 	uint i = 0;
   927 	const NetworkGameList *item = _network_game_list;
   927 	const NetworkGameList *item = _network_game_list;
   928 	while (item != NULL && i != lengthof(_network_host_list)) {
   928 	while (item != NULL && i != lengthof(_network_host_list)) {
   929 		if (item->manually) {
   929 		if (item->manually) {
   966 	}
   966 	}
   967 
   967 
   968 	return _networking;
   968 	return _networking;
   969 }
   969 }
   970 
   970 
   971 static void NetworkInitGameInfo(void)
   971 static void NetworkInitGameInfo()
   972 {
   972 {
   973 	NetworkClientInfo *ci;
   973 	NetworkClientInfo *ci;
   974 
   974 
   975 	ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
   975 	ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
   976 	ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
   976 	ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
  1011 
  1011 
  1012 	ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
  1012 	ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
  1013 	ttd_strlcpy(ci->unique_id, _network_unique_id, sizeof(ci->unique_id));
  1013 	ttd_strlcpy(ci->unique_id, _network_unique_id, sizeof(ci->unique_id));
  1014 }
  1014 }
  1015 
  1015 
  1016 bool NetworkServerStart(void)
  1016 bool NetworkServerStart()
  1017 {
  1017 {
  1018 	if (!_network_available) return false;
  1018 	if (!_network_available) return false;
  1019 
  1019 
  1020 	/* Call the pre-scripts */
  1020 	/* Call the pre-scripts */
  1021 	IConsoleCmdExec("exec scripts/pre_server.scr 0");
  1021 	IConsoleCmdExec("exec scripts/pre_server.scr 0");
  1058 	return true;
  1058 	return true;
  1059 }
  1059 }
  1060 
  1060 
  1061 // The server is rebooting...
  1061 // The server is rebooting...
  1062 // The only difference with NetworkDisconnect, is the packets that is sent
  1062 // The only difference with NetworkDisconnect, is the packets that is sent
  1063 void NetworkReboot(void)
  1063 void NetworkReboot()
  1064 {
  1064 {
  1065 	if (_network_server) {
  1065 	if (_network_server) {
  1066 		NetworkTCPSocketHandler *cs;
  1066 		NetworkTCPSocketHandler *cs;
  1067 		FOR_ALL_CLIENTS(cs) {
  1067 		FOR_ALL_CLIENTS(cs) {
  1068 			SEND_COMMAND(PACKET_SERVER_NEWGAME)(cs);
  1068 			SEND_COMMAND(PACKET_SERVER_NEWGAME)(cs);
  1082 	_networking = false;
  1082 	_networking = false;
  1083 	_network_server = false;
  1083 	_network_server = false;
  1084 }
  1084 }
  1085 
  1085 
  1086 // We want to disconnect from the host/clients
  1086 // We want to disconnect from the host/clients
  1087 void NetworkDisconnect(void)
  1087 void NetworkDisconnect()
  1088 {
  1088 {
  1089 	if (_network_server) {
  1089 	if (_network_server) {
  1090 		NetworkTCPSocketHandler *cs;
  1090 		NetworkTCPSocketHandler *cs;
  1091 		FOR_ALL_CLIENTS(cs) {
  1091 		FOR_ALL_CLIENTS(cs) {
  1092 			SEND_COMMAND(PACKET_SERVER_SHUTDOWN)(cs);
  1092 			SEND_COMMAND(PACKET_SERVER_SHUTDOWN)(cs);
  1110 	_networking = false;
  1110 	_networking = false;
  1111 	_network_server = false;
  1111 	_network_server = false;
  1112 }
  1112 }
  1113 
  1113 
  1114 // Receives something from the network
  1114 // Receives something from the network
  1115 static bool NetworkReceive(void)
  1115 static bool NetworkReceive()
  1116 {
  1116 {
  1117 	NetworkTCPSocketHandler *cs;
  1117 	NetworkTCPSocketHandler *cs;
  1118 	int n;
  1118 	int n;
  1119 	fd_set read_fd, write_fd;
  1119 	fd_set read_fd, write_fd;
  1120 	struct timeval tv;
  1120 	struct timeval tv;
  1165 	}
  1165 	}
  1166 	return true;
  1166 	return true;
  1167 }
  1167 }
  1168 
  1168 
  1169 // This sends all buffered commands (if possible)
  1169 // This sends all buffered commands (if possible)
  1170 static void NetworkSend(void)
  1170 static void NetworkSend()
  1171 {
  1171 {
  1172 	NetworkTCPSocketHandler *cs;
  1172 	NetworkTCPSocketHandler *cs;
  1173 	FOR_ALL_CLIENTS(cs) {
  1173 	FOR_ALL_CLIENTS(cs) {
  1174 		if (cs->writable) {
  1174 		if (cs->writable) {
  1175 			cs->Send_Packets();
  1175 			cs->Send_Packets();
  1181 		}
  1181 		}
  1182 	}
  1182 	}
  1183 }
  1183 }
  1184 
  1184 
  1185 // Handle the local-command-queue
  1185 // Handle the local-command-queue
  1186 static void NetworkHandleLocalQueue(void)
  1186 static void NetworkHandleLocalQueue()
  1187 {
  1187 {
  1188 	CommandPacket *cp, **cp_prev;
  1188 	CommandPacket *cp, **cp_prev;
  1189 
  1189 
  1190 	cp_prev = &_local_command_queue;
  1190 	cp_prev = &_local_command_queue;
  1191 
  1191 
  1216 		assert(_frame_counter < cp->frame);
  1216 		assert(_frame_counter < cp->frame);
  1217 	}
  1217 	}
  1218 
  1218 
  1219 }
  1219 }
  1220 
  1220 
  1221 static bool NetworkDoClientLoop(void)
  1221 static bool NetworkDoClientLoop()
  1222 {
  1222 {
  1223 	_frame_counter++;
  1223 	_frame_counter++;
  1224 
  1224 
  1225 	NetworkHandleLocalQueue();
  1225 	NetworkHandleLocalQueue();
  1226 
  1226 
  1257 
  1257 
  1258 	return true;
  1258 	return true;
  1259 }
  1259 }
  1260 
  1260 
  1261 // We have to do some UDP checking
  1261 // We have to do some UDP checking
  1262 void NetworkUDPGameLoop(void)
  1262 void NetworkUDPGameLoop()
  1263 {
  1263 {
  1264 	if (_network_udp_server) {
  1264 	if (_network_udp_server) {
  1265 		_udp_server_socket->ReceivePackets();
  1265 		_udp_server_socket->ReceivePackets();
  1266 		_udp_master_socket->ReceivePackets();
  1266 		_udp_master_socket->ReceivePackets();
  1267 	} else {
  1267 	} else {
  1271 	}
  1271 	}
  1272 }
  1272 }
  1273 
  1273 
  1274 // The main loop called from ttd.c
  1274 // The main loop called from ttd.c
  1275 //  Here we also have to do StateGameLoop if needed!
  1275 //  Here we also have to do StateGameLoop if needed!
  1276 void NetworkGameLoop(void)
  1276 void NetworkGameLoop()
  1277 {
  1277 {
  1278 	if (!_networking) return;
  1278 	if (!_networking) return;
  1279 
  1279 
  1280 	if (!NetworkReceive()) return;
  1280 	if (!NetworkReceive()) return;
  1281 
  1281 
  1316 	}
  1316 	}
  1317 
  1317 
  1318 	NetworkSend();
  1318 	NetworkSend();
  1319 }
  1319 }
  1320 
  1320 
  1321 static void NetworkGenerateUniqueId(void)
  1321 static void NetworkGenerateUniqueId()
  1322 {
  1322 {
  1323 	md5_state_t state;
  1323 	md5_state_t state;
  1324 	md5_byte_t digest[16];
  1324 	md5_byte_t digest[16];
  1325 	char hex_output[16*2 + 1];
  1325 	char hex_output[16*2 + 1];
  1326 	char coding_string[NETWORK_NAME_LENGTH];
  1326 	char coding_string[NETWORK_NAME_LENGTH];
  1370 
  1370 
  1371 	DEBUG(net, 0, "DEBUG() is now redirected");
  1371 	DEBUG(net, 0, "DEBUG() is now redirected");
  1372 }
  1372 }
  1373 
  1373 
  1374 /** This tries to launch the network for a given OS */
  1374 /** This tries to launch the network for a given OS */
  1375 void NetworkStartUp(void)
  1375 void NetworkStartUp()
  1376 {
  1376 {
  1377 	DEBUG(net, 3, "[core] starting network...");
  1377 	DEBUG(net, 3, "[core] starting network...");
  1378 
  1378 
  1379 	/* Network is available */
  1379 	/* Network is available */
  1380 	_network_available = NetworkCoreInitialize();;
  1380 	_network_available = NetworkCoreInitialize();;
  1407 	DEBUG(net, 3, "[core] network online, multiplayer available");
  1407 	DEBUG(net, 3, "[core] network online, multiplayer available");
  1408 	NetworkFindIPs();
  1408 	NetworkFindIPs();
  1409 }
  1409 }
  1410 
  1410 
  1411 /** This shuts the network down */
  1411 /** This shuts the network down */
  1412 void NetworkShutDown(void)
  1412 void NetworkShutDown()
  1413 {
  1413 {
  1414 	NetworkDisconnect();
  1414 	NetworkDisconnect();
  1415 	NetworkUDPShutdown();
  1415 	NetworkUDPShutdown();
  1416 
  1416 
  1417 	DEBUG(net, 3, "[core] shutting down network");
  1417 	DEBUG(net, 3, "[core] shutting down network");