From b39712d33f6d36ddcf14c8fb050572abb9562549 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 3 Apr 2024 20:31:34 -0400 Subject: [PATCH] Prevent crashes when the game attempts to load bad save data. --- hmm.json | 2 +- source/funkin/save/Save.hx | 4 +++ source/funkin/util/SerializerUtil.hx | 48 ++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index 0dfe88ded..641ef1bbd 100644 --- a/hmm.json +++ b/hmm.json @@ -139,7 +139,7 @@ "name": "openfl", "type": "git", "dir": null, - "ref": "f229d76361c7e31025a048fe7909847f75bb5d5e", + "ref": "228c1b5063911e2ad75cef6e3168ef0a4b9f9134", "url": "https://github.com/FunkinCrew/openfl" }, { diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index dc7c5f989..6f2146a7a 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -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()) diff --git a/source/funkin/util/SerializerUtil.hx b/source/funkin/util/SerializerUtil.hx index c87d3f6c0..fa602cc73 100644 --- a/source/funkin/util/SerializerUtil.hx +++ b/source/funkin/util/SerializerUtil.hx @@ -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 + { + 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 + { + return Type.resolveEnum(name); + }; +}