[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 <kyleshome@gmail.com>
This commit is contained in:
SkyratBot
2020-08-05 10:12:51 +02:00
committed by GitHub
co-authored by Kyle Spier-Swenson
parent 71ce4bb464
commit f858df6523
+29 -8
View File
@@ -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)