Changeset - r15386:717f25b0b15f
[Not reviewed]
master
0 1 0
rubidium - 14 years ago 2010-06-30 21:38:51
rubidium@openttd.org
(svn r20039) -Fix [FS#3907]: instead of loading the intro game when loading a savegame fails on the dedicated server, generate a new game.
Generating a new game is the least bad solution:
* loading the intro game: desyncs due to GM_MENU on the server and GM_NORMAL on the clients, NewGRFs not being loaded on the server but being loaded on the client;
* creating an empty map: OpenTTD will go crazy due to missing towns. Also clients can't properly join because of the missing towns;
* loading the last saved game: doesn't always exist and loading it might fail causing an infinite loop;
* stopping being a server: breaks the dedicated server horribly; if you loaded the game via rcon you can't connect with it anymore as you can't join the server;
* generating a new game: should always succeed, although people might think a scenario loaded fine because there are no companies and such.
1 file changed with 14 insertions and 3 deletions:
0 comments (0 inline, 0 general)
src/openttd.cpp
Show inline comments
 
@@ -863,24 +863,36 @@ extern void StartupEconomy();
 
 * @param subdir default directory to look for filename, set to 0 if not needed
 
 */
 
bool SafeSaveOrLoad(const char *filename, int mode, GameMode newgm, Subdirectory subdir)
 
{
 
	GameMode ogm = _game_mode;
 

	
 
	_game_mode = newgm;
 
	assert(mode == SL_LOAD || mode == SL_OLD_LOAD);
 
	switch (SaveOrLoad(filename, mode, subdir)) {
 
		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;
 
			}
 

	
 
			switch (ogm) {
 
				default:
 
				case GM_MENU:   LoadIntroGame();      break;
 
				case GM_EDITOR: MakeNewEditorWorld(); break;
 
			}
 
			return false;
 

	
 
		default:
 
			_game_mode = ogm;
 
			return false;
 
	}
 
}
 
@@ -902,28 +914,28 @@ static void StartScenario()
 
		_game_mode = GM_MENU;
 
		return;
 
	}
 

	
 
	/* Reinitialize windows */
 
	ResetWindowSystem();
 

	
 
	SetupColoursAndInitialWindow();
 

	
 
	ResetGRFConfig(true);
 

	
 
	/* Load game */
 
	if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, SCENARIO_DIR) != SL_OK) {
 
		LoadIntroGame();
 
	if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, SCENARIO_DIR)) {
 
		SetDParamStr(0, GetSaveLoadErrorString());
 
		ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
 
		return;
 
	}
 

	
 
	_settings_game.difficulty = _settings_newgame.difficulty;
 

	
 
	/* Inititalize data */
 
	StartupEconomy();
 
	StartupCompanies();
 
	StartupEngines();
 
	StartupDisasters();
 

	
 
	SetLocalCompany(COMPANY_FIRST);
 
	Company *c = Company::Get(COMPANY_FIRST);
 
@@ -987,25 +999,24 @@ void SwitchToMode(SwitchMode new_mode)
 
			if (_network_server) {
 
				snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded scenario)", _file_to_saveload.title);
 
			}
 
#endif /* ENABLE_NETWORK */
 
			StartScenario();
 
			break;
 

	
 
		case SM_LOAD: { // Load game, Play Scenario
 
			ResetGRFConfig(true);
 
			ResetWindowSystem();
 

	
 
			if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, NO_DIRECTORY)) {
 
				LoadIntroGame();
 
				SetDParamStr(0, GetSaveLoadErrorString());
 
				ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
 
			} else {
 
				if (_saveload_mode == SLD_LOAD_SCENARIO) {
 
					StartupEngines();
 
				}
 
				/* Update the local company for a loaded game. It is either always
 
				 * company #1 (eg 0) or in the case of a dedicated server a spectator */
 
				SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST);
 
				/* Execute the game-start script */
 
				IConsoleCmdExec("exec scripts/game_start.scr 0");
 
				/* Decrease pause counter (was increased from opening load dialog) */
0 comments (0 inline, 0 general)