mirror of https://github.com/OpenTTD/OpenTTD
Feature: [Game Coordinator] Send NewGRF names to the client
parent
3eaa470632
commit
386ef4dac3
|
@ -49,7 +49,7 @@ static const uint16 COMPAT_MTU = 1460; ///< Numbe
|
||||||
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
|
static const byte NETWORK_GAME_ADMIN_VERSION = 1; ///< What version of the admin network do we use?
|
||||||
static const byte NETWORK_GAME_INFO_VERSION = 6; ///< 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_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?
|
static const byte NETWORK_COORDINATOR_VERSION = 4; ///< What version of game-coordinator-protocol do we use?
|
||||||
|
|
||||||
static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0'
|
static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0'
|
||||||
static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0'
|
static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0'
|
||||||
|
|
|
@ -254,7 +254,7 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool
|
||||||
* @param p the packet to read the data from.
|
* @param p the packet to read the data from.
|
||||||
* @param info the NetworkGameInfo to deserialize into.
|
* @param info the NetworkGameInfo to deserialize into.
|
||||||
*/
|
*/
|
||||||
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
|
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table)
|
||||||
{
|
{
|
||||||
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
|
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
|
||||||
|
|
||||||
|
@ -300,6 +300,14 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
|
||||||
DeserializeGRFIdentifierWithName(p, &grf);
|
DeserializeGRFIdentifierWithName(p, &grf);
|
||||||
break;
|
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:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "../../newgrf_config.h"
|
#include "../../newgrf_config.h"
|
||||||
#include "../../date_type.h"
|
#include "../../date_type.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NetworkGameInfo has several revisions which we still need to support on the
|
* 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
|
* wire. The table below shows the version and size for each field of the
|
||||||
|
@ -32,6 +34,9 @@
|
||||||
* 1 = NewGRF ID, MD5 checksum and name.
|
* 1 = NewGRF ID, MD5 checksum and name.
|
||||||
* Used for direct requests and the first game
|
* Used for direct requests and the first game
|
||||||
* update to Game Coordinator.
|
* 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+ 4 version number of the Game Script (-1 is case none is selected).
|
||||||
* 5+ var string with the name of the Game Script.
|
* 5+ var string with the name of the Game Script.
|
||||||
|
@ -46,6 +51,8 @@
|
||||||
* For v4, v5, and v6+ in case of type 0 and/or type 1.
|
* For v4, v5, and v6+ in case of type 0 and/or type 1.
|
||||||
* - string with name of NewGRF.
|
* - string with name of NewGRF.
|
||||||
* For v6+ in case of type 1.
|
* 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 current game date in days since 1-1-0 (DMY)
|
||||||
* 3+ 4 game introduction date in days since 1-1-0 (DMY)
|
* 3+ 4 game introduction date in days since 1-1-0 (DMY)
|
||||||
|
@ -76,6 +83,7 @@
|
||||||
enum NewGRFSerializationType {
|
enum NewGRFSerializationType {
|
||||||
NST_GRFID_MD5 = 0, ///< Unique GRF ID and MD5 checksum.
|
NST_GRFID_MD5 = 0, ///< Unique GRF ID and MD5 checksum.
|
||||||
NST_GRFID_MD5_NAME = 1, ///< Unique GRF ID, MD5 checksum and name.
|
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).
|
NST_END ///< The end of the list (period).
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,6 +128,8 @@ struct NamedGRFIdentifier {
|
||||||
GRFIdentifier ident; ///< The unique identifier of the NewGRF.
|
GRFIdentifier ident; ///< The unique identifier of the NewGRF.
|
||||||
std::string name; ///< The name 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<uint32, NamedGRFIdentifier> GameInfoNewGRFLookupTable;
|
||||||
|
|
||||||
extern NetworkServerGameInfo _network_game_info;
|
extern NetworkServerGameInfo _network_game_info;
|
||||||
|
|
||||||
|
@ -134,7 +144,7 @@ void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf);
|
||||||
void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf);
|
void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf);
|
||||||
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf);
|
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf);
|
||||||
|
|
||||||
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info);
|
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table = nullptr);
|
||||||
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names = true);
|
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names = true);
|
||||||
|
|
||||||
#endif /* NETWORK_CORE_GAME_INFO_H */
|
#endif /* NETWORK_CORE_GAME_INFO_H */
|
||||||
|
|
|
@ -42,6 +42,7 @@ bool NetworkCoordinatorSocketHandler::HandlePacket(Packet *p)
|
||||||
case PACKET_COORDINATOR_GC_STUN_REQUEST: return this->Receive_GC_STUN_REQUEST(p);
|
case PACKET_COORDINATOR_GC_STUN_REQUEST: return this->Receive_GC_STUN_REQUEST(p);
|
||||||
case PACKET_COORDINATOR_SERCLI_STUN_RESULT: return this->Receive_SERCLI_STUN_RESULT(p);
|
case PACKET_COORDINATOR_SERCLI_STUN_RESULT: return this->Receive_SERCLI_STUN_RESULT(p);
|
||||||
case PACKET_COORDINATOR_GC_STUN_CONNECT: return this->Receive_GC_STUN_CONNECT(p);
|
case PACKET_COORDINATOR_GC_STUN_CONNECT: return this->Receive_GC_STUN_CONNECT(p);
|
||||||
|
case PACKET_COORDINATOR_GC_NEWGRF_LOOKUP: return this->Receive_GC_NEWGRF_LOOKUP(p);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Debug(net, 0, "[tcp/coordinator] Received invalid packet type {}", type);
|
Debug(net, 0, "[tcp/coordinator] Received invalid packet type {}", type);
|
||||||
|
@ -100,3 +101,4 @@ bool NetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT(Packet *p) { ret
|
||||||
bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_STUN_REQUEST); }
|
bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_REQUEST(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_STUN_REQUEST); }
|
||||||
bool NetworkCoordinatorSocketHandler::Receive_SERCLI_STUN_RESULT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERCLI_STUN_RESULT); }
|
bool NetworkCoordinatorSocketHandler::Receive_SERCLI_STUN_RESULT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_SERCLI_STUN_RESULT); }
|
||||||
bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_STUN_CONNECT); }
|
bool NetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_STUN_CONNECT); }
|
||||||
|
bool NetworkCoordinatorSocketHandler::Receive_GC_NEWGRF_LOOKUP(Packet *p) { return this->ReceiveInvalidPacket(PACKET_COORDINATOR_GC_NEWGRF_LOOKUP); }
|
||||||
|
|
|
@ -41,6 +41,7 @@ enum PacketCoordinatorType {
|
||||||
PACKET_COORDINATOR_GC_STUN_REQUEST, ///< Game Coordinator tells client/server to initiate a STUN request.
|
PACKET_COORDINATOR_GC_STUN_REQUEST, ///< Game Coordinator tells client/server to initiate a STUN request.
|
||||||
PACKET_COORDINATOR_SERCLI_STUN_RESULT, ///< Client/server informs the Game Coordinator of the result of the STUN request.
|
PACKET_COORDINATOR_SERCLI_STUN_RESULT, ///< Client/server informs the Game Coordinator of the result of the STUN request.
|
||||||
PACKET_COORDINATOR_GC_STUN_CONNECT, ///< Game Coordinator tells client/server to connect() reusing the STUN local address.
|
PACKET_COORDINATOR_GC_STUN_CONNECT, ///< Game Coordinator tells client/server to connect() reusing the STUN local address.
|
||||||
|
PACKET_COORDINATOR_GC_NEWGRF_LOOKUP, ///< Game Coordinator informs client about NewGRF lookup table updates needed for GC_LISTING.
|
||||||
PACKET_COORDINATOR_END, ///< Must ALWAYS be on the end of this list!! (period)
|
PACKET_COORDINATOR_END, ///< Must ALWAYS be on the end of this list!! (period)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,6 +126,7 @@ protected:
|
||||||
* uint8 Game Coordinator protocol version.
|
* uint8 Game Coordinator protocol version.
|
||||||
* uint8 Game-info version used by this client.
|
* uint8 Game-info version used by this client.
|
||||||
* string Revision of the client.
|
* string Revision of the client.
|
||||||
|
* uint32 (Game Coordinator protocol >= 4) Cursor as received from GC_NEWGRF_LOOKUP, or zero.
|
||||||
*
|
*
|
||||||
* @param p The packet that was just received.
|
* @param p The packet that was just received.
|
||||||
* @return True upon success, otherwise false.
|
* @return True upon success, otherwise false.
|
||||||
|
@ -263,6 +265,29 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual bool Receive_GC_STUN_CONNECT(Packet *p);
|
virtual bool Receive_GC_STUN_CONNECT(Packet *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game Coordinator informs the client of updates for the NewGRFs lookup table
|
||||||
|
* as used by the NewGRF deserialization in GC_LISTING.
|
||||||
|
* This packet is sent after a CLIENT_LISTING request, but before GC_LISTING.
|
||||||
|
*
|
||||||
|
* uint32 Lookup table cursor.
|
||||||
|
* uint16 Number of NewGRFs in the packet, with for each of the NewGRFs:
|
||||||
|
* uint32 Lookup table index for the NewGRF.
|
||||||
|
* uint32 Unique NewGRF ID.
|
||||||
|
* byte[16] MD5 checksum of the NewGRF
|
||||||
|
* string Name of the NewGRF.
|
||||||
|
*
|
||||||
|
* The lookup table built using these packets are used by the deserialisation
|
||||||
|
* of the NewGRFs for servers in the GC_LISTING. These updates are additive,
|
||||||
|
* i.e. each update will add NewGRFs but never remove them. However, this
|
||||||
|
* lookup table is specific to the connection with the Game Coordinator, and
|
||||||
|
* should be considered invalid after disconnecting from the Game Coordinator.
|
||||||
|
*
|
||||||
|
* @param p The packet that was just received.
|
||||||
|
* @return True upon success, otherwise false.
|
||||||
|
*/
|
||||||
|
virtual bool Receive_GC_NEWGRF_LOOKUP(Packet *p);
|
||||||
|
|
||||||
bool HandlePacket(Packet *p);
|
bool HandlePacket(Packet *p);
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -231,7 +231,7 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_LISTING(Packet *p)
|
||||||
|
|
||||||
/* Read the NetworkGameInfo from the packet. */
|
/* Read the NetworkGameInfo from the packet. */
|
||||||
NetworkGameInfo ngi = {};
|
NetworkGameInfo ngi = {};
|
||||||
DeserializeNetworkGameInfo(p, &ngi);
|
DeserializeNetworkGameInfo(p, &ngi, &this->newgrf_lookup_table);
|
||||||
|
|
||||||
/* Now we know the connection string, we can add it to our list. */
|
/* Now we know the connection string, we can add it to our list. */
|
||||||
NetworkGameList *item = NetworkGameListAddItem(connection_string);
|
NetworkGameList *item = NetworkGameListAddItem(connection_string);
|
||||||
|
@ -347,6 +347,18 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet *p)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_NEWGRF_LOOKUP(Packet *p)
|
||||||
|
{
|
||||||
|
this->newgrf_lookup_table_cursor = p->Recv_uint32();
|
||||||
|
|
||||||
|
uint16 newgrfs = p->Recv_uint16();
|
||||||
|
for (; newgrfs> 0; newgrfs--) {
|
||||||
|
uint32 index = p->Recv_uint32();
|
||||||
|
DeserializeGRFIdentifierWithName(p, &this->newgrf_lookup_table[index]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ClientNetworkCoordinatorSocketHandler::Connect()
|
void ClientNetworkCoordinatorSocketHandler::Connect()
|
||||||
{
|
{
|
||||||
/* We are either already connected or are trying to connect. */
|
/* We are either already connected or are trying to connect. */
|
||||||
|
@ -433,6 +445,7 @@ void ClientNetworkCoordinatorSocketHandler::GetListing()
|
||||||
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
|
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
|
||||||
p->Send_uint8(NETWORK_GAME_INFO_VERSION);
|
p->Send_uint8(NETWORK_GAME_INFO_VERSION);
|
||||||
p->Send_string(_openttd_revision);
|
p->Send_string(_openttd_revision);
|
||||||
|
p->Send_uint32(this->newgrf_lookup_table_cursor);
|
||||||
|
|
||||||
this->SendPacket(p);
|
this->SendPacket(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,9 @@ private:
|
||||||
std::map<std::string, std::map<int, std::unique_ptr<ClientNetworkStunSocketHandler>>> stun_handlers; ///< All pending STUN handlers, stored by token:family.
|
std::map<std::string, std::map<int, std::unique_ptr<ClientNetworkStunSocketHandler>>> stun_handlers; ///< All pending STUN handlers, stored by token:family.
|
||||||
TCPConnecter *game_connecter = nullptr; ///< Pending connecter to the game server.
|
TCPConnecter *game_connecter = nullptr; ///< Pending connecter to the game server.
|
||||||
|
|
||||||
|
uint32 newgrf_lookup_table_cursor = 0; ///< Last received cursor for the #GameInfoNewGRFLookupTable updates.
|
||||||
|
GameInfoNewGRFLookupTable newgrf_lookup_table; ///< Table to look up NewGRFs in the GC_LISTING packets.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Receive_GC_ERROR(Packet *p) override;
|
bool Receive_GC_ERROR(Packet *p) override;
|
||||||
bool Receive_GC_REGISTER_ACK(Packet *p) override;
|
bool Receive_GC_REGISTER_ACK(Packet *p) override;
|
||||||
|
@ -63,6 +66,7 @@ protected:
|
||||||
bool Receive_GC_DIRECT_CONNECT(Packet *p) override;
|
bool Receive_GC_DIRECT_CONNECT(Packet *p) override;
|
||||||
bool Receive_GC_STUN_REQUEST(Packet *p) override;
|
bool Receive_GC_STUN_REQUEST(Packet *p) override;
|
||||||
bool Receive_GC_STUN_CONNECT(Packet *p) override;
|
bool Receive_GC_STUN_CONNECT(Packet *p) override;
|
||||||
|
bool Receive_GC_NEWGRF_LOOKUP(Packet *p) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** The idle timeout; when to close the connection because it's idle. */
|
/** The idle timeout; when to close the connection because it's idle. */
|
||||||
|
|
Loading…
Reference in New Issue