summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lang/english.txt2
-rw-r--r--src/network/core/core.h1
-rw-r--r--src/network/core/tcp.h2
-rw-r--r--src/network/network.cpp8
-rw-r--r--src/network/network_client.cpp45
-rw-r--r--src/network/network_data.h1
-rw-r--r--src/network/network_server.cpp62
7 files changed, 106 insertions, 15 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt
index edac1dfc8..1167d3c2f 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1419,6 +1419,7 @@ STR_NETWORK_CLIENT_LIST :{WHITE}Client L
STR_NETWORK_ERR_NOTAVAILABLE :{WHITE} No network devices found or compiled without ENABLE_NETWORK
STR_NETWORK_ERR_NOSERVER :{WHITE} Could not find any network games
STR_NETWORK_ERR_NOCONNECTION :{WHITE} The server didn't answer the request
+STR_NETWORK_ERR_NEWGRF_MISMATCH :{WHITE} Could not connect due to NewGRF mismatch
STR_NETWORK_ERR_DESYNC :{WHITE} Network-Game synchronisation failed
STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Network-Game connection lost
STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Could not load savegame
@@ -1440,6 +1441,7 @@ STR_NETWORK_ERR_CLIENT_DESYNC :desync error
STR_NETWORK_ERR_CLIENT_SAVEGAME :could not load map
STR_NETWORK_ERR_CLIENT_CONNECTION_LOST :connection lost
STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR :protocol error
+STR_NETWORK_ERR_CLIENT_NEWGRF_MISMATCH :NewGRF mismatch
STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED :not authorized
STR_NETWORK_ERR_CLIENT_NOT_EXPECTED :received strange packet
STR_NETWORK_ERR_CLIENT_WRONG_REVISION :wrong revision
diff --git a/src/network/core/core.h b/src/network/core/core.h
index 865213471..729145e7f 100644
--- a/src/network/core/core.h
+++ b/src/network/core/core.h
@@ -19,6 +19,7 @@ void NetworkCoreShutdown(void);
typedef enum {
NETWORK_RECV_STATUS_OKAY, ///< Everything is okay
NETWORK_RECV_STATUS_DESYNC, ///< A desync did occur
+ NETWORK_RECV_STATUS_NEWGRF_MISMATCH, ///< We did not have the required NewGRFs
NETWORK_RECV_STATUS_SAVEGAME, ///< Something went wrong (down)loading the savegame
NETWORK_RECV_STATUS_CONN_LOST, ///< The conection is 'just' lost
NETWORK_RECV_STATUS_MALFORMED_PACKET, ///< We apparently send a malformed packet
diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h
index 74e2880e7..232d6f91a 100644
--- a/src/network/core/tcp.h
+++ b/src/network/core/tcp.h
@@ -52,6 +52,8 @@ enum {
PACKET_SERVER_NEWGAME,
PACKET_SERVER_RCON,
PACKET_CLIENT_RCON,
+ PACKET_SERVER_CHECK_NEWGRFS,
+ PACKET_CLIENT_NEWGRFS_CHECKED,
PACKET_END ///< Must ALWAYS be on the end of this list!! (period)
};
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 4ab8d3390..a181f9055 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -250,9 +250,10 @@ static void NetworkClientError(NetworkRecvStatus res, NetworkTCPSocketHandler* c
}
switch (res) {
- case NETWORK_RECV_STATUS_DESYNC: errorno = NETWORK_ERROR_DESYNC; break;
- case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
- default: errorno = NETWORK_ERROR_GENERAL; break;
+ case NETWORK_RECV_STATUS_DESYNC: errorno = NETWORK_ERROR_DESYNC; break;
+ case NETWORK_RECV_STATUS_SAVEGAME: errorno = NETWORK_ERROR_SAVEGAME_FAILED; break;
+ case NETWORK_RECV_STATUS_NEWGRF_MISMATCH: errorno = NETWORK_ERROR_NEWGRF_MISMATCH; break;
+ default: errorno = NETWORK_ERROR_GENERAL; break;
}
// This means we fucked up and the server closed the connection
if (res != NETWORK_RECV_STATUS_SERVER_ERROR && res != NETWORK_RECV_STATUS_SERVER_FULL &&
@@ -282,6 +283,7 @@ char* GetNetworkErrorMsg(char* buf, NetworkErrorCode err, const char* last)
STR_NETWORK_ERR_CLIENT_SAVEGAME,
STR_NETWORK_ERR_CLIENT_CONNECTION_LOST,
STR_NETWORK_ERR_CLIENT_PROTOCOL_ERROR,
+ STR_NETWORK_ERR_CLIENT_NEWGRF_MISMATCH,
STR_NETWORK_ERR_CLIENT_NOT_AUTHORIZED,
STR_NETWORK_ERR_CLIENT_NOT_EXPECTED,
STR_NETWORK_ERR_CLIENT_WRONG_REVISION,
diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp
index 016529889..abc61ff46 100644
--- a/src/network/network_client.cpp
+++ b/src/network/network_client.cpp
@@ -78,6 +78,18 @@ DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_JOIN)
NetworkSend_Packet(p, MY_CLIENT);
}
+DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)
+{
+ //
+ // Packet: CLIENT_NEWGRFS_CHECKED
+ // Function: Tell the server that we have the required GRFs
+ // Data:
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_CLIENT_NEWGRFS_CHECKED);
+ NetworkSend_Packet(p, MY_CLIENT);
+}
+
DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password)
{
//
@@ -408,6 +420,37 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_ERROR)
return NETWORK_RECV_STATUS_SERVER_ERROR;
}
+DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CHECK_NEWGRFS)
+{
+ uint grf_count = NetworkRecv_uint8(MY_CLIENT, p);
+ NetworkRecvStatus ret = NETWORK_RECV_STATUS_OKAY;
+
+ /* Check all GRFs */
+ for (; grf_count > 0; grf_count--) {
+ GRFConfig c;
+ MY_CLIENT->Recv_GRFIdentifier(p, &c);
+
+ /* Check whether we know this GRF */
+ const GRFConfig *f = FindGRFConfig(c.grfid, c.md5sum);
+ if (f == NULL) {
+ /* We do not know this GRF, bail out of initialization */
+ char buf[sizeof(c.md5sum) * 2 + 1];
+ md5sumToString(buf, lastof(buf), c.md5sum);
+ DEBUG(grf, 0, "NewGRF %08X not found; checksum %s", BSWAP32(c.grfid), buf);
+ ret = NETWORK_RECV_STATUS_NEWGRF_MISMATCH;
+ }
+ }
+
+ if (ret == NETWORK_RECV_STATUS_OKAY) {
+ /* Start receiving the map */
+ SEND_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)();
+ } else {
+ /* NewGRF mismatch, bail out */
+ _switch_mode_errorstr = STR_NETWORK_ERR_NEWGRF_MISMATCH;
+ }
+ return ret;
+}
+
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD)
{
NetworkPasswordType type = (NetworkPasswordType)NetworkRecv_uint8(MY_CLIENT, p);
@@ -788,6 +831,8 @@ static NetworkClientPacket* const _network_client_packet[] = {
RECEIVE_COMMAND(PACKET_SERVER_NEWGAME),
RECEIVE_COMMAND(PACKET_SERVER_RCON),
NULL, /*PACKET_CLIENT_RCON,*/
+ RECEIVE_COMMAND(PACKET_SERVER_CHECK_NEWGRFS),
+ NULL, /*PACKET_CLIENT_NEWGRFS_CHECKED,*/
};
// If this fails, check the array above with network_data.h
diff --git a/src/network/network_data.h b/src/network/network_data.h
index 46561c51f..676c9b66c 100644
--- a/src/network/network_data.h
+++ b/src/network/network_data.h
@@ -34,6 +34,7 @@ typedef enum {
NETWORK_ERROR_SAVEGAME_FAILED,
NETWORK_ERROR_CONNECTION_LOST,
NETWORK_ERROR_ILLEGAL_PACKET,
+ NETWORK_ERROR_NEWGRF_MISMATCH,
// Signals from servers
NETWORK_ERROR_NOT_AUTHORIZED,
diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp
index f69340afd..57a530921 100644
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -183,6 +183,32 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkTCPSocketHandler *cs,
NetworkCloseClient(cs);
}
+DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHECK_NEWGRFS)(NetworkTCPSocketHandler *cs)
+{
+ //
+ // Packet: PACKET_SERVER_CHECK_NEWGRFS
+ // Function: Sends info about the used GRFs to the client
+ // Data:
+ // uint8: Amount of GRFs
+ // And then for each GRF:
+ // uint32: GRF ID
+ // 16 * uint8: MD5 checksum of the GRF
+ //
+
+ Packet *p = NetworkSend_Init(PACKET_SERVER_CHECK_NEWGRFS);
+ const GRFConfig *c;
+ uint grf_count = 0;
+
+ for (c = _grfconfig; c != NULL; c = c->next) grf_count++;
+
+ NetworkSend_uint8 (p, grf_count);
+ for (c = _grfconfig; c != NULL; c = c->next) {
+ cs->Send_GRFIdentifier(p, c);
+ }
+
+ NetworkSend_Packet(p, cs);
+}
+
DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkTCPSocketHandler *cs, NetworkPasswordType type)
{
//
@@ -570,6 +596,22 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO)
SEND_COMMAND(PACKET_SERVER_COMPANY_INFO)(cs);
}
+DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)
+{
+ 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) {
+ 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') {
+ SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
+ } else {
+ SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
+ }
+ }
+}
+
DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN)
{
char name[NETWORK_CLIENT_NAME_LENGTH];
@@ -636,20 +678,14 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN)
ci->client_playas = playas;
ci->client_lang = client_lang;
- // We now want a password from the client
- // else we do not allow him in!
- if (_network_game_info.use_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') {
- SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
- } else {
- SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
- }
- }
-
/* Make sure companies to which people try to join are not autocleaned */
if (IsValidPlayer(playas)) _network_player_info[playas].months_empty = 0;
+
+ if (_grfconfig == NULL) {
+ RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED)(cs, NULL);
+ } else {
+ SEND_COMMAND(PACKET_SERVER_CHECK_NEWGRFS)(cs);
+ }
}
DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
@@ -1184,6 +1220,8 @@ static NetworkServerPacket* const _network_server_packet[] = {
NULL, /*PACKET_SERVER_NEWGAME,*/
NULL, /*PACKET_SERVER_RCON,*/
RECEIVE_COMMAND(PACKET_CLIENT_RCON),
+ NULL, /*PACKET_CLIENT_CHECK_NEWGRFS,*/
+ RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED),
};
// If this fails, check the array above with network_data.h