From 05394d5216f89c9a7e14487b571515e510828657 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Sat, 1 May 2021 14:41:25 +0200 Subject: Fix #6598: Prevent invalid memory accesses when abandoning a join from within a network game One could join a network game from within an already running network game. This would call a NetworkDisconnect, but keeps the UI alive. If, during that process the join is aborted, e.g. by cancelling on a password dialog, you would still be in your network game but also get shown the server list. Solve all the underlying problems by falling back to the main UI when (re)connecting to a(nother) server. --- src/network/network.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'src/network/network.cpp') diff --git a/src/network/network.cpp b/src/network/network.cpp index 32fc4dec9..ce79f4c51 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -760,20 +760,40 @@ bool NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const if (!_network_available) return false; if (!NetworkValidateClientName()) return false; - strecpy(_settings_client.network.last_joined, address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined)); - + _network_join.address = address; _network_join.company = join_as; _network_join.server_password = join_server_password; _network_join.company_password = join_company_password; + if (_game_mode == GM_MENU) { + /* From the menu we can immediately continue with the actual join. */ + NetworkClientJoinGame(); + } else { + /* When already playing a game, first go back to the main menu. This + * disconnects the user from the current game, meaning we can safely + * load in the new. After all, there is little point in continueing to + * play on a server if we are connecting to another one. + */ + _switch_mode = SM_JOIN_GAME; + } + return true; +} + +/** + * Actually perform the joining to the server. Use #NetworkClientConnectGame + * when you want to connect to a specific server/company. This function + * assumes _network_join is already fully set up. + */ +void NetworkClientJoinGame() +{ NetworkDisconnect(); NetworkInitialize(); + strecpy(_settings_client.network.last_joined, _network_join.address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined)); _network_join_status = NETWORK_JOIN_STATUS_CONNECTING; ShowJoinStatusWindow(); - new TCPClientConnecter(address); - return true; + new TCPClientConnecter(_network_join.address); } static void NetworkInitGameInfo() -- cgit v1.2.3-70-g09d2