diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -538,18 +538,15 @@ DEF_CONSOLE_CMD(ConStatus) DEF_CONSOLE_CMD(ConServerInfo) { - const NetworkGameInfo *gi; - if (argc == 0) { IConsoleHelp("List current and maximum client/player limits. Usage 'server_info'"); IConsoleHelp("You can change these values by setting the variables 'max_clients', 'max_companies' and 'max_spectators'"); return true; } - gi = &_network_game_info; - IConsolePrintF(CC_DEFAULT, "Current/maximum clients: %2d/%2d", gi->clients_on, gi->clients_max); - IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %2d/%2d", ActivePlayerCount(), gi->companies_max); - IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), gi->spectators_max); + IConsolePrintF(CC_DEFAULT, "Current/maximum clients: %2d/%2d", _network_game_info.clients_on, _settings_client.network.max_clients); + IConsolePrintF(CC_DEFAULT, "Current/maximum companies: %2d/%2d", ActivePlayerCount(), _settings_client.network.max_companies); + IConsolePrintF(CC_DEFAULT, "Current/maximum spectators: %2d/%2d", NetworkSpectatorCount(), _settings_client.network.max_spectators); return true; } diff --git a/src/network/core/game.h b/src/network/core/game.h --- a/src/network/core/game.h +++ b/src/network/core/game.h @@ -19,7 +19,13 @@ * some fields will be empty on the client (like game_password) by default * and only filled with data a player enters. */ -struct NetworkGameInfo { +struct NetworkServerGameInfo { + byte clients_on; ///< Current count of clients on server + Date start_date; ///< When the game started + char map_name[NETWORK_NAME_LENGTH]; ///< Map which is played ["random" for a randomized map] +}; + +struct NetworkGameInfo : NetworkServerGameInfo { byte game_info_version; ///< Version of the game info char server_name[NETWORK_NAME_LENGTH]; ///< Server name char hostname[NETWORK_HOSTNAME_LENGTH]; ///< Hostname of the server (if any) @@ -28,21 +34,16 @@ struct NetworkGameInfo { bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match byte server_lang; ///< Language of the server (we should make a nice table for this) bool use_password; ///< Is this server passworded? - char server_password[NETWORK_PASSWORD_LENGTH]; ///< On the server: the game password, on the client: != "" if server has password 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_max; ///< Max companies allowed on server + byte spectators_on; ///< How many spectators do we have? byte spectators_max; ///< Max spectators allowed on server - byte spectators_on; ///< How many spectators do we have? Date game_date; ///< Current date - Date start_date; ///< When the game started - char map_name[NETWORK_NAME_LENGTH]; ///< Map which is played ["random" for a randomized map] uint16 map_width; ///< Map width uint16 map_height; ///< Map height byte map_set; ///< Graphical set bool dedicated; ///< Is this a dedicated server? - char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< RCon password for the server. "" if rcon is disabled GRFConfig *grfconfig; ///< List of NewGRF files used }; diff --git a/src/network/network.cpp b/src/network/network.cpp --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -47,7 +47,7 @@ bool _network_available; ///< is networ bool _network_dedicated; ///< are we a dedicated server? bool _network_advertise; ///< is the server advertising to the master server? bool _is_network_server; ///< Does this client wants to be a network-server? -NetworkGameInfo _network_game_info; +NetworkServerGameInfo _network_game_info; NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; NetworkClientInfo _network_client_info[MAX_CLIENT_INFO]; uint16 _network_own_client_index; @@ -624,7 +624,7 @@ static NetworkTCPSocketHandler *NetworkA if (_network_server) { // Can we handle a new client? if (_network_clients_connected >= MAX_CLIENTS) return NULL; - if (_network_game_info.clients_on >= _network_game_info.clients_max) return NULL; + if (_network_game_info.clients_on >= _settings_client.network.max_clients) return NULL; // Register the login client_no = _network_clients_connected++; @@ -1019,39 +1019,13 @@ static void NetworkInitGameInfo() { NetworkClientInfo *ci; - _network_game_info.clients_max = _settings_client.network.max_clients; - _network_game_info.companies_max = _settings_client.network.max_companies; - _network_game_info.spectators_max = _settings_client.network.max_spectators; - _network_game_info.server_lang = _settings_client.network.server_lang; - ttd_strlcpy(_network_game_info.server_name, _settings_client.network.server_name, sizeof(_network_game_info.server_name)); - ttd_strlcpy(_network_game_info.server_password, _settings_client.network.server_password, sizeof(_network_game_info.server_password)); - ttd_strlcpy(_network_game_info.rcon_password, _settings_client.network.rcon_password, sizeof(_network_game_info.rcon_password)); - if (StrEmpty(_network_game_info.server_name)) { - snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server"); + if (StrEmpty(_settings_client.network.server_name)) { + snprintf(_settings_client.network.server_name, sizeof(_settings_client.network.server_name), "Unnamed Server"); } - ttd_strlcpy(_network_game_info.server_revision, _openttd_revision, sizeof(_network_game_info.server_revision)); - - // The server is a client too ;) - if (_network_dedicated) { - _network_game_info.clients_on = 0; - _network_game_info.companies_on = 0; - _network_game_info.dedicated = true; - } else { - _network_game_info.clients_on = 1; - _network_game_info.companies_on = 1; - _network_game_info.dedicated = false; - } - - _network_game_info.spectators_on = 0; - - _network_game_info.game_date = _date; + /* The server is a client too */ + _network_game_info.clients_on = _network_dedicated ? 0 : 1; _network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); - _network_game_info.map_width = MapSizeX(); - _network_game_info.map_height = MapSizeY(); - _network_game_info.map_set = _settings_game.game_creation.landscape; - - _network_game_info.use_password = !StrEmpty(_settings_client.network.server_password); // We use _network_client_info[MAX_CLIENT_INFO - 1] to store the server-data in it // The index is NETWORK_SERVER_INDEX ( = 1) @@ -1453,19 +1427,7 @@ void NetworkStartUp() /* Generate an unique id when there is none yet */ if (StrEmpty(_settings_client.network.network_id)) NetworkGenerateUniqueId(); - { - byte cl_max = _network_game_info.clients_max; - byte cp_max = _network_game_info.companies_max; - byte sp_max = _network_game_info.spectators_max; - byte s_lang = _network_game_info.server_lang; - - memset(&_network_game_info, 0, sizeof(_network_game_info)); - _network_game_info.clients_max = cl_max; - _network_game_info.companies_max = cp_max; - _network_game_info.spectators_max = sp_max; - _network_game_info.server_lang = s_lang; - } - + memset(&_network_game_info, 0, sizeof(_network_game_info)); NetworkInitialize(); DEBUG(net, 3, "[core] network online, multiplayer available"); diff --git a/src/network/network_func.h b/src/network/network_func.h --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -10,7 +10,7 @@ #include "network_type.h" #include "../console_type.h" -extern NetworkGameInfo _network_game_info; +extern NetworkServerGameInfo _network_game_info; extern NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; extern NetworkClientInfo _network_client_info[MAX_CLIENT_INFO]; diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -383,7 +383,7 @@ public: if (!sel->info.compatible) { DrawStringCentered(this->widget[NGWW_DETAILS].left + 115, y, sel->info.version_compatible ? STR_NETWORK_GRF_MISMATCH : STR_NETWORK_VERSION_MISMATCH, TC_FROMSTRING); // server mismatch } else if (sel->info.clients_on == sel->info.clients_max) { - /* Show: server full, when clients_on == clients_max */ + /* Show: server full, when clients_on == max_clients */ DrawStringCentered(this->widget[NGWW_DETAILS].left + 115, y, STR_NETWORK_SERVER_FULL, TC_FROMSTRING); // server full } else if (sel->info.use_password) { DrawStringCentered(this->widget[NGWW_DETAILS].left + 115, y, STR_NETWORK_PASSWORD, TC_FROMSTRING); // password warning @@ -676,7 +676,6 @@ struct NetworkStartServerWindow : public InitializeTextBuffer(&this->text, this->edit_str_buf, lengthof(this->edit_str_buf), 160); this->field = NSSW_GAMENAME; - _network_game_info.use_password = !StrEmpty(_settings_client.network.server_password); this->FindWindowPlacementAndResize(desc); } @@ -688,17 +687,17 @@ struct NetworkStartServerWindow : public /* draw basic widgets */ SetDParam(1, _connection_types_dropdown[_network_advertise]); - SetDParam(2, _network_game_info.clients_max); - SetDParam(3, _network_game_info.companies_max); - SetDParam(4, _network_game_info.spectators_max); - SetDParam(5, STR_NETWORK_LANG_ANY + _network_game_info.server_lang); + SetDParam(2, _settings_client.network.max_clients); + SetDParam(3, _settings_client.network.max_companies); + SetDParam(4, _settings_client.network.max_spectators); + SetDParam(5, STR_NETWORK_LANG_ANY + _settings_client.network.server_lang); this->DrawWidgets(); /* editbox to set game name */ this->DrawEditBox(NSSW_GAMENAME); /* if password is set, draw red '*' next to 'Set password' button */ - if (_network_game_info.use_password) DoDrawString("*", 408, 23, TC_RED); + if (!StrEmpty(_settings_client.network.server_password)) DoDrawString("*", 408, 23, TC_RED); /* draw list of maps */ GfxFillRect(11, 63, 258, 215, 0xD7); // black background of maps list @@ -762,13 +761,13 @@ struct NetworkStartServerWindow : public switch (widget) { default: NOT_REACHED(); case NSSW_CLIENTS_BTND: case NSSW_CLIENTS_BTNU: - _network_game_info.clients_max = Clamp(_network_game_info.clients_max + widget - NSSW_CLIENTS_TXT, 2, MAX_CLIENTS); + _settings_client.network.max_clients = Clamp(_settings_client.network.max_clients + widget - NSSW_CLIENTS_TXT, 2, MAX_CLIENTS); break; case NSSW_COMPANIES_BTND: case NSSW_COMPANIES_BTNU: - _network_game_info.companies_max = Clamp(_network_game_info.companies_max + widget - NSSW_COMPANIES_TXT, 1, MAX_PLAYERS); + _settings_client.network.max_companies = Clamp(_settings_client.network.max_companies + widget - NSSW_COMPANIES_TXT, 1, MAX_PLAYERS); break; case NSSW_SPECTATORS_BTND: case NSSW_SPECTATORS_BTNU: - _network_game_info.spectators_max = Clamp(_network_game_info.spectators_max + widget - NSSW_SPECTATORS_TXT, 0, MAX_CLIENTS); + _settings_client.network.max_spectators = Clamp(_settings_client.network.max_spectators + widget - NSSW_SPECTATORS_TXT, 0, MAX_CLIENTS); break; } } @@ -777,26 +776,26 @@ struct NetworkStartServerWindow : public case NSSW_CLIENTS_TXT: // Click on number of players this->widget_id = NSSW_CLIENTS_TXT; - SetDParam(0, _network_game_info.clients_max); + SetDParam(0, _settings_client.network.max_clients); ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_NETWORK_NUMBER_OF_CLIENTS, 3, 50, this, CS_NUMERAL); break; case NSSW_COMPANIES_TXT: // Click on number of companies this->widget_id = NSSW_COMPANIES_TXT; - SetDParam(0, _network_game_info.companies_max); + SetDParam(0, _settings_client.network.max_companies); ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_NETWORK_NUMBER_OF_COMPANIES, 3, 50, this, CS_NUMERAL); break; case NSSW_SPECTATORS_TXT: // Click on number of spectators this->widget_id = NSSW_SPECTATORS_TXT; - SetDParam(0, _network_game_info.spectators_max); + SetDParam(0, _settings_client.network.max_spectators); ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_NETWORK_NUMBER_OF_SPECTATORS, 3, 50, this, CS_NUMERAL); break; case NSSW_LANGUAGE_BTN: { // Language uint sel = 0; for (uint i = 0; i < lengthof(_language_dropdown) - 1; i++) { - if (_language_dropdown[i] == STR_NETWORK_LANG_ANY + _network_game_info.server_lang) { + if (_language_dropdown[i] == STR_NETWORK_LANG_ANY + _settings_client.network.server_lang) { sel = i; break; } @@ -840,7 +839,7 @@ struct NetworkStartServerWindow : public _network_advertise = (index != 0); break; case NSSW_LANGUAGE_BTN: - _network_game_info.server_lang = _language_dropdown[index] - STR_NETWORK_LANG_ANY; + _settings_client.network.server_lang = _language_dropdown[index] - STR_NETWORK_LANG_ANY; break; default: NOT_REACHED(); @@ -872,15 +871,14 @@ struct NetworkStartServerWindow : public if (this->widget_id == NSSW_SETPWD) { ttd_strlcpy(_settings_client.network.server_password, str, lengthof(_settings_client.network.server_password)); - _network_game_info.use_password = !StrEmpty(_settings_client.network.server_password); } else { int32 value = atoi(str); this->InvalidateWidget(this->widget_id); switch (this->widget_id) { default: NOT_REACHED(); - case NSSW_CLIENTS_TXT: _network_game_info.clients_max = Clamp(value, 2, MAX_CLIENTS); break; - case NSSW_COMPANIES_TXT: _network_game_info.companies_max = Clamp(value, 1, MAX_PLAYERS); break; - case NSSW_SPECTATORS_TXT: _network_game_info.spectators_max = Clamp(value, 0, MAX_CLIENTS); break; + case NSSW_CLIENTS_TXT: _settings_client.network.max_clients = Clamp(value, 2, MAX_CLIENTS); break; + case NSSW_COMPANIES_TXT: _settings_client.network.max_companies = Clamp(value, 1, MAX_PLAYERS); break; + case NSSW_SPECTATORS_TXT: _settings_client.network.max_spectators = Clamp(value, 0, MAX_CLIENTS); break; } } diff --git a/src/network/network_internal.h b/src/network/network_internal.h --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -95,7 +95,6 @@ enum NetworkLanguage { #define VARDEF extern -extern NetworkGameInfo _network_game_info; extern NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; extern uint32 _frame_counter_server; // The frame_counter of the server, if in network-mode diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -614,7 +614,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs); /* We now want a password from the client else we do not allow him in! */ - if (_network_game_info.use_password) { + if (!StrEmpty(_settings_client.network.server_password)) { SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD); } else { if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') { @@ -655,13 +655,13 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT // join another company does not affect these values switch (playas) { case PLAYER_NEW_COMPANY: /* New company */ - if (ActivePlayerCount() >= _network_game_info.companies_max) { + if (ActivePlayerCount() >= _settings_client.network.max_companies) { SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL); return; } break; case PLAYER_SPECTATOR: /* Spectator */ - if (NetworkSpectatorCount() >= _network_game_info.spectators_max) { + if (NetworkSpectatorCount() >= _settings_client.network.max_spectators) { SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_FULL); return; } @@ -711,7 +711,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT if (cs->status == STATUS_AUTHORIZING && type == NETWORK_GAME_PASSWORD) { // Check game-password - if (strcmp(password, _network_game_info.server_password) != 0) { + if (strcmp(password, _settings_client.network.server_password) != 0) { // Password is invalid SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD); return; @@ -1187,12 +1187,12 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT char pass[NETWORK_PASSWORD_LENGTH]; char command[NETWORK_RCONCOMMAND_LENGTH]; - if (_network_game_info.rcon_password[0] == '\0') return; + if (StrEmpty(_settings_client.network.rcon_password)) return; p->Recv_string(pass, sizeof(pass)); p->Recv_string(command, sizeof(command)); - if (strcmp(pass, _network_game_info.rcon_password) != 0) { + if (strcmp(pass, _settings_client.network.rcon_password) != 0) { DEBUG(net, 0, "[rcon] wrong password from client-id %d", cs->index); return; } diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -23,6 +23,7 @@ #include "../player_base.h" #include "../player_func.h" #include "../settings_type.h" +#include "../rev.h" #include "core/udp.h" @@ -68,21 +69,36 @@ public: DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_FIND_SERVER) { // Just a fail-safe.. should never happen - if (!_network_udp_server) + if (!_network_udp_server) { return; + } + + NetworkGameInfo ngi; + + /* Update some game_info */ + ngi.clients_on = _network_game_info.clients_on; + ngi.start_date = _network_game_info.start_date; + + ngi.server_lang = _settings_client.network.server_lang; + ngi.use_password = !StrEmpty(_settings_client.network.server_password); + ngi.clients_max = _settings_client.network.max_clients; + ngi.companies_on = ActivePlayerCount(); + ngi.companies_max = _settings_client.network.max_companies; + ngi.spectators_on = NetworkSpectatorCount(); + ngi.spectators_max = _settings_client.network.max_spectators; + ngi.game_date = _date; + ngi.map_width = MapSizeX(); + ngi.map_height = MapSizeY(); + ngi.map_set = _settings_game.game_creation.landscape; + ngi.dedicated = _network_dedicated; + ngi.grfconfig = _grfconfig; + + ttd_strlcpy(ngi.map_name, _network_game_info.map_name, lengthof(ngi.map_name)); + ttd_strlcpy(ngi.server_name, _settings_client.network.server_name, lengthof(ngi.server_name)); + ttd_strlcpy(ngi.server_revision, _openttd_revision, lengthof(ngi.server_revision)); Packet packet(PACKET_UDP_SERVER_RESPONSE); - - // Update some game_info - _network_game_info.game_date = _date; - _network_game_info.map_width = MapSizeX(); - _network_game_info.map_height = MapSizeY(); - _network_game_info.map_set = _settings_game.game_creation.landscape; - _network_game_info.companies_on = ActivePlayerCount(); - _network_game_info.spectators_on = NetworkSpectatorCount(); - _network_game_info.grfconfig = _grfconfig; - - this->Send_NetworkGameInfo(&packet, &_network_game_info); + this->Send_NetworkGameInfo(&packet, &ngi); // Let the client know that we are here this->SendPacket(&packet, client_addr); diff --git a/src/settings.cpp b/src/settings.cpp --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1447,20 +1447,10 @@ static int32 UpdatePlayerName(int32 p1) return 0; } -static int32 UpdateServerName(int32 p1) -{ - ttd_strlcpy(_network_game_info.server_name, _settings_client.network.server_name, sizeof(_network_game_info.server_name)); - return 0; -} - static int32 UpdateServerPassword(int32 p1) { if (strcmp(_settings_client.network.server_password, "*") == 0) { _settings_client.network.server_password[0] = '\0'; - _network_game_info.use_password = false; - } else { - ttd_strlcpy(_network_game_info.server_password, _settings_client.network.server_password, sizeof(_network_game_info.server_password)); - _network_game_info.use_password = true; } return 0; @@ -1472,8 +1462,6 @@ static int32 UpdateRconPassword(int32 p1 _settings_client.network.rcon_password[0] = '\0'; } - ttd_strlcpy(_network_game_info.rcon_password, _settings_client.network.rcon_password, sizeof(_network_game_info.rcon_password)); - return 0; } @@ -1813,7 +1801,7 @@ SDTC_CONDOMANY( gui.units, SDTC_STR(network.server_password, SLE_STRB, S, NO, NULL, STR_NULL, UpdateServerPassword), SDTC_STR(network.rcon_password, SLE_STRB, S, NO, NULL, STR_NULL, UpdateRconPassword), SDTC_STR(network.default_company_pass, SLE_STRB, S, 0, NULL, STR_NULL, NULL), - SDTC_STR(network.server_name, SLE_STRB, S, NO, NULL, STR_NULL, UpdateServerName), + SDTC_STR(network.server_name, SLE_STRB, S, NO, NULL, STR_NULL, NULL), SDTC_STR(network.connect_to_ip, SLE_STRB, S, 0, NULL, STR_NULL, NULL), SDTC_STR(network.network_id, SLE_STRB, S, NO, NULL, STR_NULL, NULL), SDTC_BOOL(network.autoclean_companies, S, NO, false, STR_NULL, NULL), @@ -2196,6 +2184,7 @@ bool SetPatchValue(uint index, const cha char *var = (char*)GetVariableAddress(NULL, &sd->save); ttd_strlcpy(var, value, sd->save.length); + if (sd->desc.proc != NULL) sd->desc.proc(0); return true; }