mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-25 05:40:21 -04:00
Fixes and improvements for asset parsing via typetree
This commit is contained in:
parent
58ee2b8f1e
commit
c37e2e65b7
@ -515,16 +515,17 @@ namespace AssetStudio
|
||||
|
||||
var jsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
Converters = { new JsonConverterHelper.ByteArrayConverter() },
|
||||
Converters = { new JsonConverterHelper.ByteArrayConverter(), new JsonConverterHelper.PPtrConverter() },
|
||||
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
|
||||
IncludeFields = true,
|
||||
};
|
||||
|
||||
var progressCount = assetsFileList.Sum(x => x.m_Objects.Count);
|
||||
int i = 0;
|
||||
var i = 0;
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in assetsFileList)
|
||||
{
|
||||
JsonConverterHelper.PPtrConverter.AssetsFile = assetsFile;
|
||||
foreach (var objectInfo in assetsFile.m_Objects)
|
||||
{
|
||||
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
|
||||
@ -542,7 +543,7 @@ namespace AssetStudio
|
||||
break;
|
||||
case ClassIDType.AnimationClip:
|
||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
||||
? new AnimationClip(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||
? new AnimationClip(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||
: new AnimationClip(objectReader);
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
@ -620,12 +621,12 @@ namespace AssetStudio
|
||||
break;
|
||||
case ClassIDType.Texture2D:
|
||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
||||
? new Texture2D(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||
? new Texture2D(objectReader, TypeTreeHelper.ReadTypeByteArray(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), jsonOptions)
|
||||
? new Texture2DArray(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||
: new Texture2DArray(objectReader);
|
||||
break;
|
||||
case ClassIDType.Transform:
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -1031,9 +1030,9 @@ namespace AssetStudio
|
||||
|
||||
public AnimationClip() { }
|
||||
|
||||
public AnimationClip(ObjectReader reader, IDictionary typeDict, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
public AnimationClip(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
{
|
||||
var parsedAnimClip = JsonSerializer.Deserialize<AnimationClip>(JsonSerializer.SerializeToUtf8Bytes(typeDict, jsonOptions), jsonOptions);
|
||||
var parsedAnimClip = JsonSerializer.Deserialize<AnimationClip>(type, jsonOptions);
|
||||
m_AnimationType = parsedAnimClip.m_AnimationType;
|
||||
m_Legacy = parsedAnimClip.m_Legacy;
|
||||
m_Compressed = parsedAnimClip.m_Compressed;
|
||||
@ -1052,8 +1051,6 @@ namespace AssetStudio
|
||||
m_MuscleClip = parsedAnimClip.m_MuscleClip;
|
||||
m_ClipBindingConstant = parsedAnimClip.m_ClipBindingConstant;
|
||||
m_Events = parsedAnimClip.m_Events;
|
||||
|
||||
typeDict.Clear();
|
||||
}
|
||||
|
||||
public AnimationClip(ObjectReader reader) : base(reader)
|
||||
|
@ -19,6 +19,11 @@ namespace AssetStudio
|
||||
|
||||
public PPtr() { }
|
||||
|
||||
public void SetAssetsFile(SerializedFile assetsFile)
|
||||
{
|
||||
_assetsFile = assetsFile;
|
||||
}
|
||||
|
||||
private bool TryGetAssetsFile(out SerializedFile result)
|
||||
{
|
||||
result = null;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@ -45,6 +46,7 @@ namespace AssetStudio
|
||||
public sealed class SpriteAtlas : NamedObject
|
||||
{
|
||||
public PPtr<Sprite>[] m_PackedSprites;
|
||||
[JsonConverter(typeof(JsonConverterHelper.RenderDataMapConverter))]
|
||||
public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap;
|
||||
public bool m_IsVariant;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@ -15,6 +15,7 @@ namespace AssetStudio
|
||||
public GLTextureSettings m_TextureSettings;
|
||||
public int m_ImageCount;
|
||||
public byte[] m_PlatformBlob;
|
||||
[JsonPropertyName("image data")]
|
||||
public ResourceReader image_data;
|
||||
public StreamingInfo m_StreamData;
|
||||
|
||||
@ -53,9 +54,9 @@ namespace AssetStudio
|
||||
byteSize = (uint)(m_Width * m_Height) * 4;
|
||||
}
|
||||
|
||||
public Texture2D(ObjectReader reader, IDictionary typeDict, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
public Texture2D(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
{
|
||||
var parsedTex2d = JsonSerializer.Deserialize<Texture2D>(JsonSerializer.SerializeToUtf8Bytes(typeDict, jsonOptions), jsonOptions);
|
||||
var parsedTex2d = JsonSerializer.Deserialize<Texture2D>(type, jsonOptions);
|
||||
m_Width = parsedTex2d.m_Width;
|
||||
m_Height = parsedTex2d.m_Height;
|
||||
m_CompleteImageSize = parsedTex2d.m_CompleteImageSize;
|
||||
@ -70,7 +71,6 @@ namespace AssetStudio
|
||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
||||
: new ResourceReader(reader, parsedTex2d.image_data.Offset, parsedTex2d.image_data.Size);
|
||||
typeDict.Clear();
|
||||
}
|
||||
|
||||
public Texture2D(ObjectReader reader) : base(reader)
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@ -14,6 +14,7 @@ namespace AssetStudio
|
||||
public uint m_DataSize;
|
||||
public GLTextureSettings m_TextureSettings;
|
||||
public int m_ColorSpace;
|
||||
[JsonPropertyName("image data")]
|
||||
public ResourceReader image_data;
|
||||
public StreamingInfo m_StreamData;
|
||||
public List<Texture2D> TextureList;
|
||||
@ -50,9 +51,9 @@ namespace AssetStudio
|
||||
TextureList = new List<Texture2D>();
|
||||
}
|
||||
|
||||
public Texture2DArray(ObjectReader reader, IDictionary typeDict, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
public Texture2DArray(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
{
|
||||
var parsedTex2dArray = JsonSerializer.Deserialize<Texture2DArray>(JsonSerializer.SerializeToUtf8Bytes(typeDict, jsonOptions), jsonOptions);
|
||||
var parsedTex2dArray = JsonSerializer.Deserialize<Texture2DArray>(type, jsonOptions);
|
||||
m_Width = parsedTex2dArray.m_Width;
|
||||
m_Height = parsedTex2dArray.m_Height;
|
||||
m_Depth = parsedTex2dArray.m_Depth;
|
||||
@ -65,7 +66,6 @@ namespace AssetStudio
|
||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
||||
: new ResourceReader(reader, parsedTex2dArray.image_data.Offset, parsedTex2dArray.image_data.Size);
|
||||
typeDict.Clear();
|
||||
|
||||
TextureList = new List<Texture2D>();
|
||||
}
|
||||
|
25
AssetStudio/JsonConverterHelpers/ByteArrayConverter.cs
Normal file
25
AssetStudio/JsonConverterHelpers/ByteArrayConverter.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static partial 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +1,12 @@
|
||||
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 static partial 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)
|
53
AssetStudio/JsonConverterHelpers/PPtrConverter.cs
Normal file
53
AssetStudio/JsonConverterHelpers/PPtrConverter.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static partial class JsonConverterHelper
|
||||
{
|
||||
public class PPtrConverter : JsonConverterFactory
|
||||
{
|
||||
public static SerializedFile AssetsFile;
|
||||
|
||||
public override bool CanConvert(Type typeToConvert)
|
||||
{
|
||||
if (!typeToConvert.IsGenericType)
|
||||
return false;
|
||||
|
||||
var generic = typeToConvert.GetGenericTypeDefinition();
|
||||
return generic == typeof(PPtr<>);
|
||||
}
|
||||
|
||||
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
|
||||
{
|
||||
var elementType = type.GetGenericArguments()[0];
|
||||
var converter = (JsonConverter)Activator.CreateInstance(typeof(PPtrConverter<>).MakeGenericType(elementType), AssetsFile);
|
||||
return converter;
|
||||
}
|
||||
}
|
||||
|
||||
private class PPtrConverter<T> : JsonConverter<PPtr<T>> where T : Object
|
||||
{
|
||||
private readonly SerializedFile _assetsFile;
|
||||
|
||||
public PPtrConverter(SerializedFile assetsFile)
|
||||
{
|
||||
_assetsFile = assetsFile;
|
||||
}
|
||||
|
||||
public override PPtr<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var pptrObj = JsonSerializer.Deserialize<PPtr<T>>(ref reader);
|
||||
pptrObj.SetAssetsFile(_assetsFile);
|
||||
return pptrObj;
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, PPtr<T> value, JsonSerializerOptions options)
|
||||
{
|
||||
JsonSerializer.Serialize(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
58
AssetStudio/JsonConverterHelpers/RenderDataMapConverter.cs
Normal file
58
AssetStudio/JsonConverterHelpers/RenderDataMapConverter.cs
Normal file
@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static partial class JsonConverterHelper
|
||||
{
|
||||
public class RenderDataMapConverter : JsonConverter<Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>>
|
||||
{
|
||||
public override Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var dataArray = JsonSerializer.Deserialize<KeyValuePair<JsonObject, SpriteAtlasData>[]>(ref reader, options);
|
||||
var renderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>(dataArray.Length);
|
||||
foreach (var kvp in dataArray)
|
||||
{
|
||||
var jsonFirst = kvp.Key["first"];
|
||||
var first = jsonFirst.Deserialize<GUID>(options).Convert();
|
||||
var second = (long) kvp.Key["second"];
|
||||
renderDataMap.Add(new KeyValuePair<Guid, long>(first, second), kvp.Value);
|
||||
}
|
||||
return renderDataMap;
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> value, JsonSerializerOptions options)
|
||||
{
|
||||
var jsonDict = new Dictionary<string, SpriteAtlasData>();
|
||||
foreach (var kv in value)
|
||||
{
|
||||
var strKey = $"{kv.Key.Key}, {kv.Key.Value}";
|
||||
jsonDict.Add(strKey, kv.Value);
|
||||
}
|
||||
var strValue = JsonSerializer.Serialize(jsonDict, options).Replace(" ", " ");
|
||||
writer.WriteRawValue(strValue);
|
||||
}
|
||||
}
|
||||
|
||||
private class GUID
|
||||
{
|
||||
[JsonPropertyName("data[0]")] public uint data0;
|
||||
[JsonPropertyName("data[1]")] public uint data1;
|
||||
[JsonPropertyName("data[2]")] public uint data2;
|
||||
[JsonPropertyName("data[3]")] public uint data3;
|
||||
|
||||
public Guid Convert()
|
||||
{
|
||||
var guidBytes = new byte[16];
|
||||
BitConverter.GetBytes(data0).CopyTo(guidBytes, 0);
|
||||
BitConverter.GetBytes(data1).CopyTo(guidBytes, 4);
|
||||
BitConverter.GetBytes(data2).CopyTo(guidBytes, 8);
|
||||
BitConverter.GetBytes(data3).CopyTo(guidBytes, 12);
|
||||
return new Guid(guidBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,11 +3,24 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static class TypeTreeHelper
|
||||
{
|
||||
private static readonly JsonSerializerOptions JsonOptions;
|
||||
static TypeTreeHelper()
|
||||
{
|
||||
JsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
|
||||
ReferenceHandler = ReferenceHandler.IgnoreCycles,
|
||||
IncludeFields = true,
|
||||
};
|
||||
}
|
||||
|
||||
public static string ReadTypeString(TypeTree m_Type, ObjectReader reader)
|
||||
{
|
||||
reader.Reset();
|
||||
@ -163,6 +176,14 @@ namespace AssetStudio
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
public static byte[] ReadTypeByteArray(TypeTree m_Types, ObjectReader reader)
|
||||
{
|
||||
var type = ReadType(m_Types, reader);
|
||||
var bytes = JsonSerializer.SerializeToUtf8Bytes(type, JsonOptions);
|
||||
type.Clear();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static OrderedDictionary ReadType(TypeTree m_Types, ObjectReader reader)
|
||||
{
|
||||
reader.Reset();
|
||||
@ -171,7 +192,7 @@ namespace AssetStudio
|
||||
for (int i = 1; i < m_Nodes.Count; i++)
|
||||
{
|
||||
var m_Node = m_Nodes[i];
|
||||
var varNameStr = m_Node.m_Name.Replace("image data", "image_data");
|
||||
var varNameStr = m_Node.m_Name;
|
||||
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
|
||||
}
|
||||
var readed = reader.Position - reader.byteStart;
|
||||
|
@ -7,7 +7,6 @@ namespace CubismLive2DExtractor
|
||||
{
|
||||
class CubismMotion3Converter
|
||||
{
|
||||
private SerializedFile assetsFile;
|
||||
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
||||
public List<ImportedKeyframedAnimation> AnimationList { get; protected set; } = new List<ImportedKeyframedAnimation>();
|
||||
|
||||
@ -30,7 +29,6 @@ namespace CubismLive2DExtractor
|
||||
foreach (var animationClip in animationClips)
|
||||
{
|
||||
var iAnim = new ImportedKeyframedAnimation();
|
||||
assetsFile = animationClip.assetsFile;
|
||||
AnimationList.Add(iAnim);
|
||||
iAnim.Name = animationClip.m_Name;
|
||||
iAnim.SampleRate = animationClip.m_SampleRate;
|
||||
@ -136,7 +134,7 @@ namespace CubismLive2DExtractor
|
||||
target = "PartOpacity";
|
||||
}
|
||||
}
|
||||
else if (binding.script.TryGet(out MonoScript script, assetsFile))
|
||||
else if (binding.script.TryGet(out MonoScript script))
|
||||
{
|
||||
switch (script.m_ClassName)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user