(svn r3500) - Workaround the inaccurate count of spectators/companies that can happen in certain border-cases. For now just dynamically get this value when requested so it is always right. To do properly all player/client creation/destruction needs a hook for networking.
authorDarkvater
Tue, 31 Jan 2006 22:16:15 +0000
changeset 2944 7c392e7b51c6
parent 2943 384c32d588e3
child 2945 5efe2ddcc9bd
(svn r3500) - Workaround the inaccurate count of spectators/companies that can happen in certain border-cases. For now just dynamically get this value when requested so it is always right. To do properly all player/client creation/destruction needs a hook for networking.
console_cmds.c
network.c
network.h
network_server.c
network_udp.c
openttd.c
player.h
players.c
--- a/console_cmds.c	Tue Jan 31 20:05:44 2006 +0000
+++ b/console_cmds.c	Tue Jan 31 22:16:15 2006 +0000
@@ -545,8 +545,8 @@
 
 	gi = &_network_game_info;
 	IConsolePrintF(_icolour_def, "Current/maximum clients:    %2d/%2d", gi->clients_on, gi->clients_max);
-	IConsolePrintF(_icolour_def, "Current/maximum companies:  %2d/%2d", gi->companies_on, gi->companies_max);
-	IConsolePrintF(_icolour_def, "Current/maximum spectators: %2d/%2d", gi->spectators_on, gi->spectators_max);
+	IConsolePrintF(_icolour_def, "Current/maximum companies:  %2d/%2d", ActivePlayerCount(), gi->companies_max);
+	IConsolePrintF(_icolour_def, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), gi->spectators_max);
 
 	return true;
 }
--- a/network.c	Tue Jan 31 20:05:44 2006 +0000
+++ b/network.c	Tue Jan 31 22:16:15 2006 +0000
@@ -103,6 +103,18 @@
 		snprintf(client_name, size, "%s", ci->client_name);
 }
 
+byte NetworkSpectatorCount(void)
+{
+	const NetworkClientState *cs;
+	byte count = 0;
+
+	FOR_ALL_CLIENTS(cs) {
+		if (DEREF_CLIENT_INFO(cs)->client_playas == OWNER_SPECTATOR) count++;
+	}
+
+	return count;
+}
+
 // This puts a text-message to the console, or in the future, the chat-box,
 //  (to keep it all a bit more general)
 // If 'self_send' is true, this is the client who is sending the message
