From ce4df857e9e64ebba8cae69a0a37f3b934e2a543 Mon Sep 17 00:00:00 2001 From: Alan Liu Date: Wed, 10 Aug 2022 16:26:42 +0800 Subject: [PATCH] Fixed an issue that deserialized guids in SpriteAtlas and Sprite don't match the value in Unity --- AssetStudio/Classes/Sprite.cs | 2 +- AssetStudio/Classes/SpriteAtlas.cs | 2 +- AssetStudio/UnityGuidHelper.cs | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 AssetStudio/UnityGuidHelper.cs diff --git a/AssetStudio/Classes/Sprite.cs b/AssetStudio/Classes/Sprite.cs index 752794f5..653ee08f 100644 --- a/AssetStudio/Classes/Sprite.cs +++ b/AssetStudio/Classes/Sprite.cs @@ -233,7 +233,7 @@ public Sprite(ObjectReader reader) : base(reader) if (version[0] >= 2017) //2017 and up { - var first = new Guid(reader.ReadBytes(16)); + var first = UnityGuidHelper.UnityGuidToGuid(reader.ReadBytes(16)); var second = reader.ReadInt64(); m_RenderDataKey = new KeyValuePair(first, second); diff --git a/AssetStudio/Classes/SpriteAtlas.cs b/AssetStudio/Classes/SpriteAtlas.cs index c1a97c5c..d1c0a329 100644 --- a/AssetStudio/Classes/SpriteAtlas.cs +++ b/AssetStudio/Classes/SpriteAtlas.cs @@ -63,7 +63,7 @@ public SpriteAtlas(ObjectReader reader) : base(reader) m_RenderDataMap = new Dictionary, SpriteAtlasData>(m_RenderDataMapSize); for (int i = 0; i < m_RenderDataMapSize; i++) { - var first = new Guid(reader.ReadBytes(16)); + var first = UnityGuidHelper.UnityGuidToGuid(reader.ReadBytes(16)); var second = reader.ReadInt64(); var value = new SpriteAtlasData(reader); m_RenderDataMap.Add(new KeyValuePair(first, second), value); diff --git a/AssetStudio/UnityGuidHelper.cs b/AssetStudio/UnityGuidHelper.cs new file mode 100644 index 00000000..f067a9b4 --- /dev/null +++ b/AssetStudio/UnityGuidHelper.cs @@ -0,0 +1,28 @@ +using System; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AssetStudio +{ + class UnityGuidHelper + { + public static Guid UnityGuidToGuid(byte[] data, int offset = 0) + { + for (int i = 0; i < 16; ++i) + { + data[i + offset] = (byte)(((data[i + offset] & 0xF0) >> 4) | ((data[i + offset] & 0x0F) << 4)); + } + + int d1 = BinaryPrimitives.ReadInt32BigEndian(new ReadOnlySpan(data, offset, 4)); + short d2 = BinaryPrimitives.ReadInt16BigEndian(new ReadOnlySpan(data, offset + 4, 2)); + short d3 = BinaryPrimitives.ReadInt16BigEndian(new ReadOnlySpan(data, offset + 6, 2)); + + return new Guid(d1, d2, d3, + data[offset + 8], data[offset + 9], data[offset + 10], data[offset + 11], + data[offset + 12], data[offset + 13], data[offset + 14], data[offset + 15]); + } + } +}