mirror of https://github.com/OpenTTD/OpenTTD.git
(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.
This commit is contained in:
parent
9d07426a29
commit
f2448ebfd4
|
@ -545,8 +545,8 @@ DEF_CONSOLE_CMD(ConServerInfo)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
18
network.c
18
network.c
|
@ -103,6 +103,18 @@ void NetworkGetClientName(char *client_name, size_t size, const NetworkClientSta
|
|||
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 @@ void NetworkCloseClient(NetworkClientState *cs)
|
|||
|
||||
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) {
|
||||
|
|
|
@ -73,9 +73,9 @@ typedef struct NetworkGameInfo {
|
|||
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 @@ VARDEF uint16 _network_restart_game_date; // If this year is reached, the ser
|
|||
|
||||
NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info);
|
||||
|
||||
byte NetworkSpectatorCount(void);
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
// Those variables must always be registered!
|
||||
|
|
|
@ -74,12 +74,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)
|
|||
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 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME)
|
|||
|
||||
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 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN)
|
|||
// 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;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
|
|||
|
||||
/* 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 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
|
|||
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 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO)
|
|||
NetworkClientInfo *ci;
|
||||
Packet *packet;
|
||||
Player *player;
|
||||
byte active = 0;
|
||||
byte current = 0;
|
||||
int i;
|
||||
|
||||
|
@ -172,14 +171,9 @@ DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO)
|
|||
|
||||
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();
|
||||
|
|
|
@ -762,13 +762,8 @@ void SwitchMode(int new_mode)
|
|||
_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;
|
||||
|
|
2
player.h
2
player.h
|
@ -211,6 +211,8 @@ VARDEF Player _players[MAX_PLAYERS];
|
|||
// 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));
|
||||
|
|
17
players.c
17
players.c
|
@ -180,6 +180,18 @@ void DrawPlayerFace(uint32 face, int color, int x, int y)
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ int32 CmdPlayerCtrl(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
_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 @@ int32 CmdPlayerCtrl(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
* 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 @@ int32 CmdPlayerCtrl(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
p->is_active = false;
|
||||
}
|
||||
RemoveAllEngineReplacementForPlayer(p);
|
||||
#ifdef ENABLE_NETWORK
|
||||
_network_game_info.companies_on--;
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
} break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue