Prevent crashes when the game attempts to load bad save data.

This commit is contained in:
EliteMasterEric 2024-04-03 20:31:34 -04:00
parent 4f2f28cb31
commit b39712d33f
3 changed files with 53 additions and 1 deletions

View File

@ -139,7 +139,7 @@
"name": "openfl",
"type": "git",
"dir": null,
"ref": "f229d76361c7e31025a048fe7909847f75bb5d5e",
"ref": "228c1b5063911e2ad75cef6e3168ef0a4b9f9134",
"url": "https://github.com/FunkinCrew/openfl"
},
{

View File

@ -9,6 +9,7 @@ import funkin.save.migrator.SaveDataMigrator;
import funkin.ui.debug.charting.ChartEditorState.ChartEditorLiveInputStyle;
import funkin.ui.debug.charting.ChartEditorState.ChartEditorTheme;
import thx.semver.Version;
import funkin.util.SerializerUtil;
@:nullSafety
class Save
@ -641,6 +642,9 @@ class Save
{
trace("[SAVE] Loading save from slot " + slot + "...");
// Prevent crashes if the save data is corrupted.
SerializerUtil.initSerializer();
FlxG.save.bind('$SAVE_NAME${slot}', SAVE_PATH);
if (FlxG.save.isEmpty())

View File

@ -63,6 +63,31 @@ class SerializerUtil
}
}
public static function initSerializer():Void
{
haxe.Unserializer.DEFAULT_RESOLVER = new FunkinTypeResolver();
}
/**
* Serialize a Haxe object using the built-in Serializer.
* @param input The object to serialize
* @return The serialized object as a string
*/
public static function fromHaxeObject(input:Dynamic):String
{
return haxe.Serializer.run(input);
}
/**
* Convert a serialized Haxe object back into a Haxe object.
* @param input The serialized object as a string
* @return The deserialized object
*/
public static function toHaxeObject(input:String):Dynamic
{
return haxe.Unserializer.run(input);
}
/**
* Customize how certain types are serialized when converting to JSON.
*/
@ -90,3 +115,26 @@ class SerializerUtil
return result;
}
}
class FunkinTypeResolver
{
public function new()
{
// Blank constructor.
}
public function resolveClass(name:String):Class<Dynamic>
{
if (name == 'Dynamic')
{
FlxG.log.warn('Found invalid class type in save data, indicates partial save corruption.');
return null;
}
return Type.resolveClass(name);
};
public function resolveEnum(name:String):Enum<Dynamic>
{
return Type.resolveEnum(name);
};
}