@@ -554,11 +566,7 @@
 
 	if (_network_server) {
 		// We just lost one client :(
-		if (cs->status > STATUS_INACTIVE) {
-			_network_game_info.clients_on--;
-			if (DEREF_CLIENT_INFO(cs)->client_playas == OWNER_SPECTATOR)
-				_network_game_info.spectators_on--;
-		}
+		if (cs->status > STATUS_INACTIVE) _network_game_info.clients_on--;
 		_network_clients_connected--;
 
 		while ((cs + 1) != DEREF_CLIENT(MAX_CLIENTS) && (cs + 1)->socket != INVALID_SOCKET) {
--- a/network.h	Tue Jan 31 20:05:44 2006 +0000
+++ b/network.h	Tue Jan 31 22:16:15 2006 +0000
@@ -73,9 +73,9 @@
 	byte clients_max;                               // Max clients allowed on server
 	byte clients_on;                                // Current count of clients on server
 	byte companies_max;                             // Max companies allowed on server
-	byte companies_on;                              // How many started companies do we have
+	byte companies_on;                              // How many started companies do we have (XXX - disabled for server atm, use ActivePlayerCount())
 	byte spectators_max;                            // Max spectators allowed on server
-	byte spectators_on;                             // How many spectators do we have?
+	byte spectators_on;                             // How many spectators do we have? (XXX - disabled for server atm, use NetworkSpectatorCount())
 	uint16 game_date;                               // Current date
 	uint16 start_date;                              // When the game started
 	char map_name[NETWORK_NAME_LENGTH];             // Map which is played ["random" for a randomized map]
@@ -210,6 +210,8 @@
 
 NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info);
 
+byte NetworkSpectatorCount(void);
+
 #endif /* ENABLE_NETWORK */
 
 // Those variables must always be registered!
--- a/network_server.c	Tue Jan 31 20:05:44 2006 +0000
+++ b/network_server.c	Tue Jan 31 22:16:15 2006 +0000
@@ -74,12 +74,7 @@
 	Player *player;
 	Packet *p;
 
-	byte active = 0;
-
-	FOR_ALL_PLAYERS(player) {
-		if (player->is_active)
-			active++;
-	}
+	byte active = ActivePlayerCount();
 
 	if (active == 0) {
 		Packet *p = NetworkSend_Init(PACKET_SERVER_COMPANY_INFO);
@@ -214,15 +209,12 @@
 
 	Packet *p;
 	const NetworkClientState *new_cs;
-	const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
 
 	// Invalid packet when status is AUTH or higher
 	if (cs->status >= STATUS_AUTH) return;
 
 	cs->status = STATUS_AUTH;
 	_network_game_info.clients_on++;
-	/* increment spectator; defer company addition for when player is actually created */
-	if (ci->client_playas == OWNER_SPECTATOR) _network_game_info.spectators_on++;
 
 	p = NetworkSend_Init(PACKET_SERVER_WELCOME);
 	NetworkSend_uint16(p, cs->index);
@@ -615,13 +607,13 @@
 	// join another company does not affect these values
 	switch (playas) {
 		case 0: /* New company */
-			if (_network_game_info.companies_on >= _network_game_info.companies_max) {
+			if (ActivePlayerCount() >= _network_game_info.companies_max) {
 				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
 				return;
 			}
 			break;
 		case OWNER_SPECTATOR: /* Spectator */
-			if (_network_game_info.spectators_on >= _network_game_info.spectators_max) {
+			if (NetworkSpectatorCount() >= _network_game_info.spectators_max) {
 				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL);
 				return;
 			}
--- a/network_udp.c	Tue Jan 31 20:05:44 2006 +0000
+++ b/network_udp.c	Tue Jan 31 22:16:15 2006 +0000
@@ -64,7 +64,7 @@
 
 	/* NETWORK_GAME_INFO_VERSION = 2 */
 	NetworkSend_uint8 (packet, _network_game_info.companies_max);
-	NetworkSend_uint8 (packet, _network_game_info.companies_on);
+	NetworkSend_uint8 (packet, ActivePlayerCount());
 	NetworkSend_uint8 (packet, _network_game_info.spectators_max);
 
 	/* NETWORK_GAME_INFO_VERSION = 1 */
@@ -74,7 +74,7 @@
 	NetworkSend_uint8 (packet, _network_game_info.use_password);
 	NetworkSend_uint8 (packet, _network_game_info.clients_max);
 	NetworkSend_uint8 (packet, _network_game_info.clients_on);
-	NetworkSend_uint8 (packet, _network_game_info.spectators_on);
+	NetworkSend_uint8 (packet, NetworkSpectatorCount());
 	NetworkSend_uint16(packet, _network_game_info.game_date);
 	NetworkSend_uint16(packet, _network_game_info.start_date);
 	NetworkSend_string(packet, _network_game_info.map_name);
@@ -162,7 +162,6 @@
 	NetworkClientInfo *ci;
 	Packet *packet;
 	Player *player;
-	byte active = 0;
 	byte current = 0;
 	int i;
 
@@ -172,14 +171,9 @@
 
 	packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
 
-	FOR_ALL_PLAYERS(player) {
-		if (player->is_active)
-			active++;
-	}
-
 	/* Send the amount of active companies */
 	NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
-	NetworkSend_uint8 (packet, active);
+	NetworkSend_uint8 (packet, ActivePlayerCount());
 
 	/* Fetch the latest version of everything */
 	NetworkPopulateCompanyInfo();
--- a/openttd.c	Tue Jan 31 20:05:44 2006 +0000
+++ b/openttd.c	Tue Jan 31 22:16:15 2006 +0000
@@ -762,13 +762,8 @@
 			_local_player = 0;
 			DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // decrease pause counter (was increased from opening load dialog)
 #ifdef ENABLE_NETWORK
-			if (_network_server) {
-				/* If we have loaded a game we need to correctly update the company-count */
-				const Player *p;
-				_network_game_info.companies_on = 0;
-				FOR_ALL_PLAYERS(p) {if (p->is_active) _network_game_info.companies_on++;}
+			if (_network_server)
 				snprintf(_network_game_info.map_name, NETWORK_NAME_LENGTH, "%s (Loaded game)", _file_to_saveload.title);
-			}
 #endif /* ENABLE_NETWORK */
 		}
 		break;
--- a/player.h	Tue Jan 31 20:05:44 2006 +0000
+++ b/player.h	Tue Jan 31 22:16:15 2006 +0000
@@ -211,6 +211,8 @@
 // NOSAVE: can be determined from player structs
 VARDEF byte _player_colors[MAX_PLAYERS];
 
+byte ActivePlayerCount(void);
+
 static inline Player* GetPlayer(PlayerID i)
 {
 	assert(i < lengthof(_players));
--- a/players.c	Tue Jan 31 20:05:44 2006 +0000
+++ b/players.c	Tue Jan 31 22:16:15 2006 +0000
@@ -180,6 +180,18 @@
 	}
 }
 
+byte ActivePlayerCount(void)
+{
+	const Player *p;
+	byte count = 0;
+
+	FOR_ALL_PLAYERS(p) {
+		if (p->is_active) count++;
+	}
+
+	return count;
+}
+
 void InvalidatePlayerWindows(const Player *p)
 {
 	PlayerID pid = p->index;
@@ -857,7 +869,6 @@
 					_local_player = ci->client_playas - 1;
 					NetworkSend_Command(0, 0, 0, CMD_CHANGE_PRESIDENT_NAME, NULL);
 					_local_player = player_backup;
-					_network_game_info.companies_on++;
 				}
 			}
 		} else if (_network_server) { // Creating player failed, defer client to spectator
@@ -865,7 +876,6 @@
 				* in network_server.c:838, function DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
 			NetworkClientInfo *ci = &_network_client_info[pid];
 			ci->client_playas = OWNER_SPECTATOR;
-			_network_game_info.spectators_on++;
 			NetworkUpdateClientInfo(ci->client_index);
 		}
 #else
@@ -904,9 +914,6 @@
 			p->is_active = false;
 		}
 		RemoveAllEngineReplacementForPlayer(p);
-#ifdef ENABLE_NETWORK
-		_network_game_info.companies_on--;
-#endif /* ENABLE_NETWORK */
 
 	} break;