Bug #834 ยป 0021-Drop-dev-save-compat.patch
configure.ac | ||
---|---|---|
[ METAINFODIR=${withval} ], [ METAINFODIR="\$(prefix)/share/metainfo" ])
|
||
AC_SUBST([METAINFODIR])
|
||
dnl try to support this development version's previous save games formats
|
||
AC_ARG_ENABLE([dev-save-compat],
|
||
AS_HELP_STRING([--enable-dev-save-compat=yes/no],
|
||
[enable development version save game compatibility]),
|
||
[case "${enableval}" in
|
||
yes) dev_save_compat=1 ;;
|
||
no) dev_save_compat=0 ;;
|
||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-dev-save-compat]) ;;
|
||
esac],
|
||
[dev_save_compat=$IS_DEVEL_VERSION])
|
||
AS_IF([test $dev_save_compat != 0],
|
||
[AC_DEFINE([FREECIV_DEV_SAVE_COMPAT], [1],
|
||
[Development version save game compatibility])
|
||
AC_DEFINE([FREECIV_DEV_SAVE_COMPAT_3_2], [1],
|
||
[Development version save game compatibility - 3.2 development])])
|
||
AC_ARG_ENABLE([patient-connect],
|
||
AS_HELP_STRING([--enable-patient-connect=yes/no],
|
||
[enable client to be very patient in connecting spawned server]),
|
server/savegame/savecompat.c | ||
---|---|---|
static void compat_post_load_030100(struct loaddata *loading,
|
||
enum sgf_version format_class);
|
||
#ifdef FREECIV_DEV_SAVE_COMPAT
|
||
static void compat_load_dev(struct loaddata *loading);
|
||
static void compat_post_load_dev(struct loaddata *loading);
|
||
#endif /* FREECIV_DEV_SAVE_COMPAT */
|
||
typedef void (*load_version_func_t) (struct loaddata *loading, enum sgf_version format_class);
|
||
struct compatibility {
|
||
... | ... | |
compat[i].load(loading, format_class);
|
||
}
|
||
}
|
||
#ifdef FREECIV_DEV_SAVE_COMPAT
|
||
if (loading->version == compat[compat_current].version) {
|
||
compat_load_dev(loading);
|
||
}
|
||
#endif /* FREECIV_DEV_SAVE_COMPAT */
|
||
}
|
||
/************************************************************************//**
|
||
... | ... | |
compat[i].post_load(loading, format_class);
|
||
}
|
||
}
|
||
#ifdef FREECIV_DEV_SAVE_COMPAT
|
||
if (loading->version == compat[compat_current].version) {
|
||
compat_post_load_dev(loading);
|
||
}
|
||
#endif /* FREECIV_DEV_SAVE_COMPAT */
|
||
}
|
||
/************************************************************************//**
|
||
... | ... | |
}
|
||
}
|
||
/************************************************************************//**
|
||
Translate savegame secfile data from earlier development version format
|
||
to current one.
|
||
****************************************************************************/
|
||
#ifdef FREECIV_DEV_SAVE_COMPAT
|
||
static void compat_load_dev(struct loaddata *loading)
|
||
{
|
||
int game_version;
|
||
/* Check status and return if not OK (sg_success FALSE). */
|
||
sg_check_ret();
|
||
log_debug("Upgrading data between development revisions");
|
||
if (!secfile_lookup_int(loading->file, &game_version, "scenario.game_version")) {
|
||
game_version = 2060000;
|
||
}
|
||
#ifdef FREECIV_DEV_SAVE_COMPAT_3_2
|
||
if (game_version < 3019100) {
|
||
/* Before version number bump to 3.1.91 */
|
||
int i;
|
||
int count;
|
||
/* Older savegames had a bug that got_tech_multi was not saved.
|
||
* Insert the entry to such savegames */
|
||
/* May be unsaved (e.g. scenario case). */
|
||
count = secfile_lookup_int_default(loading->file, 0, "research.count");
|
||
for (i = 0; i < count; i++) {
|
||
if (secfile_entry_lookup(loading->file,
|
||
"research.r%d.got_tech_multi", i) == NULL) {
|
||
/* Default to FALSE */
|
||
secfile_insert_bool(loading->file, FALSE,
|
||
"research.r%d.got_tech_multi", i);
|
||
}
|
||
}
|
||
} /* Version < 3.1.91 */
|
||
if (game_version < 3019200) {
|
||
/* Before version number bump to 3.1.92, August 2022 */
|
||
int set_count;
|
||
bool gamestart_valid = FALSE;
|
||
bool al_set_already = FALSE;
|
||
bool wrap_set_already = FALSE;
|
||
const char *level;
|
||
bool count_changed = FALSE;
|
||
bool topo_defined = FALSE;
|
||
char wrap[100];
|
||
char wrap_gs[100];
|
||
if (secfile_lookup_int(loading->file, &set_count, "settings.set_count")) {
|
||
int i;
|
||
gamestart_valid
|
||
= secfile_lookup_bool_default(loading->file, FALSE,
|
||
"settings.gamestart_valid");
|
||
for (i = 0; i < set_count; i++) {
|
||
const char *old_name
|
||
= secfile_lookup_str(loading->file, "settings.set%d.name", i);
|
||
const char *name;
|
||
if (!old_name) {
|
||
continue;
|
||
}
|
||
name = setcompat_S3_2_name_from_S3_1(old_name);
|
||
if (fc_strcasecmp(old_name, name)) {
|
||
/* Setting's name changed */
|
||
secfile_replace_str(loading->file, name, "settings.set%d.name", i);
|
||
}
|
||
if (!fc_strcasecmp("compresstype", name)) {
|
||
const char *val = secfile_lookup_str(loading->file,
|
||
"settings.set%d.value", i);
|
||
if (!fc_strcasecmp(val, "BZIP2")) {
|
||
#ifdef FREECIV_HAVE_LIBZSTD
|
||
secfile_replace_str(loading->file, "ZSTD",
|
||
"settings.set%d.value", i);
|
||
#elif FREECIV_HAVE_LIBLZMA
|
||
secfile_replace_str(loading->file, "XZ",
|
||
"settings.set%d.value", i);
|
||
#elif FREECIV_HAVE_LIBZ
|
||
secfile_replace_str(loading->file, "LIBZ",
|
||
"settings.set%d.value", i);
|
||
#else
|
||
secfile_replace_str(loading->file, "PLAIN",
|
||
"settings.set%d.value", i);
|
||
#endif
|
||
}
|
||
if (gamestart_valid) {
|
||
val = secfile_lookup_str(loading->file,
|
||
"settings.set%d.gamestart", i);
|
||
if (!fc_strcasecmp(val, "BZIP2")) {
|
||
#ifdef FREECIV_HAVE_LIBZSTD
|
||
secfile_replace_str(loading->file, "ZSTD",
|
||
"settings.set%d.gamestart", i);
|
||
#elif FREECIV_HAVE_LIBLZMA
|
||
secfile_replace_str(loading->file, "XZ",
|
||
"settings.set%d.gamestart", i);
|
||
#elif FREECIV_HAVE_LIBZ
|
||
secfile_replace_str(loading->file, "LIBZ",
|
||
"settings.set%d.gamestart", i);
|
||
#else
|
||
secfile_replace_str(loading->file, "PLAIN",
|
||
"settings.set%d.gamestart", i);
|
||
#endif
|
||
}
|
||
}
|
||
} else if (!fc_strcasecmp("ailevel", name)) {
|
||
al_set_already = TRUE;
|
||
} else if (!fc_strcasecmp("topology", name)) {
|
||
struct setting *pset = setting_by_name(name);
|
||
struct sf_cb_data info = { pset, TRUE };
|
||
int val;
|
||
if (secfile_lookup_enum_data(loading->file, &val, TRUE,
|
||
setting_bitwise_secfile_str, &info,
|
||
"settings.set%d.value", i)) {
|
||
bool topo_changed = TRUE;
|
||
if (val & TF_OLD_WRAPX) {
|
||
if (val & TF_OLD_WRAPY) {
|
||
fc_strlcpy(wrap, "WrapX|WrapY", sizeof(wrap));
|
||
} else {
|
||
fc_strlcpy(wrap, "WrapX", sizeof(wrap));
|
||
}
|
||
} else if (val & TF_OLD_WRAPY) {
|
||
fc_strlcpy(wrap, "WrapY", sizeof(wrap));
|
||
} else {
|
||
fc_strlcpy(wrap, "", sizeof(wrap));
|
||
topo_changed = FALSE;
|
||
}
|
||
if (topo_changed) {
|
||
char buf[100];
|
||
if (val & TF_ISO) {
|
||
if (val & TF_HEX) {
|
||
setting_bitwise_set(pset, "ISO|HEX", NULL, NULL, 0);
|
||
} else {
|
||
setting_bitwise_set(pset, "ISO", NULL, NULL, 0);
|
||
}
|
||
} else if (val & TF_HEX) {
|
||
setting_bitwise_set(pset, "HEX", NULL, NULL, 0);
|
||
} else {
|
||
setting_bitwise_set(pset, "", NULL, NULL, 0);
|
||
}
|
||
setting_value_name(pset, FALSE, buf, sizeof(buf));
|
||
secfile_replace_str(loading->file, buf,
|
||
"settings.set%d.value", i);
|
||
}
|
||
if (gamestart_valid) {
|
||
if (secfile_lookup_enum_data(loading->file, &val, TRUE,
|
||
setting_bitwise_secfile_str, &info,
|
||
"settings.set%d.gamestart", i)) {
|
||
topo_changed = TRUE;
|
||
if (val & TF_OLD_WRAPX) {
|
||
if (val & TF_OLD_WRAPY) {
|
||
fc_strlcpy(wrap_gs, "WrapX|WrapY", sizeof(wrap));
|
||
} else {
|
||
fc_strlcpy(wrap_gs, "WrapX", sizeof(wrap));
|
||
}
|
||
} else if (val & TF_OLD_WRAPY) {
|
||
fc_strlcpy(wrap_gs, "WrapY", sizeof(wrap));
|
||
} else {
|
||
fc_strlcpy(wrap_gs, "", sizeof(wrap));
|
||
topo_changed = FALSE;
|
||
}
|
||
if (topo_changed) {
|
||
char buf[100];
|
||
if (val & TF_ISO) {
|
||
if (val & TF_HEX) {
|
||
setting_bitwise_set(pset, "ISO|HEX", NULL, NULL, 0);
|
||
} else {
|
||
setting_bitwise_set(pset, "ISO", NULL, NULL, 0);
|
||
}
|
||
} else if (val & TF_HEX) {
|
||
setting_bitwise_set(pset, "HEX", NULL, NULL, 0);
|
||
} else {
|
||
setting_bitwise_set(pset, "", NULL, NULL, 0);
|
||
}
|
||
setting_value_name(pset, FALSE, buf, sizeof(buf));
|
||
secfile_replace_str(loading->file, buf,
|
||
"settings.set%d.gamestart", i);
|
||
}
|
||
}
|
||
}
|
||
topo_defined = TRUE;
|
||
}
|
||
} else if (!fc_strcasecmp("wrap", name)) {
|
||
wrap_set_already = TRUE;
|
||
}
|
||
}
|
||
}
|
||
if (!al_set_already) {
|
||
level = secfile_lookup_str_default(loading->file, NULL, "game.level");
|
||
if (level == NULL) {
|
||
/* Assume that this was a new format savegame after all,
|
||
* setting just has not been explicitly saved for containing default value. */
|
||
al_set_already = TRUE;
|
||
}
|
||
}
|
||
if (!al_set_already) {
|
||
/* Turn old AI level field to a setting. */
|
||
enum ai_level lvl;
|
||
if (level != NULL && !fc_strcasecmp("Handicapped", level)) {
|
||
/* Up to freeciv-3.1 Restricted AI level was known as Handicapped */
|
||
lvl = AI_LEVEL_RESTRICTED;
|
||
} else {
|
||
lvl = ai_level_by_name(level, fc_strcasecmp);
|
||
}
|
||
if (!ai_level_is_valid(lvl)) {
|
||
log_sg("Invalid AI level \"%s\". "
|
||
"Changed to \"%s\".", level,
|
||
ai_level_name(GAME_HARDCODED_DEFAULT_SKILL_LEVEL));
|
||
lvl = GAME_HARDCODED_DEFAULT_SKILL_LEVEL;
|
||
}
|
||
secfile_insert_str(loading->file, "ailevel", "settings.set%d.name", set_count);
|
||
secfile_insert_enum(loading->file, lvl, ai_level, "settings.set%d.value", set_count);
|
||
if (gamestart_valid) {
|
||
secfile_insert_enum(loading->file, lvl, ai_level, "settings.set%d.gamestart",
|
||
set_count);
|
||
}
|
||
set_count++;
|
||
count_changed = TRUE;
|
||
}
|
||
if (!wrap_set_already && topo_defined) {
|
||
secfile_insert_str(loading->file, "wrap", "settings.set%d.name", set_count);
|
||
secfile_insert_str(loading->file, wrap, "settings.set%d.value", set_count);
|
||
if (gamestart_valid) {
|
||
secfile_insert_str(loading->file, wrap_gs, "settings.set%d.value", set_count);
|
||
}
|
||
set_count++;
|
||
count_changed = TRUE;
|
||
}
|
||
if (count_changed) {
|
||
secfile_replace_int(loading->file, set_count, "settings.set_count");
|
||
}
|
||
{
|
||
int action_count;
|
||
action_count = secfile_lookup_int_default(loading->file, 0,
|
||
"savefile.action_size");
|
||
if (action_count > 0) {
|
||
const char **modname;
|
||
const char **savemod;
|
||
int j;
|
||
const char *dur_name = "Disband Unit Recover";
|
||
modname = secfile_lookup_str_vec(loading->file, &loading->action.size,
|
||
"savefile.action_vector");
|
||
savemod = fc_calloc(action_count, sizeof(*savemod));
|
||
for (j = 0; j < action_count; j++) {
|
||
if (!fc_strcasecmp("Recycle Unit", modname[j])) {
|
||
savemod[j] = dur_name;
|
||
} else {
|
||
savemod[j] = modname[j];
|
||
}
|
||
}
|
||
secfile_replace_str_vec(loading->file, savemod, action_count,
|
||
"savefile.action_vector");
|
||
free(savemod);
|
||
}
|
||
}
|
||
player_slots_iterate(pslot) {
|
||
int plrno = player_slot_index(pslot);
|
||
int wonder_city = secfile_lookup_int_default(loading->file, -1,
|
||
"player%d.adv.wonder_city",
|
||
plrno);
|
||
if (wonder_city < 0) {
|
||
/* No wonder_city saved with the new name. Check for the old name */
|
||
wonder_city = secfile_lookup_int_default(loading->file, -1,
|
||
"player%d.wonder_city",
|
||
plrno);
|
||
if (wonder_city >= 0) {
|
||
secfile_replace_int(loading->file, wonder_city,
|
||
"player%d.adv.wonder_city", plrno);
|
||
}
|
||
}
|
||
} player_slots_iterate_end;
|
||
} /* Version < 3.1.92 */
|
||
if (game_version < 3019300) {
|
||
/* Before version number bump to 3.1.93 */
|
||
/* Older savegames unnecessarily saved diplstate type order.
|
||
* Silence "unused entry" warnings about those. */
|
||
{
|
||
int dscount = secfile_lookup_int_default(loading->file, 0,
|
||
"savefile.diplstate_type_size");
|
||
int i;
|
||
for (i = 0; i < dscount; i++) {
|
||
(void) secfile_entry_lookup(loading->file,
|
||
"savefile.diplstate_type_vector,%d", i);
|
||
}
|
||
}
|
||
(void) secfile_entry_lookup(loading->file, "game.hardcoded_counters");
|
||
/* Add wl_max_length and orders_max_length entries for players */
|
||
{
|
||
player_slots_iterate(pslot) {
|
||
int plrno = player_slot_index(pslot);
|
||
int ncities, nunits;
|
||
int cnro, unro;
|
||
size_t wlist_max_length = 0;
|
||
size_t olist_max_length = 0;
|
||
if (secfile_section_lookup(loading->file, "player%d", plrno) == NULL) {
|
||
continue;
|
||
}
|
||
ncities = secfile_lookup_int_default(loading->file, 0,
|
||
"player%d.ncities", plrno);
|
||
for (cnro = 0; cnro < ncities; cnro++) {
|
||
int wl_length = secfile_lookup_int_default(loading->file, 0,
|
||
"player%d.c%d.wl_length",
|
||
plrno, cnro);
|
||
wlist_max_length = MAX(wlist_max_length, wl_length);
|
||
if (secfile_entry_lookup(loading->file,
|
||
"player%d.c%d.acquire_t",
|
||
plrno, cnro) == NULL) {
|
||
if (secfile_lookup_int_default(loading->file, plrno,
|
||
"player%d.c%d.original",
|
||
plrno, cnro) != plrno) {
|
||
secfile_insert_int(loading->file, CACQ_CONQUEST,
|
||
"player%d.c%d.acquire_t",
|
||
plrno, cnro);
|
||
} else {
|
||
secfile_insert_int(loading->file, CACQ_FOUNDED,
|
||
"player%d.c%d.acquire_t",
|
||
plrno, cnro);
|
||
}
|
||
}
|
||
if (secfile_entry_lookup(loading->file,
|
||
"player%d.c%d.wlcb",
|
||
plrno, cnro) == NULL) {
|
||
secfile_insert_int(loading->file, WLCB_SMART,
|
||
"player%d.c%d.wlcb",
|
||
plrno, cnro);
|
||
}
|
||
}
|
||
secfile_insert_int(loading->file, wlist_max_length,
|
||
"player%d.wl_max_length", plrno);
|
||
nunits = secfile_lookup_int_default(loading->file, 0,
|
||
"player%d.nunits", plrno);
|
||
for (unro = 0; unro < nunits; unro++) {
|
||
int ol_length
|
||
= secfile_lookup_int_default(loading->file, 0,
|
||
"player%d.u%d.orders_length",
|
||
plrno, unro);
|
||
olist_max_length = MAX(olist_max_length, ol_length);
|
||
}
|
||
secfile_insert_int(loading->file, olist_max_length,
|
||
"player%d.orders_max_length", plrno);
|
||
secfile_insert_int(loading->file, MAX_TRADE_ROUTES_OLD,
|
||
"player%d.routes_max_length", plrno);
|
||
} player_slots_iterate_end;
|
||
}
|
||
/* Replace got_tech[_multi] bools on free_bulbs integers. */
|
||
{
|
||
int count = secfile_lookup_int_default(loading->file, 0, "research.count");
|
||
for (int i = 0; i < count; i++) {
|
||
bool got_tech = FALSE;
|
||
int bulbs = 0;
|
||
bool got_tech_multi
|
||
= secfile_lookup_bool_default(loading->file, FALSE,
|
||
"research.r%d.got_tech_multi", i);
|
||
if (secfile_lookup_bool(loading->file, &got_tech,
|
||
"research.r%d.got_tech", i)
|
||
&& secfile_lookup_int(loading->file, &bulbs,
|
||
"research.r%d.bulbs", i)) {
|
||
secfile_insert_int(loading->file,
|
||
got_tech || got_tech_multi ? bulbs : 0,
|
||
"research.r%d.free_bulbs", i);
|
||
}
|
||
}
|
||
}
|
||
/* Convert 'alltemperate' and 'singlepole' into 'northlatitude' and
|
||
* 'southlatitude' server settings */
|
||
{
|
||
int i;
|
||
int set_count = secfile_lookup_int_default(loading->file, 0,
|
||
"settings.set_count");
|
||
int alltemperate_idx = -1, singlepole_idx = -1;
|
||
for (i = 0; i < set_count; i++) {
|
||
const char *name
|
||
= secfile_lookup_str(loading->file, "settings.set%d.name", i);
|
||
if (!name) {
|
||
continue;
|
||
}
|
||
if (!fc_strcasecmp("northlatitude", name)
|
||
|| !fc_strcasecmp("southlatitude", name)) {
|
||
/* this savegame is recent enough to already have latitude
|
||
* settings ~> no change necessary */
|
||
alltemperate_idx = singlepole_idx = -1;
|
||
break;
|
||
}
|
||
if (!fc_strcasecmp("alltemperate", name)) {
|
||
alltemperate_idx = i;
|
||
} else if (!fc_strcasecmp("singlepole", name)) {
|
||
singlepole_idx = i;
|
||
}
|
||
}
|
||
if (alltemperate_idx >= 0 || singlepole_idx >= 0) {
|
||
int north_latitude, south_latitude;
|
||
int north_idx, south_idx;
|
||
bool alltemperate, singlepole;
|
||
if (alltemperate_idx < 0
|
||
|| !secfile_lookup_bool(loading->file, &alltemperate,
|
||
"settings.set%d.value",
|
||
alltemperate_idx)) {
|
||
/* infer what would've been the ruleset default */
|
||
alltemperate = (wld.map.north_latitude == wld.map.south_latitude);
|
||
}
|
||
if (singlepole_idx < 0
|
||
|| !secfile_lookup_bool(loading->file, &singlepole,
|
||
"settings.set%d.value",
|
||
singlepole_idx)) {
|
||
/* infer what would've been the ruleset default */
|
||
singlepole = (wld.map.south_latitude >= 0);
|
||
}
|
||
/* Note: hard-coding 1000-based latitudes here; if MAX_LATITUDE ever
|
||
* changes, that'll have to be handled in later migrations anyway */
|
||
north_latitude = alltemperate ? 500 : 1000;
|
||
south_latitude = alltemperate ? 500 : (singlepole ? 0 : -1000);
|
||
/* Replace alltemperate with northlatitude, and singlepole with
|
||
* southlatitude. If only one of the two was given, add the other
|
||
* at the end. */
|
||
north_idx = (alltemperate_idx < 0) ? set_count : alltemperate_idx;
|
||
south_idx = (singlepole_idx < 0) ? set_count : singlepole_idx;
|
||
secfile_replace_str(loading->file, "northlatitude",
|
||
"settings.set%d.name", north_idx);
|
||
secfile_replace_int(loading->file, north_latitude,
|
||
"settings.set%d.value", north_idx);
|
||
secfile_replace_str(loading->file, "southlatitude",
|
||
"settings.set%d.name", south_idx);
|
||
secfile_replace_int(loading->file, south_latitude,
|
||
"settings.set%d.value", south_idx);
|
||
if (secfile_lookup_bool_default(loading->file, FALSE,
|
||
"settings.gamestart_valid")) {
|
||
if (alltemperate_idx < 0
|
||
|| !secfile_lookup_bool(loading->file, &alltemperate,
|
||
"settings.set%d.gamestart",
|
||
alltemperate_idx)) {
|
||
alltemperate =
|
||
(wld.map.north_latitude == wld.map.south_latitude);
|
||
}
|
||
if (singlepole_idx < 0
|
||
|| !secfile_lookup_bool(loading->file, &singlepole,
|
||
"settings.set%d.gamestart",
|
||
singlepole_idx)) {
|
||
singlepole = (wld.map.south_latitude >= 0);
|
||
}
|
||
north_latitude = alltemperate ? 500 : 1000;
|
||
south_latitude = alltemperate ? 500 : (singlepole ? 0 : -1000);
|
||
secfile_replace_int(loading->file, north_latitude,
|
||
"settings.set%d.gamestart", north_idx);
|
||
secfile_replace_int(loading->file, south_latitude,
|
||
"settings.set%d.gamestart", south_idx);
|
||
}
|
||
if (alltemperate_idx < 0 || singlepole_idx < 0) {
|
||
/* only one was given and replaced ~> we added one new entry */
|
||
set_count++;
|
||
secfile_replace_int(loading->file, set_count,
|
||
"settings.set_count");
|
||
}
|
||
}
|
||
}
|
||
{
|
||
int action_count;
|
||
action_count = secfile_lookup_int_default(loading->file, 0,
|
||
"savefile.action_size");
|
||
if (action_count > 0) {
|
||
const char **modname;
|
||
const char **savemod;
|
||
int j;
|
||
const char *dur_name = "Transport Deboard";
|
||
modname = secfile_lookup_str_vec(loading->file, &loading->action.size,
|
||
"savefile.action_vector");
|
||
savemod = fc_calloc(action_count, sizeof(*savemod));
|
||
for (j = 0; j < action_count; j++) {
|
||
if (!fc_strcasecmp("Transport Alight", modname[j])) {
|
||
savemod[j] = dur_name;
|
||
} else {
|
||
savemod[j] = modname[j];
|
||
}
|
||
}
|
||
secfile_replace_str_vec(loading->file, savemod, action_count,
|
||
"savefile.action_vector");
|
||
free(savemod);
|
||
}
|
||
}
|
||
{
|
||
const char *str = secfile_lookup_str_default(loading->file, NULL,
|
||
"savefile.orig_version");
|
||
if (str == NULL) {
|
||
/* Make sure CURRENTLY running version does not
|
||
* end as orig_version when we resave. */
|
||
secfile_insert_str(loading->file, "old savegame3, or older",
|
||
"savefile.orig_version");
|
||
}
|
||
}
|
||
} /* Version < 3.1.93 */
|
||
if (game_version < 3019400) {
|
||
/* Before version number bump to 3.1.94, January 2024 */
|
||
{
|
||
int action_count;
|
||
action_count = secfile_lookup_int_default(loading->file, 0,
|
||
"savefile.action_size");
|
||
if (action_count > 0) {
|
||
const char **modname;
|
||
const char **savemod;
|
||
int j;
|
||
const char *clean_name = "Clean";
|
||
modname = secfile_lookup_str_vec(loading->file, &loading->action.size,
|
||
"savefile.action_vector");
|
||
savemod = fc_calloc(action_count, sizeof(*savemod));
|
||
for (j = 0; j < action_count; j++) {
|
||
if (!fc_strcasecmp("Clean Pollution", modname[j])
|
||
|| !fc_strcasecmp("Clean Fallout", modname[j])) {
|
||
savemod[j] = clean_name;
|
||
} else {
|
||
savemod[j] = modname[j];
|
||
}
|
||
}
|
||
secfile_replace_str_vec(loading->file, savemod, action_count,
|
||
"savefile.action_vector");
|
||
free(savemod);
|
||
}
|
||
}
|
||
{
|
||
int activities_count;
|
||
activities_count = secfile_lookup_int_default(loading->file, 0,
|
||
"savefile.activities_size");
|
||
if (activities_count > 0) {
|
||
const char **modname;
|
||
const char **savemod;
|
||
int j;
|
||
const char *clean_name = "Clean";
|
||
modname = secfile_lookup_str_vec(loading->file, &loading->activities.size,
|
||
"savefile.activities_vector");
|
||
savemod = fc_calloc(activities_count, sizeof(*savemod));
|
||
for (j = 0; j < activities_count; j++) {
|
||
if (!fc_strcasecmp("Pollution", modname[j])
|
||
|| !fc_strcasecmp("Fallout", modname[j])) {
|
||
savemod[j] = clean_name;
|
||
} else {
|
||
savemod[j] = modname[j];
|
||
}
|
||
}
|
||
secfile_replace_str_vec(loading->file, savemod, activities_count,
|
||
"savefile.activities_vector");
|
||
free(savemod);
|
||
}
|
||
}
|
||
/* Server setting migration. */
|
||
{
|
||
int set_count;
|
||
if (secfile_lookup_int(loading->file, &set_count, "settings.set_count")) {
|
||
bool gamestart_valid = FALSE;
|
||
gamestart_valid
|
||
= secfile_lookup_bool_default(loading->file, FALSE,
|
||
"settings.gamestart_valid");
|
||
if (!gamestart_valid) {
|
||
int i;
|
||
/* Older savegames saved gamestart values even when they were not valid.
|
||
* Silence warnings caused by them. */
|
||
for (i = 0; i < set_count; i++) {
|
||
(void) secfile_entry_lookup(loading->file, "settings.set%d.gamestart", i);
|
||
(void) secfile_entry_lookup(loading->file, "settings.set%d.gamesetdef", i);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
{
|
||
player_slots_iterate(pslot) {
|
||
int plrno = player_slot_index(pslot);
|
||
bool first_city;
|
||
if (secfile_section_lookup(loading->file, "player%d", plrno) == NULL) {
|
||
continue;
|
||
}
|
||
first_city = secfile_lookup_bool_default(loading->file, FALSE,
|
||
"player%d.got_first_city",
|
||
plrno);
|
||
if (first_city) {
|
||
const char **flag_names = fc_calloc(PLRF_COUNT, sizeof(char *));
|
||
int flagcount = 0;
|
||
const char **flags_sg;
|
||
size_t nval;
|
||
int i;
|
||
flag_names[flagcount++] = plr_flag_id_name(PLRF_FIRST_CITY);
|
||
flags_sg = secfile_lookup_str_vec(loading->file, &nval,
|
||
"player%d.flags", plrno);
|
||
for (i = 0; i < nval; i++) {
|
||
enum plr_flag_id fid = plr_flag_id_by_name(flags_sg[i],
|
||
fc_strcasecmp);
|
||
flag_names[flagcount++] = plr_flag_id_name(fid);
|
||
}
|
||
secfile_replace_str_vec(loading->file, flag_names, flagcount,
|
||
"player%d.flags", plrno);
|
||
free(flag_names);
|
||
}
|
||
} player_slots_iterate_end;
|
||
}
|
||
} /* Version < 3.1.94 */
|
||
if (game_version < 3019500) {
|
||
/* Before version number bump to 3.1.95 */
|
||
} /* Version < 3.1.95 */
|
||
#endif /* FREECIV_DEV_SAVE_COMPAT_3_2 */
|
||
}
|
||
/************************************************************************//**
|
||
Update loaded game data from earlier development version to something
|
||
usable by current Freeciv.
|
||
****************************************************************************/
|
||
static void compat_post_load_dev(struct loaddata *loading)
|
||
{
|
||
int game_version;
|
||
/* Check status and return if not OK (sg_success FALSE). */
|
||
sg_check_ret();
|
||
if (!secfile_lookup_int(loading->file, &game_version, "scenario.game_version")) {
|
||
game_version = 2060000;
|
||
}
|
||
#ifdef FREECIV_DEV_SAVE_COMPAT_3_2
|
||
if (game_version < 3019100) {
|
||
/* Before version number bump to 3.1.91 */
|
||
} /* Version < 3.1.91 */
|
||
#endif /* FREECIV_DEV_SAVE_COMPAT_3_2 */
|
||
}
|
||
#endif /* FREECIV_DEV_SAVE_COMPAT */
|
||
/************************************************************************//**
|
||
Convert old ai level value to ai_level
|
||
****************************************************************************/
|