1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-11-15 11:22:55 +00:00

An attempt at an HTML5 save data fix

This commit is contained in:
EliteMasterEric 2024-05-21 02:23:21 -04:00
parent 4c43f1ab85
commit f3868c2ee8
5 changed files with 55 additions and 11 deletions

View file

@ -153,7 +153,7 @@
"name": "polymod",
"type": "git",
"dir": null,
"ref": "8553b800965f225bb14c7ab8f04bfa9cdec362ac",
"ref": "bfbe30d81601b3543d80dce580108ad6b7e182c7",
"url": "https://github.com/larsiusprime/polymod"
},
{

View file

@ -53,7 +53,8 @@ class Save
public function new(?data:RawSaveData)
{
if (data == null) this.data = Save.getDefault();
else this.data = data;
else
this.data = data;
}
public static function getDefault():RawSaveData
@ -714,6 +715,7 @@ class Save
/**
* An anonymous structure containingg all the user's save data.
* Isn't stored with JSON, stored with some sort of Haxe built-in serialization?
*/
typedef RawSaveData =
{
@ -724,8 +726,6 @@ typedef RawSaveData =
/**
* A semantic versioning string for the save data format.
*/
@:jcustomparse(funkin.data.DataParse.semverVersion)
@:jcustomwrite(funkin.data.DataWrite.semverVersion)
var version:Version;
var api:SaveApiData;

View file

@ -24,6 +24,8 @@ class SaveDataMigrator
}
else
{
// Sometimes the Haxe serializer has issues with the version so we fix it here.
version = VersionUtil.repairVersion(version);
if (VersionUtil.validateVersion(version, Save.SAVE_DATA_VERSION_RULE))
{
// Simply import the structured data.
@ -32,8 +34,9 @@ class SaveDataMigrator
}
else
{
trace('[SAVE] Invalid save data version! Returning blank data.');
trace(inputData);
var message:String = 'Error migrating save data, expected ${Save.SAVE_DATA_VERSION}.';
lime.app.Application.current.window.alert(message, "Save Data Failure");
trace('[SAVE] ' + message);
return new Save(Save.getDefault());
}
}

View file

@ -44,8 +44,15 @@ class StructureUtil
return Std.isOfType(a, haxe.Constraints.IMap);
}
public static function isObject(a:Dynamic):Bool
/**
* Returns `true` if `a` is an anonymous structure.
* I believe this returns `false` even for class instances and arrays.
*/
public static function isStructure(a:Dynamic):Bool
{
// TODO: Is there a difference?
// return Reflect.isObject(foo);
switch (Type.typeof(a))
{
case TObject:
@ -55,6 +62,22 @@ class StructureUtil
}
}
/**
* Returns true if `a` is an array.
*
* NOTE: isObject and isInstance also return true,
* since they're objects of the Array<> class, so check this first!
*/
public static function isArray(a:Dynamic):Bool
{
return Std.is(a, Array);
}
public static function isInstance(a:Dynamic):Bool
{
return Type.getClass(a) != null;
}
public static function isPrimitive(a:Dynamic):Bool
{
switch (Type.typeof(a))
@ -89,6 +112,7 @@ class StructureUtil
{
if (a == null) return b;
if (b == null) return null;
if (isArray(a) && isArray(b)) return b;
if (isPrimitive(a) && isPrimitive(b)) return b;
if (isMap(b))
{
@ -101,7 +125,6 @@ class StructureUtil
return StructureUtil.toMap(a).merge(b);
}
}
if (!Reflect.isObject(a) || !Reflect.isObject(b)) return b;
if (Std.isOfType(b, haxe.ds.StringMap))
{
if (Std.isOfType(a, haxe.ds.StringMap))
@ -113,15 +136,14 @@ class StructureUtil
return StructureUtil.toMap(a).merge(b);
}
}
if (!isStructure(a) || !isStructure(b)) return b;
var result:DynamicAccess<Dynamic> = Reflect.copy(a);
for (field in Reflect.fields(b))
{
if (Reflect.isObject(b))
if (isStructure(b))
{
// Note that isObject also returns true for class instances,
// but we just assume that's not a problem here.
result.set(field, deepMerge(Reflect.field(result, field), Reflect.field(b, field)));
}
else

View file

@ -32,6 +32,25 @@ class VersionUtil
}
}
public static function repairVersion(version:thx.semver.Version):thx.semver.Version
{
var versionData:thx.semver.Version.SemVer = version;
if (StructureUtil.isStructure(versionData.version))
{
// This is bad! versionData.version should be an array!
versionData.version = [versionData.version[0], versionData.version[1], versionData.version[2]];
var fixedVersion:thx.semver.Version = versionData;
return fixedVersion;
}
else
{
// No need for repair.
return version;
}
}
/**
* Checks that a given verison number satisisfies a given version rule.
* Version rule can be complex, e.g. "1.0.x" or ">=1.0.0,<1.1.0", or anything NPM supports.