From e6d0756c2827550205cf03a105217ec9a5865c16 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Thu, 5 Jan 2023 05:25:20 +0200 Subject: [PATCH 33/33] Sanity check diplstate max_state See osdn #44732 Signed-off-by: Marko Lindqvist --- server/diplhand.c | 15 +++++++++++++++ server/diplhand.h | 4 ++++ server/sanitycheck.c | 2 ++ server/savegame/savegame2.c | 7 +++++++ server/savegame/savegame3.c | 9 ++++++++- 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/server/diplhand.c b/server/diplhand.c index 1bdd560f56..a194678964 100644 --- a/server/diplhand.c +++ b/server/diplhand.c @@ -104,6 +104,21 @@ static enum diplstate_type dst_closest(enum diplstate_type a, } } +/**********************************************************************//** + Return closest diplstate dst has had, with extra sanity checking + (i.e. may return state other than the recorder max_state) +**************************************************************************/ +enum diplstate_type valid_dst_closest(struct player_diplstate *dst) +{ + if (dst_closest(dst->type, dst->max_state) == dst->max_state) { + /* Sane max_state */ + return dst->max_state; + } + + /* max_state illegally lower than current. Return current as max_state */ + return dst->type; +} + /**********************************************************************//** Set diplstate between two players. **************************************************************************/ diff --git a/server/diplhand.h b/server/diplhand.h index 21bfa8e55d..2876df9b2b 100644 --- a/server/diplhand.h +++ b/server/diplhand.h @@ -13,8 +13,10 @@ #ifndef FC__DIPLHAND_H #define FC__DIPLHAND_H +/* common */ #include "fc_types.h" +/* server */ #include "hand_gen.h" struct Treaty; @@ -31,4 +33,6 @@ void set_diplstate_type(struct player_diplstate *state1, struct player_diplstate *state2, enum diplstate_type type); +enum diplstate_type valid_dst_closest(struct player_diplstate *dst); + #endif /* FC__DIPLHAND_H */ diff --git a/server/sanitycheck.c b/server/sanitycheck.c index 11c88a8b24..66e561edad 100644 --- a/server/sanitycheck.c +++ b/server/sanitycheck.c @@ -36,6 +36,7 @@ /* server */ #include "citytools.h" #include "cityturn.h" /* city_repair_size() */ +#include "diplhand.h" /* valid_dst_closest() */ #include "maphand.h" #include "plrhand.h" #include "srv_main.h" @@ -543,6 +544,7 @@ static void check_players(const char *file, const char *function, int line) state2 = player_diplstate_get(pplayer2, pplayer); SANITY_CHECK(state1->type == state2->type); SANITY_CHECK(state1->max_state == state2->max_state); + SANITY_CHECK(valid_dst_closest(state1) == state1->max_state); if (state1->type == DS_CEASEFIRE || state1->type == DS_ARMISTICE) { SANITY_CHECK(state1->turns_left == state2->turns_left); diff --git a/server/savegame/savegame2.c b/server/savegame/savegame2.c index 0581c750ed..e9e02122e9 100644 --- a/server/savegame/savegame2.c +++ b/server/savegame/savegame2.c @@ -2953,6 +2953,13 @@ static void sg_load_player_main(struct loaddata *loading, } #endif + if (valid_dst_closest(ds) != ds->max_state) { + sg_regr(03020000, + "Player%d: closest diplstate to player %d less than current. " + "Updated.", plrno, i); + ds->max_state = ds->type; + } + ds->first_contact_turn = secfile_lookup_int_default(loading->file, 0, "%s.first_contact_turn", buf); diff --git a/server/savegame/savegame3.c b/server/savegame/savegame3.c index 0b22efe58f..7e79a2ca02 100644 --- a/server/savegame/savegame3.c +++ b/server/savegame/savegame3.c @@ -4090,7 +4090,7 @@ static void sg_load_player_main(struct loaddata *loading, struct player_diplstate *ds = player_diplstate_get(plr, pplayer); i = player_index(pplayer); - /* load diplomatic status */ + /* Load diplomatic status */ fc_snprintf(buf, sizeof(buf), "player%d.diplstate%d", plrno, i); ds->type = @@ -4110,6 +4110,13 @@ static void sg_load_player_main(struct loaddata *loading, } #endif + if (valid_dst_closest(ds) != ds->max_state) { + sg_regr(03020000, + "Player%d: closest diplstate to player %d less than current. " + "Updated.", plrno, i); + ds->max_state = ds->type; + } + ds->first_contact_turn = secfile_lookup_int_default(loading->file, 0, "%s.first_contact_turn", buf); -- 2.39.0