Use system.text.json to parse typetree

well, it's still slower than some more suitable libs for such task, but stable and with minimal code changes (and has net472 support, yeah)
This commit is contained in:
VaDiM 2024-04-13 01:01:23 +03:00
parent a3f4c7a029
commit 2c860f004b
8 changed files with 115 additions and 59 deletions

View File

@ -13,14 +13,11 @@
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="System.IO.Compression" Version="4.0.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.1.11" />
<PackageReference Include="ZstdSharp.Port" Version="0.6.5" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
</Project>

View File

@ -5,6 +5,8 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json;
using static AssetStudio.ImportHelper;
namespace AssetStudio
@ -511,6 +513,13 @@ namespace AssetStudio
{
Logger.Info("Read assets...");
var jsonOptions = new JsonSerializerOptions
{
Converters = { new JsonConverterHelper.ByteArrayConverter() },
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
IncludeFields = true,
};
var progressCount = assetsFileList.Sum(x => x.m_Objects.Count);
int i = 0;
Progress.Reset();
@ -533,7 +542,7 @@ namespace AssetStudio
break;
case ClassIDType.AnimationClip:
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
? new AnimationClip(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
? new AnimationClip(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader), jsonOptions)
: new AnimationClip(objectReader);
break;
case ClassIDType.Animator:
@ -608,12 +617,12 @@ namespace AssetStudio
break;
case ClassIDType.Texture2D:
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
? new Texture2D(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
? new Texture2D(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader), jsonOptions)
: new Texture2D(objectReader);
break;
case ClassIDType.Texture2DArray:
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
? new Texture2DArray(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
? new Texture2DArray(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader), jsonOptions)
: new Texture2DArray(objectReader);
break;
case ClassIDType.Transform:

View File

@ -1,9 +1,9 @@
using Newtonsoft.Json;
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
namespace AssetStudio
{
@ -1018,9 +1018,9 @@ namespace AssetStudio
public AnimationClip() { }
public AnimationClip(ObjectReader reader, IDictionary typeDict) : base(reader)
public AnimationClip(ObjectReader reader, IDictionary typeDict, JsonSerializerOptions jsonOptions) : base(reader)
{
var parsedAnimClip = JsonConvert.DeserializeObject<AnimationClip>(JsonConvert.SerializeObject(typeDict));
var parsedAnimClip = JsonSerializer.Deserialize<AnimationClip>(JsonSerializer.SerializeToUtf8Bytes(typeDict, jsonOptions), jsonOptions);
m_AnimationType = parsedAnimClip.m_AnimationType;
m_Legacy = parsedAnimClip.m_Legacy;
m_Compressed = parsedAnimClip.m_Compressed;

View File

@ -1,5 +1,7 @@
using Newtonsoft.Json;
using System.Collections.Specialized;
using System.Collections.Specialized;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
@ -19,6 +21,20 @@ namespace AssetStudio
[JsonIgnore]
public SerializedType serializedType;
public uint byteSize;
private static JsonSerializerOptions jsonOptions;
static Object()
{
jsonOptions = new JsonSerializerOptions
{
Converters = { new JsonConverterHelper.FloatConverter() },
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
IncludeFields = true,
WriteIndented = true,
};
}
public Object() { }
@ -41,34 +57,12 @@ namespace AssetStudio
}
}
public string Dump()
{
if (serializedType?.m_Type != null)
{
return TypeTreeHelper.ReadTypeString(serializedType.m_Type, reader);
}
return null;
}
public string Dump(TypeTree m_Type)
{
if (m_Type != null)
{
return TypeTreeHelper.ReadTypeString(m_Type, reader);
}
return null;
}
public string DumpObject()
{
string str = null;
try
{
str = JsonConvert.SerializeObject(this, new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}).Replace(" ", " ");
str = JsonSerializer.Serialize(this, GetType(), jsonOptions).Replace(" ", " ");
}
catch
{
@ -77,22 +71,22 @@ namespace AssetStudio
return str;
}
public OrderedDictionary ToType()
public string Dump(TypeTree m_Type = null)
{
if (serializedType?.m_Type != null)
{
return TypeTreeHelper.ReadType(serializedType.m_Type, reader);
}
return null;
m_Type = m_Type ?? serializedType?.m_Type;
if (m_Type == null)
return null;
return TypeTreeHelper.ReadTypeString(m_Type, reader);
}
public OrderedDictionary ToType(TypeTree m_Type)
public OrderedDictionary ToType(TypeTree m_Type = null)
{
if (m_Type != null)
{
return TypeTreeHelper.ReadType(m_Type, reader);
}
return null;
m_Type = m_Type ?? serializedType?.m_Type;
if (m_Type == null)
return null;
return TypeTreeHelper.ReadType(m_Type, reader);
}
public byte[] GetRawData()

View File

@ -1,6 +1,6 @@
using System;
using System.Collections;
using Newtonsoft.Json;
using System.Text.Json;
namespace AssetStudio
{
@ -53,9 +53,9 @@ namespace AssetStudio
byteSize = (uint)(m_Width * m_Height) * 4;
}
public Texture2D(ObjectReader reader, IDictionary typeDict) : base(reader)
public Texture2D(ObjectReader reader, IDictionary typeDict, JsonSerializerOptions jsonOptions) : base(reader)
{
var parsedTex2d = JsonConvert.DeserializeObject<Texture2D>(JsonConvert.SerializeObject(typeDict));
var parsedTex2d = JsonSerializer.Deserialize<Texture2D>(JsonSerializer.SerializeToUtf8Bytes(typeDict, jsonOptions), jsonOptions);
m_Width = parsedTex2d.m_Width;
m_Height = parsedTex2d.m_Height;
m_CompleteImageSize = parsedTex2d.m_CompleteImageSize;

View File

@ -1,6 +1,6 @@
using Newtonsoft.Json;
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Text.Json;
namespace AssetStudio
{
@ -50,9 +50,9 @@ namespace AssetStudio
TextureList = new List<Texture2D>();
}
public Texture2DArray(ObjectReader reader, IDictionary typeDict) : base(reader)
public Texture2DArray(ObjectReader reader, IDictionary typeDict, JsonSerializerOptions jsonOptions) : base(reader)
{
var parsedTex2dArray = JsonConvert.DeserializeObject<Texture2DArray>(JsonConvert.SerializeObject(typeDict));
var parsedTex2dArray = JsonSerializer.Deserialize<Texture2DArray>(JsonSerializer.SerializeToUtf8Bytes(typeDict, jsonOptions), jsonOptions);
m_Width = parsedTex2dArray.m_Width;
m_Height = parsedTex2dArray.m_Height;
m_Depth = parsedTex2dArray.m_Depth;

View File

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public static class JsonConverterHelper
{
public class ByteArrayConverter : JsonConverter<byte[]>
{
public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.TokenType == JsonTokenType.StartArray
? JsonSerializer.Deserialize<List<byte>>(ref reader).ToArray() //JsonArray to ByteArray
: JsonSerializer.Deserialize<byte[]>(ref reader);
}
public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options)
{
writer.WriteBase64StringValue(value);
}
}
public class FloatConverter : JsonConverter<float>
{
public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<float>(ref reader, new JsonSerializerOptions
{
NumberHandling = options.NumberHandling
});
}
public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options)
{
if (float.IsNaN(value) || float.IsInfinity(value))
{
if (options.NumberHandling == JsonNumberHandling.AllowNamedFloatingPointLiterals)
{
writer.WriteStringValue($"{value.ToString(CultureInfo.InvariantCulture)}");
}
else
{
writer.WriteStringValue(JsonSerializer.Serialize(value));
}
}
else
{
writer.WriteNumberValue((decimal)value);
}
}
}
}
}

View File

@ -281,13 +281,13 @@ namespace AssetStudio
var vector = GetNodes(m_Nodes, i);
i += vector.Count - 1;
var size = reader.ReadInt32();
var list = new List<object>(size);
var array = new object[size];
for (int j = 0; j < size; j++)
{
int tmp = 3;
list.Add(ReadValue(vector, reader, ref tmp));
array[j] = ReadValue(vector, reader, ref tmp);
}
value = list;
value = array;
break;
}
else //Class