diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -13,7 +13,7 @@
#include "engine_func.h"
#include "landscape.h"
#include "saveload/saveload.h"
-#include "network/core/game_info.h"
+#include "network/core/network_game_info.h"
#include "network/network.h"
#include "network/network_func.h"
#include "network/network_base.h"
diff --git a/src/network/core/CMakeLists.txt b/src/network/core/CMakeLists.txt
--- a/src/network/core/CMakeLists.txt
+++ b/src/network/core/CMakeLists.txt
@@ -5,8 +5,8 @@ add_files(
config.h
core.cpp
core.h
- game_info.cpp
- game_info.h
+ network_game_info.cpp
+ network_game_info.h
host.cpp
host.h
http.h
diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp
deleted file mode 100644
--- a/src/network/core/game_info.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * This file is part of OpenTTD.
- * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
- * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
- */
-
-/**
- * @file game_info.cpp Functions to convert NetworkGameInfo to Packet and back.
- */
-
-#include "../../stdafx.h"
-#include "game_info.h"
-#include "../../core/bitmath_func.hpp"
-#include "../../company_base.h"
-#include "../../timer/timer_game_calendar.h"
-#include "../../debug.h"
-#include "../../map_func.h"
-#include "../../game/game.hpp"
-#include "../../game/game_info.hpp"
-#include "../../settings_type.h"
-#include "../../string_func.h"
-#include "../../rev.h"
-#include "../network_func.h"
-#include "../network.h"
-#include "packet.h"
-
-#include "../../safeguards.h"
-
-
-/**
- * How many hex digits of the git hash to include in network revision string.
- * Determined as 10 hex digits + 2 characters for -g/-u/-m prefix.
- */
-static const uint GITHASH_SUFFIX_LEN = 12;
-
-NetworkServerGameInfo _network_game_info; ///< Information about our game.
-
-/**
- * Get the network version string used by this build.
- * The returned string is guaranteed to be at most NETWORK_REVISON_LENGTH bytes including '\0' terminator.
- */
-std::string_view GetNetworkRevisionString()
-{
- static std::string network_revision;
-
- if (network_revision.empty()) {
- network_revision = _openttd_revision;
- if (_openttd_revision_tagged) {
- /* Tagged; do not mangle further, though ensure it's not too long. */
- if (network_revision.size() >= NETWORK_REVISION_LENGTH) network_revision.resize(NETWORK_REVISION_LENGTH - 1);
- } else {
- /* Not tagged; add the githash suffix while ensuring the string does not become too long. */
- assert(_openttd_revision_modified < 3);
- std::string githash_suffix = fmt::format("-{}{}", "gum"[_openttd_revision_modified], _openttd_revision_hash);
- if (githash_suffix.size() > GITHASH_SUFFIX_LEN) githash_suffix.resize(GITHASH_SUFFIX_LEN);
-
- /* Where did the hash start in the original string? Overwrite from that position, unless that would create a too long string. */
- size_t hash_end = network_revision.find_last_of('-');
- if (hash_end == std::string::npos) hash_end = network_revision.size();
- if (hash_end + githash_suffix.size() >= NETWORK_REVISION_LENGTH) hash_end = NETWORK_REVISION_LENGTH - githash_suffix.size() - 1;
-
- /* Replace the git hash in revision string. */
- network_revision.replace(hash_end, std::string::npos, githash_suffix);
- }
- assert(network_revision.size() < NETWORK_REVISION_LENGTH); // size does not include terminator, constant does, hence strictly less than
- Debug(net, 3, "Network revision name: {}", network_revision);
- }
-
- return network_revision;
-}
-
-/**
- * Extract the git hash from the revision string.
- * @param revision_string The revision string (formatted as DATE-BRANCH-GITHASH).
- * @return The git has part of the revision.
- */
-static std::string_view ExtractNetworkRevisionHash(std::string_view revision_string)
-{
- size_t index = revision_string.find_last_of('-');
- if (index == std::string::npos) return {};
- return revision_string.substr(index);
-}
-
-/**
- * Checks whether the given version string is compatible with our version.
- * First tries to match the full string, if that fails, attempts to compare just git hashes.
- * @param other the version string to compare to
- */
-bool IsNetworkCompatibleVersion(std::string_view other)
-{
- if (GetNetworkRevisionString() == other) return true;
-
- /* If this version is tagged, then the revision string must be a complete match,
- * since there is no git hash suffix in it.
- * This is needed to avoid situations like "1.9.0-beta1" comparing equal to "2.0.0-beta1". */
- if (_openttd_revision_tagged) return false;
-
- std::string_view hash1 = ExtractNetworkRevisionHash(GetNetworkRevisionString());
- std::string_view hash2 = ExtractNetworkRevisionHash(other);
- return hash1 == hash2;
-}
-
-/**
- * Check if an game entry is compatible with our client.
- */
-void CheckGameCompatibility(NetworkGameInfo &ngi)
-{
- /* Check if we are allowed on this server based on the revision-check. */
- ngi.version_compatible = IsNetworkCompatibleVersion(ngi.server_revision);
- ngi.compatible = ngi.version_compatible;
-
- /* Check if we have all the GRFs on the client-system too. */
- for (const GRFConfig *c = ngi.grfconfig; c != nullptr; c = c->next) {
- if (c->status == GCS_NOT_FOUND) ngi.compatible = false;
- }
-}
-
-/**
- * Fill a NetworkServerGameInfo structure with the static content, or things
- * that are so static they can be updated on request from a settings change.
- */
-void FillStaticNetworkServerGameInfo()
-{
- _network_game_info.use_password = !_settings_client.network.server_password.empty();
- _network_game_info.start_date = TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
- _network_game_info.clients_max = _settings_client.network.max_clients;
- _network_game_info.companies_max = _settings_client.network.max_companies;
- _network_game_info.map_width = Map::SizeX();
- _network_game_info.map_height = Map::SizeY();
- _network_game_info.landscape = _settings_game.game_creation.landscape;
- _network_game_info.dedicated = _network_dedicated;
- _network_game_info.grfconfig = _grfconfig;
-
- _network_game_info.server_name = _settings_client.network.server_name;
- _network_game_info.server_revision = GetNetworkRevisionString();
-}
-
-/**
- * Get the NetworkServerGameInfo structure with the latest information of the server.
- * @return The current NetworkServerGameInfo.
- */
-const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo()
-{
- /* These variables are updated inside _network_game_info as if they are global variables:
- * - clients_on
- * - invite_code
- * These don't need to be updated manually here.
- */
- _network_game_info.companies_on = (byte)Company::GetNumItems();
- _network_game_info.spectators_on = NetworkSpectatorCount();
- _network_game_info.game_date = TimerGameCalendar::date;
- return &_network_game_info;
-}
-
-/**
- * Function that is called for every GRFConfig that is read when receiving
- * a NetworkGameInfo. Only grfid and md5sum are set, the rest is zero. This
- * function must set all appropriate fields. This GRF is later appended to
- * the grfconfig list of the NetworkGameInfo.
- * @param config The GRF to handle.
- * @param name The name of the NewGRF, empty when unknown.
- */
-static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config, std::string name)
-{
- /* Find the matching GRF file */
- const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, &config->ident.md5sum);
- if (f == nullptr) {
- AddGRFTextToList(config->name, name.empty() ? GetString(STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN) : name);
- config->status = GCS_NOT_FOUND;
- } else {
- config->filename = f->filename;
- config->name = f->name;
- config->info = f->info;
- config->url = f->url;
- }
- SetBit(config->flags, GCF_COPY);
-}
-
-/**
- * Serializes the NetworkGameInfo struct to the packet.
- * @param p the packet to write the data to.
- * @param info the NetworkGameInfo struct to serialize from.
- */
-void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names)
-{
- p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
-
- /*
- * Please observe the order.
- * The parts must be read in the same order as they are sent!
- */
-
- /* Update the documentation in game_info.h on changes
- * to the NetworkGameInfo wire-protocol! */
-
- /* NETWORK_GAME_INFO_VERSION = 6 */
- p->Send_uint8(send_newgrf_names ? NST_GRFID_MD5_NAME : NST_GRFID_MD5);
-
- /* NETWORK_GAME_INFO_VERSION = 5 */
- GameInfo *game_info = Game::GetInfo();
- p->Send_uint32(game_info == nullptr ? -1 : (uint32_t)game_info->GetVersion());
- p->Send_string(game_info == nullptr ? "" : game_info->GetName());
-
- /* NETWORK_GAME_INFO_VERSION = 4 */
- {
- /* Only send the GRF Identification (GRF_ID and MD5 checksum) of
- * the GRFs that are needed, i.e. the ones that the server has
- * selected in the NewGRF GUI and not the ones that are used due
- * to the fact that they are in [newgrf-static] in openttd.cfg */
- const GRFConfig *c;
- uint count = 0;
-
- /* Count number of GRFs to send information about */
- for (c = info->grfconfig; c != nullptr; c = c->next) {
- if (!HasBit(c->flags, GCF_STATIC)) count++;
- }
- p->Send_uint8 (count); // Send number of GRFs
-
- /* Send actual GRF Identifications */
- for (c = info->grfconfig; c != nullptr; c = c->next) {
- if (HasBit(c->flags, GCF_STATIC)) continue;
-
- SerializeGRFIdentifier(p, &c->ident);
- if (send_newgrf_names) p->Send_string(c->GetName());
- }
- }
-
- /* NETWORK_GAME_INFO_VERSION = 3 */
- p->Send_uint32(static_cast(info->game_date));
- p->Send_uint32(static_cast(info->start_date));
-
- /* NETWORK_GAME_INFO_VERSION = 2 */
- p->Send_uint8 (info->companies_max);
- p->Send_uint8 (info->companies_on);
- p->Send_uint8 (info->clients_max); // Used to be max-spectators
-
- /* NETWORK_GAME_INFO_VERSION = 1 */
- p->Send_string(info->server_name);
- p->Send_string(info->server_revision);
- p->Send_bool (info->use_password);
- p->Send_uint8 (info->clients_max);
- p->Send_uint8 (info->clients_on);
- p->Send_uint8 (info->spectators_on);
- p->Send_uint16(info->map_width);
- p->Send_uint16(info->map_height);
- p->Send_uint8 (info->landscape);
- p->Send_bool (info->dedicated);
-}
-
-/**
- * Deserializes the NetworkGameInfo struct from the packet.
- * @param p the packet to read the data from.
- * @param info the NetworkGameInfo to deserialize into.
- */
-void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table)
-{
- static const TimerGameCalendar::Date MAX_DATE = TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
-
- byte game_info_version = p->Recv_uint8();
- NewGRFSerializationType newgrf_serialisation = NST_GRFID_MD5;
-
- /*
- * Please observe the order.
- * The parts must be read in the same order as they are sent!
- */
-
- /* Update the documentation in game_info.h on changes
- * to the NetworkGameInfo wire-protocol! */
-
- switch (game_info_version) {
- case 6:
- newgrf_serialisation = (NewGRFSerializationType)p->Recv_uint8();
- if (newgrf_serialisation >= NST_END) return;
- FALLTHROUGH;
-
- case 5: {
- info->gamescript_version = (int)p->Recv_uint32();
- info->gamescript_name = p->Recv_string(NETWORK_NAME_LENGTH);
- FALLTHROUGH;
- }
-
- case 4: {
- /* Ensure that the maximum number of NewGRFs and the field in the network
- * protocol are matched to eachother. If that is not the case anymore a
- * check must be added to ensure the received data is still valid. */
- static_assert(std::numeric_limits::max() == NETWORK_MAX_GRF_COUNT);
- uint num_grfs = p->Recv_uint8();
-
- GRFConfig **dst = &info->grfconfig;
- for (uint i = 0; i < num_grfs; i++) {
- NamedGRFIdentifier grf;
- switch (newgrf_serialisation) {
- case NST_GRFID_MD5:
- DeserializeGRFIdentifier(p, &grf.ident);
- break;
-
- case NST_GRFID_MD5_NAME:
- DeserializeGRFIdentifierWithName(p, &grf);
- break;
-
- case NST_LOOKUP_ID: {
- if (newgrf_lookup_table == nullptr) return;
- auto it = newgrf_lookup_table->find(p->Recv_uint32());
- if (it == newgrf_lookup_table->end()) return;
- grf = it->second;
- break;
- }
-
- default:
- NOT_REACHED();
- }
-
- GRFConfig *c = new GRFConfig();
- c->ident = grf.ident;
- HandleIncomingNetworkGameInfoGRFConfig(c, grf.name);
-
- /* Append GRFConfig to the list */
- *dst = c;
- dst = &c->next;
- }
- FALLTHROUGH;
- }
-
- case 3:
- info->game_date = Clamp(p->Recv_uint32(), 0, static_cast(MAX_DATE));
- info->start_date = Clamp(p->Recv_uint32(), 0, static_cast(MAX_DATE));
- FALLTHROUGH;
-
- case 2:
- info->companies_max = p->Recv_uint8 ();
- info->companies_on = p->Recv_uint8 ();
- p->Recv_uint8(); // Used to contain max-spectators.
- FALLTHROUGH;
-
- case 1:
- info->server_name = p->Recv_string(NETWORK_NAME_LENGTH);
- info->server_revision = p->Recv_string(NETWORK_REVISION_LENGTH);
- if (game_info_version < 6) p->Recv_uint8 (); // Used to contain server-lang.
- info->use_password = p->Recv_bool ();
- info->clients_max = p->Recv_uint8 ();
- info->clients_on = p->Recv_uint8 ();
- info->spectators_on = p->Recv_uint8 ();
- if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
- info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
- info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
- }
- if (game_info_version < 6) while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
- info->map_width = p->Recv_uint16();
- info->map_height = p->Recv_uint16();
- info->landscape = p->Recv_uint8 ();
- info->dedicated = p->Recv_bool ();
-
- if (info->landscape >= NUM_LANDSCAPE) info->landscape = 0;
- }
-}
-
-/**
- * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
- * @param p the packet to write the data to.
- * @param grf the GRFIdentifier to serialize.
- */
-void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
-{
- p->Send_uint32(grf->grfid);
- for (size_t j = 0; j < grf->md5sum.size(); j++) {
- p->Send_uint8(grf->md5sum[j]);
- }
-}
-
-/**
- * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet
- * @param p the packet to read the data from.
- * @param grf the GRFIdentifier to deserialize.
- */
-void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf)
-{
- grf->grfid = p->Recv_uint32();
- for (size_t j = 0; j < grf->md5sum.size(); j++) {
- grf->md5sum[j] = p->Recv_uint8();
- }
-}
-
-/**
- * Deserializes the NamedGRFIdentifier (GRF ID, MD5 checksum and name) from the packet
- * @param p the packet to read the data from.
- * @param grf the NamedGRFIdentifier to deserialize.
- */
-void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf)
-{
- DeserializeGRFIdentifier(p, &grf->ident);
- grf->name = p->Recv_string(NETWORK_GRF_NAME_LENGTH);
-}
diff --git a/src/network/core/game_info.h b/src/network/core/game_info.h
deleted file mode 100644
--- a/src/network/core/game_info.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * This file is part of OpenTTD.
- * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
- * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
- */
-
-/**
- * @file game_info.h Convert NetworkGameInfo to Packet and back.
- */
-
-#ifndef NETWORK_CORE_GAME_INFO_H
-#define NETWORK_CORE_GAME_INFO_H
-
-#include "config.h"
-#include "core.h"
-#include "../../newgrf_config.h"
-#include "../../timer/timer_game_calendar.h"
-
-#include
-
-/*
- * NetworkGameInfo has several revisions which we still need to support on the
- * wire. The table below shows the version and size for each field of the
- * serialized NetworkGameInfo.
- *
- * Version: Bytes: Description:
- * all 1 the version of this packet's structure
- *
- * 6+ 1 type of storage for the NewGRFs below:
- * 0 = NewGRF ID and MD5 checksum.
- * Used as default for version 5 and below, and for
- * later game updates to the Game Coordinator.
- * 1 = NewGRF ID, MD5 checksum and name.
- * Used for direct requests and the first game
- * update to Game Coordinator.
- * 2 = Index in NewGRF lookup table.
- * Used for sending server listing from the Game
- * Coordinator to the clients.
- *
- * 5+ 4 version number of the Game Script (-1 is case none is selected).
- * 5+ var string with the name of the Game Script.
- *
- * 4+ 1 number of GRFs attached (n).
- * 4+ n * var identifiers for GRF files. Consists of:
- * Note: the 'vN' refers to packet version and 'type'
- * refers to the v6+ type of storage for the NewGRFs.
- * - 4 byte variable with the GRF ID.
- * For v4, v5, and v6+ in case of type 0 and/or type 1.
- * - 16 bytes with the MD5 checksum of the GRF.
- * For v4, v5, and v6+ in case of type 0 and/or type 1.
- * - string with name of NewGRF.
- * For v6+ in case of type 1.
- * - 4 byte lookup table index.
- * For v6+ in case of type 2.
- *
- * 3+ 4 current game date in days since 1-1-0 (DMY)
- * 3+ 4 game introduction date in days since 1-1-0 (DMY)
- *
- * 2+ 1 maximum number of companies allowed on the server
- * 2+ 1 number of companies on the server
- * 2+ 1 maximum number of spectators allowed on the server
- *
- * 1+ var string with the name of the server
- * 1+ var string with the revision of the server
- * 1 - 5 1 the language run on the server
- * (0 = any, 1 = English, 2 = German, 3 = French)
- * 1+ 1 whether the server uses a password (0 = no, 1 = yes)
- * 1+ 1 maximum number of clients allowed on the server
- * 1+ 1 number of clients on the server
- * 1+ 1 number of spectators on the server
- * 1 & 2 2 current game date in days since 1-1-1920 (DMY)
- * 1 & 2 2 game introduction date in days since 1-1-1920 (DMY)
- * 1 - 5 var string with the name of the map
- * 1+ 2 width of the map in tiles
- * 1+ 2 height of the map in tiles
- * 1+ 1 type of map:
- * (0 = temperate, 1 = arctic, 2 = desert, 3 = toyland)
- * 1+ 1 whether the server is dedicated (0 = no, 1 = yes)
- */
-
-/** The different types/ways a NewGRF can be serialized in the GameInfo since version 6. */
-enum NewGRFSerializationType {
- NST_GRFID_MD5 = 0, ///< Unique GRF ID and MD5 checksum.
- NST_GRFID_MD5_NAME = 1, ///< Unique GRF ID, MD5 checksum and name.
- NST_LOOKUP_ID = 2, ///< Unique ID into a lookup table that is sent before.
- NST_END ///< The end of the list (period).
-};
-
-/**
- * The game information that is sent from the server to the client.
- */
-struct NetworkServerGameInfo {
- GRFConfig *grfconfig; ///< List of NewGRF files used
- TimerGameCalendar::Date start_date; ///< When the game started
- TimerGameCalendar::Date game_date; ///< Current date
- uint16_t map_width; ///< Map width
- uint16_t map_height; ///< Map height
- std::string server_name; ///< Server name
- std::string server_revision; ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
- bool dedicated; ///< Is this a dedicated server?
- bool use_password; ///< Is this server passworded?
- byte clients_on; ///< Current count of clients on server
- byte clients_max; ///< Max clients 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 landscape; ///< The used landscape
- int gamescript_version; ///< Version of the gamescript.
- std::string gamescript_name; ///< Name of the gamescript.
-};
-
-/**
- * The game information that is sent from the server to the clients
- * with extra information only required at the client side.
- */
-struct NetworkGameInfo : NetworkServerGameInfo {
- bool version_compatible; ///< Can we connect to this server or not? (based on server_revision)
- bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match
-};
-
-/**
- * Container to hold the GRF identifier (GRF ID + MD5 checksum) and the name
- * associated with that NewGRF.
- */
-struct NamedGRFIdentifier {
- GRFIdentifier ident; ///< The unique identifier of the NewGRF.
- std::string name; ///< The name of the NewGRF.
-};
-/** Lookup table for the GameInfo in case of #NST_LOOKUP_ID. */
-typedef std::unordered_map GameInfoNewGRFLookupTable;
-
-extern NetworkServerGameInfo _network_game_info;
-
-std::string_view GetNetworkRevisionString();
-bool IsNetworkCompatibleVersion(std::string_view other);
-void CheckGameCompatibility(NetworkGameInfo &ngi);
-
-void FillStaticNetworkServerGameInfo();
-const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo();
-
-void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf);
-void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf);
-void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf);
-
-void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table = nullptr);
-void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names = true);
-
-#endif /* NETWORK_CORE_GAME_INFO_H */
diff --git a/src/network/core/network_game_info.cpp b/src/network/core/network_game_info.cpp
new file mode 100644
--- /dev/null
+++ b/src/network/core/network_game_info.cpp
@@ -0,0 +1,393 @@
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/**
+ * @file game_info.cpp Functions to convert NetworkGameInfo to Packet and back.
+ */
+
+#include "../../stdafx.h"
+#include "network_game_info.h"
+#include "../../core/bitmath_func.hpp"
+#include "../../company_base.h"
+#include "../../timer/timer_game_calendar.h"
+#include "../../debug.h"
+#include "../../map_func.h"
+#include "../../game/game.hpp"
+#include "../../game/game_info.hpp"
+#include "../../settings_type.h"
+#include "../../string_func.h"
+#include "../../rev.h"
+#include "../network_func.h"
+#include "../network.h"
+#include "packet.h"
+
+#include "../../safeguards.h"
+
+
+/**
+ * How many hex digits of the git hash to include in network revision string.
+ * Determined as 10 hex digits + 2 characters for -g/-u/-m prefix.
+ */
+static const uint GITHASH_SUFFIX_LEN = 12;
+
+NetworkServerGameInfo _network_game_info; ///< Information about our game.
+
+/**
+ * Get the network version string used by this build.
+ * The returned string is guaranteed to be at most NETWORK_REVISON_LENGTH bytes including '\0' terminator.
+ */
+std::string_view GetNetworkRevisionString()
+{
+ static std::string network_revision;
+
+ if (network_revision.empty()) {
+ network_revision = _openttd_revision;
+ if (_openttd_revision_tagged) {
+ /* Tagged; do not mangle further, though ensure it's not too long. */
+ if (network_revision.size() >= NETWORK_REVISION_LENGTH) network_revision.resize(NETWORK_REVISION_LENGTH - 1);
+ } else {
+ /* Not tagged; add the githash suffix while ensuring the string does not become too long. */
+ assert(_openttd_revision_modified < 3);
+ std::string githash_suffix = fmt::format("-{}{}", "gum"[_openttd_revision_modified], _openttd_revision_hash);
+ if (githash_suffix.size() > GITHASH_SUFFIX_LEN) githash_suffix.resize(GITHASH_SUFFIX_LEN);
+
+ /* Where did the hash start in the original string? Overwrite from that position, unless that would create a too long string. */
+ size_t hash_end = network_revision.find_last_of('-');
+ if (hash_end == std::string::npos) hash_end = network_revision.size();
+ if (hash_end + githash_suffix.size() >= NETWORK_REVISION_LENGTH) hash_end = NETWORK_REVISION_LENGTH - githash_suffix.size() - 1;
+
+ /* Replace the git hash in revision string. */
+ network_revision.replace(hash_end, std::string::npos, githash_suffix);
+ }
+ assert(network_revision.size() < NETWORK_REVISION_LENGTH); // size does not include terminator, constant does, hence strictly less than
+ Debug(net, 3, "Network revision name: {}", network_revision);
+ }
+
+ return network_revision;
+}
+
+/**
+ * Extract the git hash from the revision string.
+ * @param revision_string The revision string (formatted as DATE-BRANCH-GITHASH).
+ * @return The git has part of the revision.
+ */
+static std::string_view ExtractNetworkRevisionHash(std::string_view revision_string)
+{
+ size_t index = revision_string.find_last_of('-');
+ if (index == std::string::npos) return {};
+ return revision_string.substr(index);
+}
+
+/**
+ * Checks whether the given version string is compatible with our version.
+ * First tries to match the full string, if that fails, attempts to compare just git hashes.
+ * @param other the version string to compare to
+ */
+bool IsNetworkCompatibleVersion(std::string_view other)
+{
+ if (GetNetworkRevisionString() == other) return true;
+
+ /* If this version is tagged, then the revision string must be a complete match,
+ * since there is no git hash suffix in it.
+ * This is needed to avoid situations like "1.9.0-beta1" comparing equal to "2.0.0-beta1". */
+ if (_openttd_revision_tagged) return false;
+
+ std::string_view hash1 = ExtractNetworkRevisionHash(GetNetworkRevisionString());
+ std::string_view hash2 = ExtractNetworkRevisionHash(other);
+ return hash1 == hash2;
+}
+
+/**
+ * Check if an game entry is compatible with our client.
+ */
+void CheckGameCompatibility(NetworkGameInfo &ngi)
+{
+ /* Check if we are allowed on this server based on the revision-check. */
+ ngi.version_compatible = IsNetworkCompatibleVersion(ngi.server_revision);
+ ngi.compatible = ngi.version_compatible;
+
+ /* Check if we have all the GRFs on the client-system too. */
+ for (const GRFConfig *c = ngi.grfconfig; c != nullptr; c = c->next) {
+ if (c->status == GCS_NOT_FOUND) ngi.compatible = false;
+ }
+}
+
+/**
+ * Fill a NetworkServerGameInfo structure with the static content, or things
+ * that are so static they can be updated on request from a settings change.
+ */
+void FillStaticNetworkServerGameInfo()
+{
+ _network_game_info.use_password = !_settings_client.network.server_password.empty();
+ _network_game_info.start_date = TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
+ _network_game_info.clients_max = _settings_client.network.max_clients;
+ _network_game_info.companies_max = _settings_client.network.max_companies;
+ _network_game_info.map_width = Map::SizeX();
+ _network_game_info.map_height = Map::SizeY();
+ _network_game_info.landscape = _settings_game.game_creation.landscape;
+ _network_game_info.dedicated = _network_dedicated;
+ _network_game_info.grfconfig = _grfconfig;
+
+ _network_game_info.server_name = _settings_client.network.server_name;
+ _network_game_info.server_revision = GetNetworkRevisionString();
+}
+
+/**
+ * Get the NetworkServerGameInfo structure with the latest information of the server.
+ * @return The current NetworkServerGameInfo.
+ */
+const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo()
+{
+ /* These variables are updated inside _network_game_info as if they are global variables:
+ * - clients_on
+ * - invite_code
+ * These don't need to be updated manually here.
+ */
+ _network_game_info.companies_on = (byte)Company::GetNumItems();
+ _network_game_info.spectators_on = NetworkSpectatorCount();
+ _network_game_info.game_date = TimerGameCalendar::date;
+ return &_network_game_info;
+}
+
+/**
+ * Function that is called for every GRFConfig that is read when receiving
+ * a NetworkGameInfo. Only grfid and md5sum are set, the rest is zero. This
+ * function must set all appropriate fields. This GRF is later appended to
+ * the grfconfig list of the NetworkGameInfo.
+ * @param config The GRF to handle.
+ * @param name The name of the NewGRF, empty when unknown.
+ */
+static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config, std::string name)
+{
+ /* Find the matching GRF file */
+ const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, &config->ident.md5sum);
+ if (f == nullptr) {
+ AddGRFTextToList(config->name, name.empty() ? GetString(STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN) : name);
+ config->status = GCS_NOT_FOUND;
+ } else {
+ config->filename = f->filename;
+ config->name = f->name;
+ config->info = f->info;
+ config->url = f->url;
+ }
+ SetBit(config->flags, GCF_COPY);
+}
+
+/**
+ * Serializes the NetworkGameInfo struct to the packet.
+ * @param p the packet to write the data to.
+ * @param info the NetworkGameInfo struct to serialize from.
+ */
+void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names)
+{
+ p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
+
+ /*
+ * Please observe the order.
+ * The parts must be read in the same order as they are sent!
+ */
+
+ /* Update the documentation in game_info.h on changes
+ * to the NetworkGameInfo wire-protocol! */
+
+ /* NETWORK_GAME_INFO_VERSION = 6 */
+ p->Send_uint8(send_newgrf_names ? NST_GRFID_MD5_NAME : NST_GRFID_MD5);
+
+ /* NETWORK_GAME_INFO_VERSION = 5 */
+ GameInfo *game_info = Game::GetInfo();
+ p->Send_uint32(game_info == nullptr ? -1 : (uint32_t)game_info->GetVersion());
+ p->Send_string(game_info == nullptr ? "" : game_info->GetName());
+
+ /* NETWORK_GAME_INFO_VERSION = 4 */
+ {
+ /* Only send the GRF Identification (GRF_ID and MD5 checksum) of
+ * the GRFs that are needed, i.e. the ones that the server has
+ * selected in the NewGRF GUI and not the ones that are used due
+ * to the fact that they are in [newgrf-static] in openttd.cfg */
+ const GRFConfig *c;
+ uint count = 0;
+
+ /* Count number of GRFs to send information about */
+ for (c = info->grfconfig; c != nullptr; c = c->next) {
+ if (!HasBit(c->flags, GCF_STATIC)) count++;
+ }
+ p->Send_uint8 (count); // Send number of GRFs
+
+ /* Send actual GRF Identifications */
+ for (c = info->grfconfig; c != nullptr; c = c->next) {
+ if (HasBit(c->flags, GCF_STATIC)) continue;
+
+ SerializeGRFIdentifier(p, &c->ident);
+ if (send_newgrf_names) p->Send_string(c->GetName());
+ }
+ }
+
+ /* NETWORK_GAME_INFO_VERSION = 3 */
+ p->Send_uint32(static_cast(info->game_date));
+ p->Send_uint32(static_cast(info->start_date));
+
+ /* NETWORK_GAME_INFO_VERSION = 2 */
+ p->Send_uint8 (info->companies_max);
+ p->Send_uint8 (info->companies_on);
+ p->Send_uint8 (info->clients_max); // Used to be max-spectators
+
+ /* NETWORK_GAME_INFO_VERSION = 1 */
+ p->Send_string(info->server_name);
+ p->Send_string(info->server_revision);
+ p->Send_bool (info->use_password);
+ p->Send_uint8 (info->clients_max);
+ p->Send_uint8 (info->clients_on);
+ p->Send_uint8 (info->spectators_on);
+ p->Send_uint16(info->map_width);
+ p->Send_uint16(info->map_height);
+ p->Send_uint8 (info->landscape);
+ p->Send_bool (info->dedicated);
+}
+
+/**
+ * Deserializes the NetworkGameInfo struct from the packet.
+ * @param p the packet to read the data from.
+ * @param info the NetworkGameInfo to deserialize into.
+ */
+void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table)
+{
+ static const TimerGameCalendar::Date MAX_DATE = TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
+
+ byte game_info_version = p->Recv_uint8();
+ NewGRFSerializationType newgrf_serialisation = NST_GRFID_MD5;
+
+ /*
+ * Please observe the order.
+ * The parts must be read in the same order as they are sent!
+ */
+
+ /* Update the documentation in game_info.h on changes
+ * to the NetworkGameInfo wire-protocol! */
+
+ switch (game_info_version) {
+ case 6:
+ newgrf_serialisation = (NewGRFSerializationType)p->Recv_uint8();
+ if (newgrf_serialisation >= NST_END) return;
+ FALLTHROUGH;
+
+ case 5: {
+ info->gamescript_version = (int)p->Recv_uint32();
+ info->gamescript_name = p->Recv_string(NETWORK_NAME_LENGTH);
+ FALLTHROUGH;
+ }
+
+ case 4: {
+ /* Ensure that the maximum number of NewGRFs and the field in the network
+ * protocol are matched to eachother. If that is not the case anymore a
+ * check must be added to ensure the received data is still valid. */
+ static_assert(std::numeric_limits::max() == NETWORK_MAX_GRF_COUNT);
+ uint num_grfs = p->Recv_uint8();
+
+ GRFConfig **dst = &info->grfconfig;
+ for (uint i = 0; i < num_grfs; i++) {
+ NamedGRFIdentifier grf;
+ switch (newgrf_serialisation) {
+ case NST_GRFID_MD5:
+ DeserializeGRFIdentifier(p, &grf.ident);
+ break;
+
+ case NST_GRFID_MD5_NAME:
+ DeserializeGRFIdentifierWithName(p, &grf);
+ break;
+
+ case NST_LOOKUP_ID: {
+ if (newgrf_lookup_table == nullptr) return;
+ auto it = newgrf_lookup_table->find(p->Recv_uint32());
+ if (it == newgrf_lookup_table->end()) return;
+ grf = it->second;
+ break;
+ }
+
+ default:
+ NOT_REACHED();
+ }
+
+ GRFConfig *c = new GRFConfig();
+ c->ident = grf.ident;
+ HandleIncomingNetworkGameInfoGRFConfig(c, grf.name);
+
+ /* Append GRFConfig to the list */
+ *dst = c;
+ dst = &c->next;
+ }
+ FALLTHROUGH;
+ }
+
+ case 3:
+ info->game_date = Clamp(p->Recv_uint32(), 0, static_cast(MAX_DATE));
+ info->start_date = Clamp(p->Recv_uint32(), 0, static_cast(MAX_DATE));
+ FALLTHROUGH;
+
+ case 2:
+ info->companies_max = p->Recv_uint8 ();
+ info->companies_on = p->Recv_uint8 ();
+ p->Recv_uint8(); // Used to contain max-spectators.
+ FALLTHROUGH;
+
+ case 1:
+ info->server_name = p->Recv_string(NETWORK_NAME_LENGTH);
+ info->server_revision = p->Recv_string(NETWORK_REVISION_LENGTH);
+ if (game_info_version < 6) p->Recv_uint8 (); // Used to contain server-lang.
+ info->use_password = p->Recv_bool ();
+ info->clients_max = p->Recv_uint8 ();
+ info->clients_on = p->Recv_uint8 ();
+ info->spectators_on = p->Recv_uint8 ();
+ if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
+ info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
+ info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
+ }
+ if (game_info_version < 6) while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
+ info->map_width = p->Recv_uint16();
+ info->map_height = p->Recv_uint16();
+ info->landscape = p->Recv_uint8 ();
+ info->dedicated = p->Recv_bool ();
+
+ if (info->landscape >= NUM_LANDSCAPE) info->landscape = 0;
+ }
+}
+
+/**
+ * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
+ * @param p the packet to write the data to.
+ * @param grf the GRFIdentifier to serialize.
+ */
+void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
+{
+ p->Send_uint32(grf->grfid);
+ for (size_t j = 0; j < grf->md5sum.size(); j++) {
+ p->Send_uint8(grf->md5sum[j]);
+ }
+}
+
+/**
+ * Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet
+ * @param p the packet to read the data from.
+ * @param grf the GRFIdentifier to deserialize.
+ */
+void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf)
+{
+ grf->grfid = p->Recv_uint32();
+ for (size_t j = 0; j < grf->md5sum.size(); j++) {
+ grf->md5sum[j] = p->Recv_uint8();
+ }
+}
+
+/**
+ * Deserializes the NamedGRFIdentifier (GRF ID, MD5 checksum and name) from the packet
+ * @param p the packet to read the data from.
+ * @param grf the NamedGRFIdentifier to deserialize.
+ */
+void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf)
+{
+ DeserializeGRFIdentifier(p, &grf->ident);
+ grf->name = p->Recv_string(NETWORK_GRF_NAME_LENGTH);
+}
diff --git a/src/network/core/network_game_info.h b/src/network/core/network_game_info.h
new file mode 100644
--- /dev/null
+++ b/src/network/core/network_game_info.h
@@ -0,0 +1,149 @@
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+/**
+ * @file game_info.h Convert NetworkGameInfo to Packet and back.
+ */
+
+#ifndef NETWORK_CORE_GAME_INFO_H
+#define NETWORK_CORE_GAME_INFO_H
+
+#include "config.h"
+#include "core.h"
+#include "../../newgrf_config.h"
+#include "../../timer/timer_game_calendar.h"
+
+#include
+
+/*
+ * NetworkGameInfo has several revisions which we still need to support on the
+ * wire. The table below shows the version and size for each field of the
+ * serialized NetworkGameInfo.
+ *
+ * Version: Bytes: Description:
+ * all 1 the version of this packet's structure
+ *
+ * 6+ 1 type of storage for the NewGRFs below:
+ * 0 = NewGRF ID and MD5 checksum.
+ * Used as default for version 5 and below, and for
+ * later game updates to the Game Coordinator.
+ * 1 = NewGRF ID, MD5 checksum and name.
+ * Used for direct requests and the first game
+ * update to Game Coordinator.
+ * 2 = Index in NewGRF lookup table.
+ * Used for sending server listing from the Game
+ * Coordinator to the clients.
+ *
+ * 5+ 4 version number of the Game Script (-1 is case none is selected).
+ * 5+ var string with the name of the Game Script.
+ *
+ * 4+ 1 number of GRFs attached (n).
+ * 4+ n * var identifiers for GRF files. Consists of:
+ * Note: the 'vN' refers to packet version and 'type'
+ * refers to the v6+ type of storage for the NewGRFs.
+ * - 4 byte variable with the GRF ID.
+ * For v4, v5, and v6+ in case of type 0 and/or type 1.
+ * - 16 bytes with the MD5 checksum of the GRF.
+ * For v4, v5, and v6+ in case of type 0 and/or type 1.
+ * - string with name of NewGRF.
+ * For v6+ in case of type 1.
+ * - 4 byte lookup table index.
+ * For v6+ in case of type 2.
+ *
+ * 3+ 4 current game date in days since 1-1-0 (DMY)
+ * 3+ 4 game introduction date in days since 1-1-0 (DMY)
+ *
+ * 2+ 1 maximum number of companies allowed on the server
+ * 2+ 1 number of companies on the server
+ * 2+ 1 maximum number of spectators allowed on the server
+ *
+ * 1+ var string with the name of the server
+ * 1+ var string with the revision of the server
+ * 1 - 5 1 the language run on the server
+ * (0 = any, 1 = English, 2 = German, 3 = French)
+ * 1+ 1 whether the server uses a password (0 = no, 1 = yes)
+ * 1+ 1 maximum number of clients allowed on the server
+ * 1+ 1 number of clients on the server
+ * 1+ 1 number of spectators on the server
+ * 1 & 2 2 current game date in days since 1-1-1920 (DMY)
+ * 1 & 2 2 game introduction date in days since 1-1-1920 (DMY)
+ * 1 - 5 var string with the name of the map
+ * 1+ 2 width of the map in tiles
+ * 1+ 2 height of the map in tiles
+ * 1+ 1 type of map:
+ * (0 = temperate, 1 = arctic, 2 = desert, 3 = toyland)
+ * 1+ 1 whether the server is dedicated (0 = no, 1 = yes)
+ */
+
+/** The different types/ways a NewGRF can be serialized in the GameInfo since version 6. */
+enum NewGRFSerializationType {
+ NST_GRFID_MD5 = 0, ///< Unique GRF ID and MD5 checksum.
+ NST_GRFID_MD5_NAME = 1, ///< Unique GRF ID, MD5 checksum and name.
+ NST_LOOKUP_ID = 2, ///< Unique ID into a lookup table that is sent before.
+ NST_END ///< The end of the list (period).
+};
+
+/**
+ * The game information that is sent from the server to the client.
+ */
+struct NetworkServerGameInfo {
+ GRFConfig *grfconfig; ///< List of NewGRF files used
+ TimerGameCalendar::Date start_date; ///< When the game started
+ TimerGameCalendar::Date game_date; ///< Current date
+ uint16_t map_width; ///< Map width
+ uint16_t map_height; ///< Map height
+ std::string server_name; ///< Server name
+ std::string server_revision; ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
+ bool dedicated; ///< Is this a dedicated server?
+ bool use_password; ///< Is this server passworded?
+ byte clients_on; ///< Current count of clients on server
+ byte clients_max; ///< Max clients 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 landscape; ///< The used landscape
+ int gamescript_version; ///< Version of the gamescript.
+ std::string gamescript_name; ///< Name of the gamescript.
+};
+
+/**
+ * The game information that is sent from the server to the clients
+ * with extra information only required at the client side.
+ */
+struct NetworkGameInfo : NetworkServerGameInfo {
+ bool version_compatible; ///< Can we connect to this server or not? (based on server_revision)
+ bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match
+};
+
+/**
+ * Container to hold the GRF identifier (GRF ID + MD5 checksum) and the name
+ * associated with that NewGRF.
+ */
+struct NamedGRFIdentifier {
+ GRFIdentifier ident; ///< The unique identifier of the NewGRF.
+ std::string name; ///< The name of the NewGRF.
+};
+/** Lookup table for the GameInfo in case of #NST_LOOKUP_ID. */
+typedef std::unordered_map GameInfoNewGRFLookupTable;
+
+extern NetworkServerGameInfo _network_game_info;
+
+std::string_view GetNetworkRevisionString();
+bool IsNetworkCompatibleVersion(std::string_view other);
+void CheckGameCompatibility(NetworkGameInfo &ngi);
+
+void FillStaticNetworkServerGameInfo();
+const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo();
+
+void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf);
+void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf);
+void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf);
+
+void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table = nullptr);
+void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names = true);
+
+#endif /* NETWORK_CORE_GAME_INFO_H */
diff --git a/src/network/core/tcp_coordinator.h b/src/network/core/tcp_coordinator.h
--- a/src/network/core/tcp_coordinator.h
+++ b/src/network/core/tcp_coordinator.h
@@ -15,7 +15,7 @@
#include "os_abstraction.h"
#include "tcp.h"
#include "packet.h"
-#include "game_info.h"
+#include "network_game_info.h"
/**
* Enum with all types of TCP Game Coordinator packets. The order MUST not be changed.
diff --git a/src/network/core/tcp_turn.h b/src/network/core/tcp_turn.h
--- a/src/network/core/tcp_turn.h
+++ b/src/network/core/tcp_turn.h
@@ -15,7 +15,7 @@
#include "os_abstraction.h"
#include "tcp.h"
#include "packet.h"
-#include "game_info.h"
+#include "network_game_info.h"
/** Enum with all types of TCP TURN packets. The order MUST not be changed. **/
enum PacketTurnType {
diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp
--- a/src/network/core/udp.cpp
+++ b/src/network/core/udp.cpp
@@ -12,7 +12,7 @@
#include "../../stdafx.h"
#include "../../timer/timer_game_calendar.h"
#include "../../debug.h"
-#include "game_info.h"
+#include "network_game_info.h"
#include "udp.h"
#include "../../safeguards.h"
diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp
--- a/src/network/network_admin.cpp
+++ b/src/network/network_admin.cpp
@@ -11,7 +11,7 @@
#include "../strings_func.h"
#include "../timer/timer_game_calendar.h"
#include "../timer/timer_game_calendar.h"
-#include "core/game_info.h"
+#include "core/network_game_info.h"
#include "network_admin.h"
#include "network_base.h"
#include "network_server.h"
diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h
--- a/src/network/network_gamelist.h
+++ b/src/network/network_gamelist.h
@@ -11,7 +11,7 @@
#define NETWORK_GAMELIST_H
#include "core/address.h"
-#include "core/game_info.h"
+#include "core/network_game_info.h"
#include "network_type.h"
/** The status a server can be in. */
diff --git a/src/network/network_query.cpp b/src/network/network_query.cpp
--- a/src/network/network_query.cpp
+++ b/src/network/network_query.cpp
@@ -8,7 +8,7 @@
/** @file network_query.cpp Query part of the network protocol. */
#include "../stdafx.h"
-#include "core/game_info.h"
+#include "core/network_game_info.h"
#include "network_query.h"
#include "network_gamelist.h"
#include "../error.h"
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
@@ -9,7 +9,7 @@
#include "../stdafx.h"
#include "../strings_func.h"
-#include "core/game_info.h"
+#include "core/network_game_info.h"
#include "network_admin.h"
#include "network_server.h"
#include "network_udp.h"
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
@@ -16,7 +16,7 @@
#include "../timer/timer_game_calendar.h"
#include "../map_func.h"
#include "../debug.h"
-#include "core/game_info.h"
+#include "core/network_game_info.h"
#include "network_gamelist.h"
#include "network_internal.h"
#include "network_udp.h"