From d59396ab9f132c61648210907b409b4844f900ab Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Thu, 26 May 2022 00:17:29 +0300 Subject: [PATCH 15/15] Sanity check research->techs_researched from savegame See osdn #44595 Signed-off-by: Marko Lindqvist --- common/research.c | 17 +++++++++++++++++ common/research.h | 2 ++ server/legacysave.c | 10 ++++++++++ server/savegame2.c | 10 ++++++++++ server/savegame3.c | 10 ++++++++++ 5 files changed, 49 insertions(+) diff --git a/common/research.c b/common/research.c index c1be7d11f3..ac06db033c 100644 --- a/common/research.c +++ b/common/research.c @@ -1326,3 +1326,20 @@ struct iterator *research_player_iter_init(struct research_player_iter *it, return base; } + +/**************************************************************************** + Return recalculated number of techs researched. Useful for + sanity checking techs_researched counter. +****************************************************************************/ +int recalculate_techs_researched(const struct research *presearch) +{ + int techs = 1; /* A_NONE known, and not part of below iteration */ + + advance_iterate(A_FIRST, t) { + if (research_invention_state(presearch, advance_number(t)) == TECH_KNOWN) { + techs++; + } + } advance_iterate_end; + + return techs + presearch->future_tech; +} diff --git a/common/research.h b/common/research.h index fbc2cc6d6d..38ebb54bbb 100644 --- a/common/research.h +++ b/common/research.h @@ -171,6 +171,8 @@ struct iterator *research_player_iter_init(struct research_player_iter *it, _presearch) #define research_players_iterate_end generic_iterate_end +int recalculate_techs_researched(const struct research *presearch); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/server/legacysave.c b/server/legacysave.c index 975899fda3..ebcb0382e7 100644 --- a/server/legacysave.c +++ b/server/legacysave.c @@ -4143,6 +4143,8 @@ static void game_load_internal(struct section_file *file) /* In case of tech_leakage, we can update research only after all * the players have been loaded */ researches_iterate(presearch) { + int techs; + /* Mark the reachable techs */ research_update(presearch); @@ -4167,6 +4169,14 @@ static void game_load_internal(struct section_file *file) research_name_translation(presearch)); presearch->tech_goal = A_UNSET; } + + techs = recalculate_techs_researched(presearch); + + if (presearch->techs_researched != techs) { + log_sg(_("%s had finished researches count wrong."), + research_name_translation(presearch)); + presearch->techs_researched = techs; + } } researches_iterate_end; /* The savegame may contain valid nations that are not included in diff --git a/server/savegame2.c b/server/savegame2.c index 2b7e1618cf..13ed0486bd 100644 --- a/server/savegame2.c +++ b/server/savegame2.c @@ -5185,6 +5185,8 @@ static void sg_load_sanitycheck(struct loaddata *loading) /* Check researching technologies and goals. */ researches_iterate(presearch) { + int techs; + if (presearch->researching != A_UNSET && !is_future_tech(presearch->researching) && (valid_advance_by_number(presearch->researching) == NULL @@ -5204,6 +5206,14 @@ static void sg_load_sanitycheck(struct loaddata *loading) research_name_translation(presearch)); presearch->tech_goal = A_UNSET; } + + techs = recalculate_techs_researched(presearch); + + if (presearch->techs_researched != techs) { + log_sg(_("%s had finished researches count wrong."), + research_name_translation(presearch)); + presearch->techs_researched = techs; + } } researches_iterate_end; if (0 == strlen(server.game_identifier) diff --git a/server/savegame3.c b/server/savegame3.c index acf47b77c6..1a638828ce 100644 --- a/server/savegame3.c +++ b/server/savegame3.c @@ -7098,6 +7098,8 @@ static void sg_load_sanitycheck(struct loaddata *loading) /* Check researching technologies and goals. */ researches_iterate(presearch) { + int techs; + if (presearch->researching != A_UNSET && !is_future_tech(presearch->researching) && (valid_advance_by_number(presearch->researching) == NULL @@ -7117,6 +7119,14 @@ static void sg_load_sanitycheck(struct loaddata *loading) research_name_translation(presearch)); presearch->tech_goal = A_UNSET; } + + techs = recalculate_techs_researched(presearch); + + if (presearch->techs_researched != techs) { + log_sg(_("%s had finished researches count wrong."), + research_name_translation(presearch)); + presearch->techs_researched = techs; + } } researches_iterate_end; /* Check if some player has more than one of some UTYF_UNIQUE unit type */ -- 2.35.1