summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/core/config.h2
-rw-r--r--src/network/core/game_info.cpp58
-rw-r--r--src/network/core/game_info.h46
-rw-r--r--src/network/network_coordinator.cpp5
4 files changed, 89 insertions, 22 deletions
diff --git a/src/network/core/config.h b/src/network/core/config.h
index 6039c4252..ccc9cd263 100644
--- a/src/network/core/config.h
+++ b/src/network/core/config.h
@@ -47,7 +47,7 @@ static const uint16 TCP_MTU = 32767; ///< Numbe
static const uint16 COMPAT_MTU = 1460; ///< Number of bytes we can pack in a single packet for backward compatibility
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
-static const byte NETWORK_GAME_INFO_VERSION = 5; ///< What version of game-info do we use?
+static const byte NETWORK_GAME_INFO_VERSION = 6; ///< What version of game-info do we use?
static const byte NETWORK_COMPANY_INFO_VERSION = 6; ///< What version of company info is this?
static const byte NETWORK_COORDINATOR_VERSION = 3; ///< What version of game-coordinator-protocol do we use?
diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp
index d3c0491ba..138053b05 100644
--- a/src/network/core/game_info.cpp
+++ b/src/network/core/game_info.cpp
@@ -159,14 +159,15 @@ const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo()
* 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 config The GRF to handle.
+ * @param name The name of the NewGRF, empty when unknown.
*/
-static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
+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, GetString(STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN));
+ AddGRFTextToList(config->name, name.empty() ? GetString(STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN) : name);
config->status = GCS_NOT_FOUND;
} else {
config->filename = f->filename;
@@ -182,7 +183,7 @@ static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
* @param p the packet to write the data to.
* @param info the NetworkGameInfo struct to serialize from.
*/
-void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
+void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names)
{
p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
@@ -194,6 +195,9 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
/* 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)game_info->GetVersion());
@@ -216,7 +220,10 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
/* Send actual GRF Identifications */
for (c = info->grfconfig; c != nullptr; c = c->next) {
- if (!HasBit(c->flags, GCF_STATIC)) SerializeGRFIdentifier(p, &c->ident);
+ if (HasBit(c->flags, GCF_STATIC)) continue;
+
+ SerializeGRFIdentifier(p, &c->ident);
+ if (send_newgrf_names) p->Send_string(c->GetName());
}
}
@@ -232,12 +239,10 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
/* NETWORK_GAME_INFO_VERSION = 1 */
p->Send_string(info->server_name);
p->Send_string(info->server_revision);
- p->Send_uint8 (0); // Used to be server-lang.
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_string(""); // Used to be map-name.
p->Send_uint16(info->map_width);
p->Send_uint16(info->map_height);
p->Send_uint8 (info->landscape);
@@ -254,6 +259,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
static const Date MAX_DATE = 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.
@@ -264,6 +270,11 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
* 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);
@@ -279,9 +290,23 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
for (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;
+
+ default:
+ NOT_REACHED();
+ }
+
GRFConfig *c = new GRFConfig();
- DeserializeGRFIdentifier(p, &c->ident);
- HandleIncomingNetworkGameInfoGRFConfig(c);
+ c->ident = grf.ident;
+ HandleIncomingNetworkGameInfoGRFConfig(c, grf.name);
/* Append GRFConfig to the list */
*dst = c;
@@ -304,7 +329,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
case 1:
info->server_name = p->Recv_string(NETWORK_NAME_LENGTH);
info->server_revision = p->Recv_string(NETWORK_REVISION_LENGTH);
- p->Recv_uint8 (); // Used to contain server-lang.
+ 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 ();
@@ -313,7 +338,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
}
- while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
+ 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 ();
@@ -350,3 +375,14 @@ void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf)
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
index a1719acd7..1d17b6f41 100644
--- a/src/network/core/game_info.h
+++ b/src/network/core/game_info.h
@@ -25,14 +25,27 @@
* 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.
+ *
* 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 * 20 unique identifier for GRF files. Consists of:
- * - one 4 byte variable with the GRF ID
- * - 16 bytes (sent sequentially) for the MD5 checksum
- * of the GRF
+ * 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.
*
* 3+ 4 current game date in days since 1-1-0 (DMY)
* 3+ 4 game introduction date in days since 1-1-0 (DMY)
@@ -43,7 +56,7 @@
*
* 1+ var string with the name of the server
* 1+ var string with the revision of the server
- * 1+ 1 the language run on 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
@@ -51,7 +64,7 @@
* 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+ var string with the name of the map
+ * 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:
@@ -59,6 +72,13 @@
* 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_END ///< The end of the list (period).
+};
+
/**
* The game information that is sent from the server to the client.
*/
@@ -92,6 +112,15 @@ struct NetworkGameInfo : NetworkServerGameInfo {
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.
+};
+
extern NetworkServerGameInfo _network_game_info;
std::string_view GetNetworkRevisionString();
@@ -102,9 +131,10 @@ 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);
-void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info);
+void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names = true);
#endif /* NETWORK_CORE_GAME_INFO_H */
diff --git a/src/network/network_coordinator.cpp b/src/network/network_coordinator.cpp
index bf8e06261..ab0f21050 100644
--- a/src/network/network_coordinator.cpp
+++ b/src/network/network_coordinator.cpp
@@ -410,13 +410,14 @@ void ClientNetworkCoordinatorSocketHandler::Register()
void ClientNetworkCoordinatorSocketHandler::SendServerUpdate()
{
Debug(net, 6, "Sending server update to Game Coordinator");
- this->next_update = std::chrono::steady_clock::now() + NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES;
Packet *p = new Packet(PACKET_COORDINATOR_SERVER_UPDATE, TCP_MTU);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
- SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo());
+ SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo(), this->next_update.time_since_epoch() != std::chrono::nanoseconds::zero());
this->SendPacket(p);
+
+ this->next_update = std::chrono::steady_clock::now() + NETWORK_COORDINATOR_DELAY_BETWEEN_UPDATES;
}
/**