From fcc2938c1ecd3f5d5d4702dae80f73e49820fada Mon Sep 17 00:00:00 2001 From: Sveinung Kvilhaugsvik Date: Mon, 12 Apr 2021 14:17:25 +0200 Subject: [PATCH] Use scenario ruleset as fall back. Some scenarios aren't ruleset locked. They can still require that the ruleset has certain ruleset_caps. The current ruleset may not fulfill that requirement. Fall back to the ruleset specified in the scenario's rulesetdir when that happens. The previous behavior was to both fail to load the scenario and to reset the ruleset. See osdn #41994 --- server/savegame3.c | 58 +++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/server/savegame3.c b/server/savegame3.c index 1ac24edbe9..f16eb97c46 100644 --- a/server/savegame3.c +++ b/server/savegame3.c @@ -1261,6 +1261,7 @@ static void sg_load_savefile(struct loaddata *loading) int i; const char *terr_name; const char *ruleset = NULL; + bool current_ruleset_rejected; /* Check status and return if not OK (sg_success != TRUE). */ sg_check_ret(); @@ -1274,7 +1275,39 @@ static void sg_load_savefile(struct loaddata *loading) (void) secfile_entry_by_path(loading->file, "savefile.reason"); (void) secfile_entry_by_path(loading->file, "savefile.revision"); - if (!game.scenario.is_scenario || game.scenario.ruleset_locked) { + current_ruleset_rejected = FALSE; + if (game.scenario.is_scenario && !game.scenario.ruleset_locked) { + const char *req_caps; + + if (!load_rulesets(NULL, FALSE, NULL, TRUE, FALSE)) { + /* Failed to load correct ruleset */ + sg_failure_ret(FALSE, _("Failed to load ruleset '%s'."), + game.server.rulesetdir); + } + + req_caps = secfile_lookup_str_default(loading->file, "", + "scenario.ruleset_caps"); + strncpy(game.scenario.req_caps, req_caps, + sizeof(game.scenario.req_caps) - 1); + game.scenario.req_caps[sizeof(game.scenario.req_caps) - 1] = '\0'; + + if (!has_capabilities(req_caps, game.ruleset_capabilities)) { + /* Current ruleset lacks required capabilities. */ + log_normal(_("Scenario requires ruleset capabilities: %s"), req_caps); + log_normal(_("Ruleset has capabilities: %s"), + game.ruleset_capabilities); + /* TRANS: ... ruleset dir ... scenario name ... */ + log_error(_("Current ruleset %s not compatible with the scenario %s." + " Trying to switch to the ruleset specified by the" + " scenario."), + game.server.rulesetdir, game.scenario.name); + + current_ruleset_rejected = TRUE; + } + } + + if (!game.scenario.is_scenario || game.scenario.ruleset_locked + || current_ruleset_rejected) { ruleset = secfile_lookup_str_default(loading->file, GAME_DEFAULT_RULESETDIR, "savefile.rulesetdir"); @@ -1303,28 +1336,15 @@ static void sg_load_savefile(struct loaddata *loading) } } + if (current_ruleset_rejected) { + /* TRANS: ruleset dir */ + log_normal(_("Successfully loaded the scenario's ruleset %s."), ruleset); + } + /* Remove all aifill players. Correct number of them get created later * with correct skill level etc. */ (void) aifill(0); - if (game.scenario.is_scenario && !game.scenario.ruleset_locked) { - const char *req_caps; - - req_caps = secfile_lookup_str_default(loading->file, "", - "scenario.ruleset_caps"); - strncpy(game.scenario.req_caps, req_caps, sizeof(game.scenario.req_caps) - 1); - game.scenario.req_caps[sizeof(game.scenario.req_caps) - 1] = '\0'; - - if (!has_capabilities(req_caps, game.ruleset_capabilities)) { - /* Current ruleset lacks required capabilities. */ - log_normal(_("Scenario requires ruleset capabilities: %s"), req_caps); - log_normal(_("Ruleset has capabilities: %s"), game.ruleset_capabilities); - log_error(_("Current ruleset not compatible with the scenario.")); - sg_success = FALSE; - return; - } - } - /* This is in the savegame only if the game has been started before savegame3.c time, * and in that case it's TRUE. If it's missing, it's to be considered FALSE. */ game.server.last_updated_year = secfile_lookup_bool_default(loading->file, FALSE, -- 2.30.2