From 24b5033a0650ae1ba9682c6aac1e30c29cda5aec Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 15 Mar 2023 20:59:58 +0100 Subject: [PATCH] Fix #10568: "can savegame be loaded check" failed in dedicated server * If loading fails, it usually returns SL_REINIT which doesn't trigger check * If savegame has NewGRFs, it complains NewGRFs are not allowed in intro game --- src/openttd.cpp | 68 +++++++++++++++++++++++---------------- src/video/dedicated_v.cpp | 11 ------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/openttd.cpp b/src/openttd.cpp index 010b366632..4a7806384a 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -969,37 +969,51 @@ bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileTy _game_mode = newgm; - switch (lf == nullptr ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf)) { - case SL_OK: return true; - - case SL_REINIT: - if (_network_dedicated) { - /* - * We need to reinit a network map... - * We can't simply load the intro game here as that game has many - * special cases which make clients desync immediately. So we fall - * back to just generating a new game with the current settings. - */ - Debug(net, 0, "Loading game failed, so a new (random) game will be started"); - MakeNewGame(false, true); - return false; - } - if (_network_server) { - /* We can't load the intro game as server, so disconnect first. */ - NetworkDisconnect(); - } + SaveOrLoadResult result = (lf == nullptr) ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf); + if (result == SL_OK) return true; + + if (_network_dedicated && ogm == GM_MENU) { + /* + * If we are a dedicated server *and* we just were in the menu, then we + * are loading the first savegame. If that fails, not starting the + * server is a better reaction than starting the server with a newly + * generated map as it is quite likely to be started from a script. + */ + Debug(net, 0, "Loading requested map failed; closing server."); + _exit_game = true; + return false; + } - switch (ogm) { - default: - case GM_MENU: LoadIntroGame(); break; - case GM_EDITOR: MakeNewEditorWorld(); break; - } - return false; + if (result != SL_REINIT) { + _game_mode = ogm; + return false; + } + + if (_network_dedicated) { + /* + * If we are a dedicated server, have already loaded/started a game, + * and then loading the savegame fails in a manner that we need to + * reinitialize everything. We must not fall back into the menu mode + * with the intro game, as that is unjoinable by clients. So there is + * nothing else to do than start a new game, as it might have failed + * trying to reload the originally loaded savegame/scenario. + */ + Debug(net, 0, "Loading game failed, so a new (random) game will be started"); + MakeNewGame(false, true); + return false; + } + + if (_network_server) { + /* We can't load the intro game as server, so disconnect first. */ + NetworkDisconnect(); + } + switch (ogm) { default: - _game_mode = ogm; - return false; + case GM_MENU: LoadIntroGame(); break; + case GM_EDITOR: MakeNewEditorWorld(); break; } + return false; } void SwitchToMode(SwitchMode new_mode) diff --git a/src/video/dedicated_v.cpp b/src/video/dedicated_v.cpp index 259e7f7220..99dc5ee691 100644 --- a/src/video/dedicated_v.cpp +++ b/src/video/dedicated_v.cpp @@ -251,17 +251,6 @@ void VideoDriver_Dedicated::MainLoop() /* If SwitchMode is SM_LOAD_GAME, it means that the user used the '-g' options */ if (_switch_mode != SM_LOAD_GAME) { StartNewGameWithoutGUI(GENERATE_NEW_SEED); - } else { - /* First we need to test if the savegame can be loaded, else we will end up playing the - * intro game... */ - if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, BASE_DIR) == SL_ERROR) { - /* Loading failed, pop out.. */ - Debug(net, 0, "Loading requested map failed; closing server."); - return; - } else { - /* We can load this game, so go ahead */ - _switch_mode = SM_LOAD_GAME; - } } this->is_game_threaded = false;