From 2884abcbfed4baa32a85c02d86a41b02a55b7f61 Mon Sep 17 00:00:00 2001 From: Pavel Stupnikov Date: Tue, 11 Apr 2017 23:35:36 +0300 Subject: [PATCH] Add a trick to join servers with different version of the game --- src/lang/english.txt | 3 +++ src/network/network_client.cpp | 27 +++++++++++++++++++++++++-- src/network/network_client.h | 1 + src/network/network_gui.cpp | 14 +++++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 4267d4e697..d0f81b4453 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5324,3 +5324,6 @@ STR_STATION_RATING_TOOLTIP_WAITUNITS_5 :{GREEN}{NUM}, + STR_STATION_RATING_TOOLTIP_STATUE :Statue in town (max 10%): {STRING} STR_STATION_RATING_TOOLTIP_STATUE_NO :{GOLD}no, 0% STR_STATION_RATING_TOOLTIP_STATUE_YES :{GREEN}yes, +10% + +STR_IGNORE_VERSION_CHECK_WARNING : WARNING! You're about to join server running a different version of the game! +STR_IGNORE_VERSION_CHECK_WARNING_DETAILS : OpenTTD was never indended to work in such way. If you're lucky you may be able to play it but most likely something is going to break sooner or later. Desyncs or crashes are to be expected. So proceed at your own risk and don't report any errors you encounter there. diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 55fa75ef36..bf2ad2d0ad 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -41,6 +41,12 @@ /* This file handles all the client-commands */ void SyncCMUser(const char *msg); +static const std::map OPENTTD_NEWGRF_VERSIONS = { + {"1.7.0", 386428096}, + {"1.7.0-RC1", 385903751}, + {"1.6.1", 370699225}, + {"1.6.0", 369650572}, +}; /** Read some packets, and when do use that data as initial load filter. */ struct PacketReader : LoadFilter { @@ -308,6 +314,8 @@ CompanyID _network_join_as; const char *_network_join_server_password = NULL; /** Company password from -P argument */ const char *_network_join_company_password = NULL; +/** Server revision to use when fooling revision check */ +const char *_network_join_server_revision = NULL; /** Make sure the server ID length is the same as a md5 hash. */ assert_compile(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1); @@ -337,8 +345,23 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin() SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); Packet *p = new Packet(PACKET_CLIENT_JOIN); - p->Send_string(_openttd_revision); - p->Send_uint32(_openttd_newgrf_version); + if (_network_join_server_revision) { + auto r = _network_join_server_revision; + p->Send_string(r); + auto nr = OPENTTD_NEWGRF_VERSIONS.find(r); + int rev; + if (nr != OPENTTD_NEWGRF_VERSIONS.end()) { + p->Send_uint32(nr->second); + } else if (r[0] == 'r' && r[6] == 0 && (rev = atoi(r + 1)) > 0) { + // assume it's nightly + p->Send_uint32((rev >= 27840 ? 402653184u : 385875968u) | rev); + } else { + p->Send_uint32(_openttd_newgrf_version); + } + } else { + p->Send_string(_openttd_revision); + p->Send_uint32(_openttd_newgrf_version); + } p->Send_string(_settings_client.network.client_name); // Client name p->Send_uint8 (_network_join_as); // PlayAs p->Send_uint8 (NETLANG_ANY); // Language diff --git a/src/network/network_client.h b/src/network/network_client.h index b184f21dab..06db7ea454 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -117,6 +117,7 @@ extern CompanyID _network_join_as; extern const char *_network_join_server_password; extern const char *_network_join_company_password; +extern const char *_network_join_server_revision; #endif /* ENABLE_NETWORK */ diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index bfb564ed04..ad356c784b 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -14,6 +14,7 @@ #include "../strings_func.h" #include "../date_func.h" #include "../fios.h" +#include "../error.h" #include "network_client.h" #include "network_gui.h" #include "network_gamelist.h" @@ -613,7 +614,7 @@ public: this->SetWidgetDisabledState(WID_NG_JOIN, sel == NULL || // no Selected Server !sel->online || // Server offline sel->info.clients_on >= sel->info.clients_max || // Server full - !sel->info.compatible); // Revision mismatch + (!sel->info.compatible && !_ctrl_pressed)); // Revision mismatch /* 'NewGRF Settings' button invisible if no NewGRF is used */ this->GetWidget(WID_NG_NEWGRF_SEL)->SetDisplayedPlane(sel == NULL || !sel->online || sel->info.grfconfig == NULL); @@ -772,6 +773,17 @@ public: if (this->server != NULL) { seprintf(_settings_client.network.last_host, lastof(_settings_client.network.last_host), "%s", this->server->address.GetHostname()); _settings_client.network.last_port = this->server->address.GetPort(); + if (this->server->info.compatible) { + _network_join_server_revision = NULL; + } else { + _network_join_server_revision = this->server->info.server_revision; + ShowErrorMessage(STR_IGNORE_VERSION_CHECK_WARNING, + STR_IGNORE_VERSION_CHECK_WARNING_DETAILS, + WL_WARNING, + 0, 0, + NULL, 0, NULL); + // ShowGoalQuestion(0, 2 /* WARNING */, 2 /* OK */, "Full-tile autoroad tool is deprecated and will be removed in next release.\n Use regular autoroad tool instead."); + } ShowNetworkLobbyWindow(this->server); } break;