From 41d740177b1c4a6e58be51865d306e19d4a525de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20Lach?= Date: Sun, 6 Feb 2022 13:43:58 +0100 Subject: [PATCH 2/2] - Properly load savegame with counter info Load city counters from savegame in correct order and with sanity checks --- server/savegame/savecompat.h | 6 +++++- server/savegame/savegame3.c | 42 ++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/server/savegame/savecompat.h b/server/savegame/savecompat.h index 7d87ff1640..ff899fb448 100644 --- a/server/savegame/savecompat.h +++ b/server/savegame/savecompat.h @@ -48,7 +48,11 @@ struct loaddata { struct section_file *file; const char *secfile_options; int version; - + /* loaded in sg_load_counters() */ + struct { + const char **order; + size_t size; + } counter; /* loaded in sg_load_savefile(); needed in sg_load_player() */ struct { const char **order; diff --git a/server/savegame/savegame3.c b/server/savegame/savegame3.c index 3d91053bfb..abb032b5c9 100644 --- a/server/savegame/savegame3.c +++ b/server/savegame/savegame3.c @@ -2585,32 +2585,46 @@ static void sg_load_counters (struct loaddata * loading) { struct city *pcity; int i, j; - size_t length; + size_t length, length2; int *city_count; - int city_ccount = secfile_lookup_int_default(loading->file, 0, + length = secfile_lookup_int_default(loading->file, 0, "savefile.city_counters_order_size"); + if (length) { + loading->counter.order = secfile_lookup_str_vec(loading->file, &loading->counter.size, "savefile.city_counters_order_vector"); + + sg_failure_ret(loading->counter.order != 0, + "Failed to load counter's ruleset order: %s", + secfile_error()); + sg_failure_ret(loading->counter.size = length, + "Counter vector in savegame have bad size: %s", + secfile_error()); + } + + int corder[length]; + + for (i = 0; i < length; i++) { + + struct counter *ctg = counter_by_rule_name(loading->counter.order[i]); + corder[i] = counter_index(ctg); + } + i = 0; while (NULL != (city_count = - secfile_lookup_int_vec(loading->file, &length, + secfile_lookup_int_vec(loading->file, &length2, "counters.c%d", i))) { - if (length -1 != (size_t) city_ccount) { - - log_error("Bad city counters vector size. Should be %d. Is %ld.", city_ccount, length - 1); - break; - } + sg_failure_ret((length2 -1 == (size_t) length), ( "Bad city counters vector size. Should be " SIZE_T_PRINTF ". Is " SIZE_T_PRINTF "." ), length, length2 - 1); pcity = game_city_by_number(city_count[0]); - pcity->counter_values = fc_calloc(city_ccount, sizeof(*pcity->counter_values)); - for (j = 0; j < city_ccount; ++j) { + sg_failure_ret(NULL != pcity, "City with id %d not found. Is savegame malformed? Abort loading.", city_count[0]); - pcity->counter_values[j] = city_count[j+1]; - } + for (j = 0; j < length; j++) { - free(city_count); - ++i; + pcity->counter_values[corder[j]] = city_count[j+1]; + } + i++; } } -- 2.35.1