From f858df652325e733e363b87d1ad2fccf22aa9fe3 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 5 Aug 2020 10:12:51 +0200 Subject: [PATCH] [MIRROR] [Ready] Robust savefile versioning (#201) * Robust savefile versioning (#52549) tl;dr: savefiles now update all character slots when the version is bumped, and saves the updated savefile to disk. It also backups the pre-update version. Later on we can look at just using this backed up version if the server's savefile version goes down, indicating a revert. * [Ready] Robust savefile versioning Co-authored-by: Kyle Spier-Swenson --- code/modules/client/preferences_savefile.dm | 37 ++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 9984fd0b366..1895c45b81a 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -91,6 +91,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car var/needs_update = savefile_needs_update(S) if(needs_update == -2) //fatal, can't load any data + var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup + if (fexists(bacpath)) + fdel(bacpath) //only keep 1 version of backup + fcopy(S, bacpath) //byond helpfully lets you use a savefile for the first arg. return FALSE //general preferences @@ -144,7 +148,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //try to fix any outdated data if necessary if(needs_update >= 0) + var/bacpath = "[path].updatebac" //todo: if the savefile version is higher then the server, check the backup, and give the player a prompt to load the backup + if (fexists(bacpath)) + fdel(bacpath) //only keep 1 version of backup + fcopy(S, bacpath) //byond helpfully lets you use a savefile for the first arg. update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer) + + //Sanitize asaycolor = sanitize_ooccolor(sanitize_hexcolor(asaycolor, 6, 1, initial(asaycolor))) @@ -178,7 +188,24 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style)) pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color)) key_bindings = sanitize_keybindings(key_bindings) - + + if(needs_update >= 0) //save the updated version + var/old_default_slot = default_slot + var/old_max_save_slots = max_save_slots + + for (var/slot in S.dir) //but first, update all current character slots. + if (copytext(slot, 1, 10) != "character") + continue + var/slotnum = text2num(copytext(slot, 10)) + if (!slotnum) + continue + max_save_slots = max(max_save_slots, slotnum) //so we can still update byond member slots after they lose memeber status + default_slot = slotnum + if (load_character()) + save_character() + default_slot = old_default_slot + max_save_slots = old_max_save_slots + save_preferences() return TRUE @@ -266,12 +293,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car scars_index = rand(1,5) - if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000") - WRITE_FILE(S["features["mcolor"]"] , "#FFF") - - if(!S["feature_ethcolor"] || S["feature_ethcolor"] == "#000") - WRITE_FILE(S["feature_ethcolor"] , "9c3030") - //Character READ_FILE(S["real_name"], real_name) READ_FILE(S["gender"], gender) @@ -334,11 +355,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car READ_FILE(S["all_quirks"], all_quirks) //try to fix any outdated data if necessary + //preference updating will handle saving the updated data for us. if(needs_update >= 0) update_character(needs_update, S) //needs_update == savefile_version if we need an update (positive integer) //Sanitize - real_name = reject_bad_name(real_name) gender = sanitize_gender(gender) body_type = sanitize_gender(body_type, FALSE, FALSE, gender)