From 53744881a409f3d1624d0e60e3823370a3900cbe Mon Sep 17 00:00:00 2001 From: peter1138 Date: Tue, 3 Oct 2006 16:15:34 +0000 Subject: (svn r6628) - Feature: Add the ability to pause a server if not enough players are connected. The setting for this is 'min_players' and can be set in the config and via the console. If the number of players drops below this number, the server will pause the game. --- console_cmds.c | 10 ++++++++++ network.c | 41 +++++++++++++++++++++++++++++++++++++++++ network.h | 2 ++ network_server.c | 2 ++ settings.c | 1 + 5 files changed, 56 insertions(+) diff --git a/console_cmds.c b/console_cmds.c index 37b7d92a6..39f34cfb2 100644 --- a/console_cmds.c +++ b/console_cmds.c @@ -612,6 +612,12 @@ DEF_CONSOLE_HOOK(ConHookValidateMaxSpectatorsCount) return true; } +DEF_CONSOLE_HOOK(ConHookCheckMinPlayers) +{ + CheckMinPlayers(); + return true; +} + DEF_CONSOLE_CMD(ConKick) { NetworkClientInfo *ci; @@ -1580,6 +1586,10 @@ void IConsoleStdLibRegister(void) IConsoleVarRegister("restart_game_year", &_network_restart_game_year, ICONSOLE_VAR_UINT16, "Auto-restart the server when Jan 1st of the set year is reached. Use '0' to disable this"); IConsoleVarHookAdd("restart_game_year", ICONSOLE_HOOK_ACCESS, ConHookServerOnly); + IConsoleVarRegister("min_players", &_network_min_players, ICONSOLE_VAR_BYTE, "Automatically pause the game when the number of active players passes below the given amount"); + IConsoleVarHookAdd("min_players", ICONSOLE_HOOK_ACCESS, ConHookServerOnly); + IConsoleVarHookAdd("min_players", ICONSOLE_HOOK_POST_ACTION, ConHookCheckMinPlayers); + #endif /* ENABLE_NETWORK */ // debugging stuff diff --git a/network.c b/network.c index 85d838ea2..7034e65c7 100644 --- a/network.c +++ b/network.c @@ -286,6 +286,42 @@ char *GetNetworkErrorMsg(char *buf, NetworkErrorCode err) return GetString(buf, network_error_strings[err]); } +/* Count the number of active clients connected */ +static uint NetworkCountPlayers(void) +{ + NetworkClientState *cs; + uint count = 0; + + FOR_ALL_CLIENTS(cs) { + NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs); + if (ci->client_playas > 0 && ci->client_playas <= MAX_PLAYERS) count++; + } + + return count; +} + +static bool _min_players_paused = false; + +/* Check if the minimum number of players has been reached and pause or unpause the game as appropriate */ +void CheckMinPlayers(void) +{ + if (!_network_dedicated) return; + + if (NetworkCountPlayers() < _network_min_players) { + if (_min_players_paused) return; + + _min_players_paused = true; + DoCommandP(0, 1, 0, NULL, CMD_PAUSE); + NetworkServer_HandleChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, "Game paused (not enough players)", NETWORK_SERVER_INDEX); + } else { + if (!_min_players_paused) return; + + _min_players_paused = false; + DoCommandP(0, 0, 0, NULL, CMD_PAUSE); + NetworkServer_HandleChat(NETWORK_ACTION_CHAT, DESTTYPE_BROADCAST, 0, "Game unpaused (enough players)", NETWORK_SERVER_INDEX); + } +} + // Find all IP-aliases for this host static void NetworkFindIPs(void) { @@ -626,6 +662,8 @@ void NetworkCloseClient(NetworkClientState *cs) cs->status = STATUS_INACTIVE; cs->index = NETWORK_EMPTY_INDEX; ci->client_index = NETWORK_EMPTY_INDEX; + + CheckMinPlayers(); } // A client wants to connect to a server @@ -1041,6 +1079,9 @@ bool NetworkServerStart(void) // if the server is dedicated ... add some other script if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0"); + _min_players_paused = false; + CheckMinPlayers(); + /* Try to register us to the master server */ _network_last_advertise_frame = 0; _network_need_advertise = true; diff --git a/network.h b/network.h index c4d8c3fe4..5e0d0ac11 100644 --- a/network.h +++ b/network.h @@ -207,6 +207,7 @@ VARDEF uint8 _network_autoclean_unprotected; // Remove a company after X months VARDEF uint8 _network_autoclean_protected; // Unprotect a company after X months VARDEF Year _network_restart_game_year; // If this year is reached, the server automaticly restarts +VARDEF uint8 _network_min_players; // Minimum number of players for game to unpause NetworkGameList *NetworkQueryServer(const char* host, unsigned short port, bool game_info); @@ -221,6 +222,7 @@ void NetworkAddServer(const char *b); void NetworkRebuildHostList(void); bool NetworkChangeCompanyPassword(byte argc, char *argv[]); void NetworkPopulateCompanyInfo(void); +void CheckMinPlayers(void); #endif /* ENABLE_NETWORK */ diff --git a/network_server.c b/network_server.c index 2c646b162..d70583ab5 100644 --- a/network_server.c +++ b/network_server.c @@ -932,6 +932,8 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT) if (new_cs->status > STATUS_AUTH) { SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->index, str); } + + CheckMinPlayers(); } cs->quited = true; diff --git a/settings.c b/settings.c index 0b77381cb..b8b72dd54 100644 --- a/settings.c +++ b/settings.c @@ -1210,6 +1210,7 @@ static const SettingDescGlobVarList _network_settings[] = { SDTG_VAR("max_clients", SLE_UINT8, S, 0, _network_game_info.clients_max, 10, 0, 10, 0, STR_NULL, NULL), SDTG_VAR("max_spectators", SLE_UINT8, S, 0, _network_game_info.spectators_max, 10, 0, 10, 0, STR_NULL, NULL), SDTG_VAR("restart_game_year", SLE_INT32, S,D0, _network_restart_game_year, 0, MIN_YEAR, MAX_YEAR, 1, STR_NULL, NULL), + SDTG_VAR("min_players", SLE_UINT8, S, 0, _network_min_players, 0, 0, 10, 0, STR_NULL, NULL), SDTG_END() }; #endif /* ENABLE_NETWORK */ -- cgit v1.2.3-70-g09d2