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:
parent
4c43f1ab85
commit
f3868c2ee8
2
hmm.json
2
hmm.json
|
@ -153,7 +153,7 @@
|
|||
"name": "polymod",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "8553b800965f225bb14c7ab8f04bfa9cdec362ac",
|
||||
"ref": "bfbe30d81601b3543d80dce580108ad6b7e182c7",
|
||||
"url": "https://github.com/larsiusprime/polymod"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue