From 432116d834230f31a7147a9e4ddf5b298882d091 Mon Sep 17 00:00:00 2001 From: Perfare Date: Fri, 28 May 2021 22:23:07 +0800 Subject: [PATCH] Improve SerializedFile reading. --- AssetStudio/AssetStudio.csproj | 2 + AssetStudio/AssetsManager.cs | 2 +- AssetStudio/Classes/Object.cs | 34 ++--- AssetStudio/Classes/PPtr.cs | 2 +- AssetStudio/ObjectInfo.cs | 2 + AssetStudio/ObjectReader.cs | 2 +- AssetStudio/SerializedFile.cs | 140 ++++++++++--------- AssetStudio/SerializedFileFormatVersion.cs | 33 +++++ AssetStudio/SerializedFileHeader.cs | 2 +- AssetStudio/SerializedType.cs | 5 +- AssetStudio/TypeTree.cs | 14 ++ AssetStudio/TypeTreeHelper.cs | 90 ++++++------ AssetStudioGUI/AssetStudioGUIForm.cs | 4 +- AssetStudioGUI/Components/TypeTreeItem.cs | 10 +- AssetStudioGUI/Exporter.cs | 8 +- AssetStudioGUI/Studio.cs | 16 +-- AssetStudioUtility/MonoBehaviourConverter.cs | 11 +- 17 files changed, 218 insertions(+), 159 deletions(-) create mode 100644 AssetStudio/SerializedFileFormatVersion.cs create mode 100644 AssetStudio/TypeTree.cs diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj index 3b7d546..6b98d61 100644 --- a/AssetStudio/AssetStudio.csproj +++ b/AssetStudio/AssetStudio.csproj @@ -135,10 +135,12 @@ + + diff --git a/AssetStudio/AssetsManager.cs b/AssetStudio/AssetsManager.cs index 2cc6ce4..02391aa 100644 --- a/AssetStudio/AssetsManager.cs +++ b/AssetStudio/AssetsManager.cs @@ -130,7 +130,7 @@ namespace AssetStudio { var assetsFile = new SerializedFile(this, fullName, reader); assetsFile.originalPath = originalPath; - if (assetsFile.header.m_Version < 7) + if (assetsFile.header.m_Version < SerializedFileFormatVersion.kUnknown_7) { assetsFile.SetVersion(unityVersion); } diff --git a/AssetStudio/Classes/Object.cs b/AssetStudio/Classes/Object.cs index a070013..8ce7293 100644 --- a/AssetStudio/Classes/Object.cs +++ b/AssetStudio/Classes/Object.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using System.Text; +using System.Collections.Specialized; namespace AssetStudio { @@ -36,47 +33,38 @@ namespace AssetStudio } } - protected bool HasStructMember(string name) - { - return serializedType?.m_Nodes != null && serializedType.m_Nodes.Any(x => x.m_Name == name); - } - public string Dump() { - if (serializedType?.m_Nodes != null) + if (serializedType?.m_Type != null) { - var sb = new StringBuilder(); - TypeTreeHelper.ReadTypeString(sb, serializedType.m_Nodes, reader); - return sb.ToString(); + return TypeTreeHelper.ReadTypeString(serializedType.m_Type, reader); } return null; } - public string Dump(List m_Nodes) + public string Dump(TypeTree m_Type) { - if (m_Nodes != null) + if (m_Type != null) { - var sb = new StringBuilder(); - TypeTreeHelper.ReadTypeString(sb, m_Nodes, reader); - return sb.ToString(); + return TypeTreeHelper.ReadTypeString(m_Type, reader); } return null; } public OrderedDictionary ToType() { - if (serializedType?.m_Nodes != null) + if (serializedType?.m_Type != null) { - return TypeTreeHelper.ReadType(serializedType.m_Nodes, reader); + return TypeTreeHelper.ReadType(serializedType.m_Type, reader); } return null; } - public OrderedDictionary ToType(List m_Nodes) + public OrderedDictionary ToType(TypeTree m_Type) { - if (m_Nodes != null) + if (m_Type != null) { - return TypeTreeHelper.ReadType(m_Nodes, reader); + return TypeTreeHelper.ReadType(m_Type, reader); } return null; } diff --git a/AssetStudio/Classes/PPtr.cs b/AssetStudio/Classes/PPtr.cs index 561090a..4849e9c 100644 --- a/AssetStudio/Classes/PPtr.cs +++ b/AssetStudio/Classes/PPtr.cs @@ -13,7 +13,7 @@ namespace AssetStudio public PPtr(ObjectReader reader) { m_FileID = reader.ReadInt32(); - m_PathID = reader.m_Version < 14 ? reader.ReadInt32() : reader.ReadInt64(); + m_PathID = reader.m_Version < SerializedFileFormatVersion.kUnknown_14 ? reader.ReadInt32() : reader.ReadInt64(); assetsFile = reader.assetsFile; } diff --git a/AssetStudio/ObjectInfo.cs b/AssetStudio/ObjectInfo.cs index bf4314b..4a50105 100644 --- a/AssetStudio/ObjectInfo.cs +++ b/AssetStudio/ObjectInfo.cs @@ -11,6 +11,8 @@ namespace AssetStudio public uint byteSize; public int typeID; public int classID; + public ushort isDestroyed; + public byte stripped; public long m_PathID; public SerializedType serializedType; diff --git a/AssetStudio/ObjectReader.cs b/AssetStudio/ObjectReader.cs index dbf4441..47b33bc 100644 --- a/AssetStudio/ObjectReader.cs +++ b/AssetStudio/ObjectReader.cs @@ -15,7 +15,7 @@ namespace AssetStudio public ClassIDType type; public SerializedType serializedType; public BuildTarget platform; - public uint m_Version; + public SerializedFileFormatVersion m_Version; public int[] version => assetsFile.version; public BuildType buildType => assetsFile.buildType; diff --git a/AssetStudio/SerializedFile.cs b/AssetStudio/SerializedFile.cs index 3167bce..4c26ab8 100644 --- a/AssetStudio/SerializedFile.cs +++ b/AssetStudio/SerializedFile.cs @@ -19,15 +19,17 @@ namespace AssetStudio public Dictionary ObjectsDic; public SerializedFileHeader header; - private EndianType m_FileEndianess; + private byte m_FileEndianess; public string unityVersion = "2.5.0f5"; public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform; private bool m_EnableTypeTree = true; public List m_Types; - public List m_RefTypes; + public int bigIDEnabled = 0; public List m_Objects; private List m_ScriptTypes; public List m_Externals; + public List m_RefTypes; + public string userInformation; public SerializedFile(AssetsManager assetsManager, string fullName, EndianBinaryReader reader) { @@ -36,26 +38,26 @@ namespace AssetStudio this.fullName = fullName; fileName = Path.GetFileName(fullName); - //ReadHeader + // ReadHeader header = new SerializedFileHeader(); header.m_MetadataSize = reader.ReadUInt32(); header.m_FileSize = reader.ReadUInt32(); - header.m_Version = reader.ReadUInt32(); + header.m_Version = (SerializedFileFormatVersion)reader.ReadUInt32(); header.m_DataOffset = reader.ReadUInt32(); - if (header.m_Version >= 9) + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_9) { header.m_Endianess = reader.ReadByte(); header.m_Reserved = reader.ReadBytes(3); - m_FileEndianess = (EndianType)header.m_Endianess; + m_FileEndianess = header.m_Endianess; } else { reader.Position = header.m_FileSize - header.m_MetadataSize; - m_FileEndianess = (EndianType)reader.ReadByte(); + m_FileEndianess = reader.ReadByte(); } - if (header.m_Version >= 22) + if (header.m_Version >= SerializedFileFormatVersion.kLargeFilesSupport) { header.m_MetadataSize = reader.ReadUInt32(); header.m_FileSize = reader.ReadInt64(); @@ -63,17 +65,17 @@ namespace AssetStudio reader.ReadInt64(); // unknown } - //ReadMetadata - if (m_FileEndianess == EndianType.LittleEndian) + // ReadMetadata + if (m_FileEndianess == 0) { reader.endian = EndianType.LittleEndian; } - if (header.m_Version >= 7) + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_7) { unityVersion = reader.ReadStringToNull(); SetVersion(unityVersion); } - if (header.m_Version >= 8) + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_8) { m_TargetPlatform = (BuildTarget)reader.ReadInt32(); if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform)) @@ -81,26 +83,25 @@ namespace AssetStudio m_TargetPlatform = BuildTarget.UnknownPlatform; } } - if (header.m_Version >= 13) + if (header.m_Version >= SerializedFileFormatVersion.kHasTypeTreeHashes) { m_EnableTypeTree = reader.ReadBoolean(); } - //ReadTypes + // Read Types int typeCount = reader.ReadInt32(); m_Types = new List(typeCount); for (int i = 0; i < typeCount; i++) { - m_Types.Add(ReadSerializedType()); + m_Types.Add(ReadSerializedType(false)); } - var bigIDEnabled = 0; - if (header.m_Version >= 7 && header.m_Version < 14) + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_7 && header.m_Version < SerializedFileFormatVersion.kUnknown_14) { bigIDEnabled = reader.ReadInt32(); } - //ReadObjects + // Read Objects int objectCount = reader.ReadInt32(); m_Objects = new List(objectCount); Objects = new List(objectCount); @@ -112,7 +113,7 @@ namespace AssetStudio { objectInfo.m_PathID = reader.ReadInt64(); } - else if (header.m_Version < 14) + else if (header.m_Version < SerializedFileFormatVersion.kUnknown_14) { objectInfo.m_PathID = reader.ReadInt32(); } @@ -122,7 +123,7 @@ namespace AssetStudio objectInfo.m_PathID = reader.ReadInt64(); } - if (header.m_Version >= 22) + if (header.m_Version >= SerializedFileFormatVersion.kLargeFilesSupport) objectInfo.byteStart = reader.ReadInt64(); else objectInfo.byteStart = reader.ReadUInt32(); @@ -130,7 +131,7 @@ namespace AssetStudio objectInfo.byteStart += header.m_DataOffset; objectInfo.byteSize = reader.ReadUInt32(); objectInfo.typeID = reader.ReadInt32(); - if (header.m_Version < 16) + if (header.m_Version < SerializedFileFormatVersion.kRefactoredClassId) { objectInfo.classID = reader.ReadUInt16(); objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID); @@ -141,24 +142,24 @@ namespace AssetStudio objectInfo.serializedType = type; objectInfo.classID = type.classID; } - if (header.m_Version < 11) + if (header.m_Version < SerializedFileFormatVersion.kHasScriptTypeIndex) { - var isDestroyed = reader.ReadUInt16(); + objectInfo.isDestroyed = reader.ReadUInt16(); } - if (header.m_Version >= 11 && header.m_Version < 17) + if (header.m_Version >= SerializedFileFormatVersion.kHasScriptTypeIndex && header.m_Version < SerializedFileFormatVersion.kRefactorTypeData) { var m_ScriptTypeIndex = reader.ReadInt16(); if (objectInfo.serializedType != null) objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex; } - if (header.m_Version == 15 || header.m_Version == 16) + if (header.m_Version == SerializedFileFormatVersion.kSupportsStrippedObject || header.m_Version == SerializedFileFormatVersion.kRefactoredClassId) { - var stripped = reader.ReadByte(); + objectInfo.stripped = reader.ReadByte(); } m_Objects.Add(objectInfo); } - if (header.m_Version >= 11) + if (header.m_Version >= SerializedFileFormatVersion.kHasScriptTypeIndex) { int scriptCount = reader.ReadInt32(); m_ScriptTypes = new List(scriptCount); @@ -166,7 +167,7 @@ namespace AssetStudio { var m_ScriptType = new LocalSerializedObjectIdentifier(); m_ScriptType.localSerializedFileIndex = reader.ReadInt32(); - if (header.m_Version < 14) + if (header.m_Version < SerializedFileFormatVersion.kUnknown_14) { m_ScriptType.localIdentifierInFile = reader.ReadInt32(); } @@ -184,11 +185,11 @@ namespace AssetStudio for (int i = 0; i < externalsCount; i++) { var m_External = new FileIdentifier(); - if (header.m_Version >= 6) + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_6) { var tempEmpty = reader.ReadStringToNull(); } - if (header.m_Version >= 5) + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_5) { m_External.guid = new Guid(reader.ReadBytes(16)); m_External.type = reader.ReadInt32(); @@ -198,19 +199,19 @@ namespace AssetStudio m_Externals.Add(m_External); } - if (header.m_Version >= 20) + if (header.m_Version >= SerializedFileFormatVersion.kSupportsRefObject) { int refTypesCount = reader.ReadInt32(); m_RefTypes = new List(refTypesCount); for (int i = 0; i < refTypesCount; i++) { - m_RefTypes.Add(ReadSerializedType()); + m_RefTypes.Add(ReadSerializedType(true)); } } - if (header.m_Version >= 5) + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_5) { - var userInformation = reader.ReadStringToNull(); + userInformation = reader.ReadStringToNull(); } //reader.AlignStream(16); @@ -225,73 +226,84 @@ namespace AssetStudio version = versionSplit.Select(int.Parse).ToArray(); } - private SerializedType ReadSerializedType() + private SerializedType ReadSerializedType(bool isRefType) { var type = new SerializedType(); type.classID = reader.ReadInt32(); - if (header.m_Version >= 16) + if (header.m_Version >= SerializedFileFormatVersion.kRefactoredClassId) { type.m_IsStrippedType = reader.ReadBoolean(); } - if (header.m_Version >= 17) + if (header.m_Version >= SerializedFileFormatVersion.kRefactorTypeData) { type.m_ScriptTypeIndex = reader.ReadInt16(); } - if (header.m_Version >= 13) + if (header.m_Version >= SerializedFileFormatVersion.kHasTypeTreeHashes) { - if ((header.m_Version < 16 && type.classID < 0) || (header.m_Version >= 16 && type.classID == 114)) + if (isRefType && type.m_ScriptTypeIndex >= 0) { - type.m_ScriptID = reader.ReadBytes(16); //Hash128 + type.m_ScriptID = reader.ReadBytes(16); } - type.m_OldTypeHash = reader.ReadBytes(16); //Hash128 + else if ((header.m_Version < SerializedFileFormatVersion.kRefactoredClassId && type.classID < 0) || (header.m_Version >= SerializedFileFormatVersion.kRefactoredClassId && type.classID == 114)) + { + type.m_ScriptID = reader.ReadBytes(16); + } + type.m_OldTypeHash = reader.ReadBytes(16); } if (m_EnableTypeTree) { - var typeTree = new List(); - if (header.m_Version >= 12 || header.m_Version == 10) + type.m_Type = new TypeTree(); + type.m_Type.m_Nodes = new List(); + if (header.m_Version >= SerializedFileFormatVersion.kUnknown_12 || header.m_Version == SerializedFileFormatVersion.kUnknown_10) { - TypeTreeBlobRead(typeTree); + TypeTreeBlobRead(type.m_Type); } else { - ReadTypeTree(typeTree); + ReadTypeTree(type.m_Type); } - - if (header.m_Version >= 21) + if (header.m_Version >= SerializedFileFormatVersion.kStoresTypeDependencies) { - type.m_TypeDependencies = reader.ReadInt32Array(); + if (isRefType) + { + type.m_KlassName = reader.ReadStringToNull(); + type.m_NameSpace = reader.ReadStringToNull(); + type.m_AsmName = reader.ReadStringToNull(); + } + else + { + type.m_TypeDependencies = reader.ReadInt32Array(); + } } - - type.m_Nodes = typeTree; } return type; } - private void ReadTypeTree(List typeTree, int level = 0) + private void ReadTypeTree(TypeTree m_Type, int level = 0) { var typeTreeNode = new TypeTreeNode(); - typeTree.Add(typeTreeNode); + m_Type.m_Nodes.Add(typeTreeNode); typeTreeNode.m_Level = level; typeTreeNode.m_Type = reader.ReadStringToNull(); typeTreeNode.m_Name = reader.ReadStringToNull(); typeTreeNode.m_ByteSize = reader.ReadInt32(); - if (header.m_Version == 2) + if (header.m_Version == SerializedFileFormatVersion.kUnknown_2) { var variableCount = reader.ReadInt32(); } - if (header.m_Version != 3) + if (header.m_Version != SerializedFileFormatVersion.kUnknown_3) { typeTreeNode.m_Index = reader.ReadInt32(); } typeTreeNode.m_IsArray = reader.ReadInt32(); typeTreeNode.m_Version = reader.ReadInt32(); - if (header.m_Version != 3) + if (header.m_Version != SerializedFileFormatVersion.kUnknown_3) { typeTreeNode.m_MetaFlag = reader.ReadInt32(); } @@ -299,18 +311,18 @@ namespace AssetStudio int childrenCount = reader.ReadInt32(); for (int i = 0; i < childrenCount; i++) { - ReadTypeTree(typeTree, level + 1); + ReadTypeTree(m_Type, level + 1); } } - private void TypeTreeBlobRead(List typeTree) + private void TypeTreeBlobRead(TypeTree m_Type) { int numberOfNodes = reader.ReadInt32(); int stringBufferSize = reader.ReadInt32(); for (int i = 0; i < numberOfNodes; i++) { var typeTreeNode = new TypeTreeNode(); - typeTree.Add(typeTreeNode); + m_Type.m_Nodes.Add(typeTreeNode); typeTreeNode.m_Version = reader.ReadUInt16(); typeTreeNode.m_Level = reader.ReadByte(); typeTreeNode.m_IsArray = reader.ReadBoolean() ? 1 : 0; @@ -319,20 +331,20 @@ namespace AssetStudio typeTreeNode.m_ByteSize = reader.ReadInt32(); typeTreeNode.m_Index = reader.ReadInt32(); typeTreeNode.m_MetaFlag = reader.ReadInt32(); - if (header.m_Version >= 19) + if (header.m_Version >= SerializedFileFormatVersion.kTypeTreeNodeWithTypeFlags) { typeTreeNode.m_RefTypeHash = reader.ReadUInt64(); } } - var m_StringBuffer = reader.ReadBytes(stringBufferSize); + m_Type.m_StringBuffer = reader.ReadBytes(stringBufferSize); - using (var stringBufferReader = new BinaryReader(new MemoryStream(m_StringBuffer))) + using (var stringBufferReader = new BinaryReader(new MemoryStream(m_Type.m_StringBuffer))) { for (int i = 0; i < numberOfNodes; i++) { - var typeTreeNode = typeTree[i]; - typeTreeNode.m_Type = ReadString(stringBufferReader, typeTreeNode.m_TypeStrOffset); - typeTreeNode.m_Name = ReadString(stringBufferReader, typeTreeNode.m_NameStrOffset); + var m_Node = m_Type.m_Nodes[i]; + m_Node.m_Type = ReadString(stringBufferReader, m_Node.m_TypeStrOffset); + m_Node.m_Name = ReadString(stringBufferReader, m_Node.m_NameStrOffset); } } diff --git a/AssetStudio/SerializedFileFormatVersion.cs b/AssetStudio/SerializedFileFormatVersion.cs new file mode 100644 index 0000000..30edd5e --- /dev/null +++ b/AssetStudio/SerializedFileFormatVersion.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AssetStudio +{ + public enum SerializedFileFormatVersion + { + kUnsupported = 1, + kUnknown_2 = 2, + kUnknown_3 = 3, + kUnknown_5 = 5, + kUnknown_6 = 6, + kUnknown_7 = 7, + kUnknown_8 = 8, + kUnknown_9 = 9, + kUnknown_10 = 10, + kHasScriptTypeIndex = 11, + kUnknown_12 = 12, + kHasTypeTreeHashes = 13, + kUnknown_14 = 14, + kSupportsStrippedObject = 15, + kRefactoredClassId = 16, + kRefactorTypeData = 17, + kRefactorShareableTypeTreeData = 18, + kTypeTreeNodeWithTypeFlags = 19, + kSupportsRefObject = 20, + kStoresTypeDependencies = 21, + kLargeFilesSupport = 22 + } +} diff --git a/AssetStudio/SerializedFileHeader.cs b/AssetStudio/SerializedFileHeader.cs index e45b609..81f4f31 100644 --- a/AssetStudio/SerializedFileHeader.cs +++ b/AssetStudio/SerializedFileHeader.cs @@ -9,7 +9,7 @@ namespace AssetStudio { public uint m_MetadataSize; public long m_FileSize; - public uint m_Version; + public SerializedFileFormatVersion m_Version; public long m_DataOffset; public byte m_Endianess; public byte[] m_Reserved; diff --git a/AssetStudio/SerializedType.cs b/AssetStudio/SerializedType.cs index a4f61f2..a4e3db6 100644 --- a/AssetStudio/SerializedType.cs +++ b/AssetStudio/SerializedType.cs @@ -10,9 +10,12 @@ namespace AssetStudio public int classID; public bool m_IsStrippedType; public short m_ScriptTypeIndex = -1; - public List m_Nodes; + public TypeTree m_Type; public byte[] m_ScriptID; //Hash128 public byte[] m_OldTypeHash; //Hash128 public int[] m_TypeDependencies; + public string m_KlassName; + public string m_NameSpace; + public string m_AsmName; } } diff --git a/AssetStudio/TypeTree.cs b/AssetStudio/TypeTree.cs new file mode 100644 index 0000000..a10a2d0 --- /dev/null +++ b/AssetStudio/TypeTree.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AssetStudio +{ + public class TypeTree + { + public List m_Nodes; + public byte[] m_StringBuffer; + } +} diff --git a/AssetStudio/TypeTreeHelper.cs b/AssetStudio/TypeTreeHelper.cs index 1b133cd..a3c5e32 100644 --- a/AssetStudio/TypeTreeHelper.cs +++ b/AssetStudio/TypeTreeHelper.cs @@ -7,29 +7,32 @@ namespace AssetStudio { public static class TypeTreeHelper { - public static void ReadTypeString(StringBuilder sb, List members, ObjectReader reader) + public static string ReadTypeString(TypeTree m_Type, ObjectReader reader) { reader.Reset(); - for (int i = 0; i < members.Count; i++) + var sb = new StringBuilder(); + var m_Nodes = m_Type.m_Nodes; + for (int i = 0; i < m_Nodes.Count; i++) { - ReadStringValue(sb, members, reader, ref i); + ReadStringValue(sb, m_Nodes, reader, ref i); } var readed = reader.Position - reader.byteStart; if (readed != reader.byteSize) { Logger.Info($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes"); } + return sb.ToString(); } - private static void ReadStringValue(StringBuilder sb, List members, BinaryReader reader, ref int i) + private static void ReadStringValue(StringBuilder sb, List m_Nodes, BinaryReader reader, ref int i) { - var member = members[i]; - var level = member.m_Level; - var varTypeStr = member.m_Type; - var varNameStr = member.m_Name; + var m_Node = m_Nodes[i]; + var level = m_Node.m_Level; + var varTypeStr = m_Node.m_Type; + var varNameStr = m_Node.m_Name; object value = null; var append = true; - var align = (member.m_MetaFlag & 0x4000) != 0; + var align = (m_Node.m_MetaFlag & 0x4000) != 0; switch (varTypeStr) { case "SInt8": @@ -82,18 +85,18 @@ namespace AssetStudio break; case "map": { - if ((members[i + 1].m_MetaFlag & 0x4000) != 0) + if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0) align = true; append = false; sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array"); var size = reader.ReadInt32(); sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size); - var map = GetMembers(members, i); + var map = GetNodes(m_Nodes, i); i += map.Count - 1; - var first = GetMembers(map, 4); + var first = GetNodes(map, 4); var next = 4 + first.Count; - var second = GetMembers(map, next); + var second = GetNodes(map, next); for (int j = 0; j < size; j++) { sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j); @@ -117,16 +120,16 @@ namespace AssetStudio } default: { - if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array + if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array { - if ((members[i + 1].m_MetaFlag & 0x4000) != 0) + if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0) align = true; append = false; sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array"); var size = reader.ReadInt32(); sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size); - var vector = GetMembers(members, i); + var vector = GetNodes(m_Nodes, i); i += vector.Count - 1; for (int j = 0; j < size; j++) { @@ -140,7 +143,7 @@ namespace AssetStudio { append = false; sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); - var @class = GetMembers(members, i); + var @class = GetNodes(m_Nodes, i); i += @class.Count - 1; for (int j = 1; j < @class.Count; j++) { @@ -156,15 +159,16 @@ namespace AssetStudio reader.AlignStream(); } - public static OrderedDictionary ReadType(List members, ObjectReader reader) + public static OrderedDictionary ReadType(TypeTree m_Types, ObjectReader reader) { reader.Reset(); var obj = new OrderedDictionary(); - for (int i = 1; i < members.Count; i++) + var m_Nodes = m_Types.m_Nodes; + for (int i = 1; i < m_Nodes.Count; i++) { - var member = members[i]; - var varNameStr = member.m_Name; - obj[varNameStr] = ReadValue(members, reader, ref i); + var m_Node = m_Nodes[i]; + var varNameStr = m_Node.m_Name; + obj[varNameStr] = ReadValue(m_Nodes, reader, ref i); } var readed = reader.Position - reader.byteStart; if (readed != reader.byteSize) @@ -174,12 +178,12 @@ namespace AssetStudio return obj; } - private static object ReadValue(List members, BinaryReader reader, ref int i) + private static object ReadValue(List m_Nodes, BinaryReader reader, ref int i) { - var member = members[i]; - var varTypeStr = member.m_Type; + var m_Node = m_Nodes[i]; + var varTypeStr = m_Node.m_Type; object value; - var align = (member.m_MetaFlag & 0x4000) != 0; + var align = (m_Node.m_MetaFlag & 0x4000) != 0; switch (varTypeStr) { case "SInt8": @@ -230,13 +234,13 @@ namespace AssetStudio break; case "map": { - if ((members[i + 1].m_MetaFlag & 0x4000) != 0) + if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0) align = true; - var map = GetMembers(members, i); + var map = GetNodes(m_Nodes, i); i += map.Count - 1; - var first = GetMembers(map, 4); + var first = GetNodes(map, 4); var next = 4 + first.Count; - var second = GetMembers(map, next); + var second = GetNodes(map, next); var size = reader.ReadInt32(); var dic = new List>(size); for (int j = 0; j < size; j++) @@ -257,11 +261,11 @@ namespace AssetStudio } default: { - if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array + if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array { - if ((members[i + 1].m_MetaFlag & 0x4000) != 0) + if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0) align = true; - var vector = GetMembers(members, i); + var vector = GetNodes(m_Nodes, i); i += vector.Count - 1; var size = reader.ReadInt32(); var list = new List(size); @@ -275,7 +279,7 @@ namespace AssetStudio } else //Class { - var @class = GetMembers(members, i); + var @class = GetNodes(m_Nodes, i); i += @class.Count - 1; var obj = new OrderedDictionary(); for (int j = 1; j < @class.Count; j++) @@ -294,22 +298,22 @@ namespace AssetStudio return value; } - private static List GetMembers(List members, int index) + private static List GetNodes(List m_Nodes, int index) { - var member2 = new List(); - member2.Add(members[index]); - var level = members[index].m_Level; - for (int i = index + 1; i < members.Count; i++) + var nodes = new List(); + nodes.Add(m_Nodes[index]); + var level = m_Nodes[index].m_Level; + for (int i = index + 1; i < m_Nodes.Count; i++) { - var member = members[i]; + var member = m_Nodes[i]; var level2 = member.m_Level; if (level2 <= level) { - return member2; + return nodes; } - member2.Add(member); + nodes.Add(member); } - return member2; + return nodes; } } } diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index b665cd1..e96bc13 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -943,8 +943,8 @@ namespace AssetStudioGUI var obj = m_MonoBehaviour.ToType(); if (obj == null) { - var nodes = MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); - obj = m_MonoBehaviour.ToType(nodes); + var type = MonoBehaviourToTypeTree(m_MonoBehaviour); + obj = m_MonoBehaviour.ToType(type); } var str = JsonConvert.SerializeObject(obj, Formatting.Indented); PreviewText(str); diff --git a/AssetStudioGUI/Components/TypeTreeItem.cs b/AssetStudioGUI/Components/TypeTreeItem.cs index e7ac72e..e0789ff 100644 --- a/AssetStudioGUI/Components/TypeTreeItem.cs +++ b/AssetStudioGUI/Components/TypeTreeItem.cs @@ -7,19 +7,19 @@ namespace AssetStudioGUI { internal class TypeTreeItem : ListViewItem { - private List m_Nodes; + private TypeTree m_Type; - public TypeTreeItem(int typeID, List m_Nodes) + public TypeTreeItem(int typeID, TypeTree m_Type) { - this.m_Nodes = m_Nodes; - Text = m_Nodes[0].m_Type + " " + m_Nodes[0].m_Name; + this.m_Type = m_Type; + Text = m_Type.m_Nodes[0].m_Type + " " + m_Type.m_Nodes[0].m_Name; SubItems.Add(typeID.ToString()); } public override string ToString() { var sb = new StringBuilder(); - foreach (var i in m_Nodes) + foreach (var i in m_Type.m_Nodes) { sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.m_Level), i.m_Type, i.m_Name, i.m_ByteSize, (i.m_MetaFlag & 0x4000) != 0); } diff --git a/AssetStudioGUI/Exporter.cs b/AssetStudioGUI/Exporter.cs index af83c22..1c00f68 100644 --- a/AssetStudioGUI/Exporter.cs +++ b/AssetStudioGUI/Exporter.cs @@ -120,8 +120,8 @@ namespace AssetStudioGUI var type = m_MonoBehaviour.ToType(); if (type == null) { - var nodes = Studio.MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); - type = m_MonoBehaviour.ToType(nodes); + var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour); + type = m_MonoBehaviour.ToType(m_Type); } var str = JsonConvert.SerializeObject(type, Formatting.Indented); File.WriteAllText(exportFullPath, str); @@ -373,8 +373,8 @@ namespace AssetStudioGUI var str = item.Asset.Dump(); if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour) { - var nodes = Studio.MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); - str = m_MonoBehaviour.Dump(nodes); + var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour); + str = m_MonoBehaviour.Dump(m_Type); } if (str != null) { diff --git a/AssetStudioGUI/Studio.cs b/AssetStudioGUI/Studio.cs index 04c0532..da208f2 100644 --- a/AssetStudioGUI/Studio.cs +++ b/AssetStudioGUI/Studio.cs @@ -341,27 +341,27 @@ namespace AssetStudioGUI { if (typeMap.TryGetValue(assetsFile.unityVersion, out var curVer)) { - foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null)) + foreach (var type in assetsFile.m_Types.Where(x => x.m_Type != null)) { var key = type.classID; if (type.m_ScriptTypeIndex >= 0) { key = -1 - type.m_ScriptTypeIndex; } - curVer[key] = new TypeTreeItem(key, type.m_Nodes); + curVer[key] = new TypeTreeItem(key, type.m_Type); } } else { var items = new SortedDictionary(); - foreach (var type in assetsFile.m_Types.Where(x => x.m_Nodes != null)) + foreach (var type in assetsFile.m_Types.Where(x => x.m_Type != null)) { var key = type.classID; if (type.m_ScriptTypeIndex >= 0) { key = -1 - type.m_ScriptTypeIndex; } - items[key] = new TypeTreeItem(key, type.m_Nodes); + items[key] = new TypeTreeItem(key, type.m_Type); } typeMap.Add(assetsFile.unityVersion, items); } @@ -680,7 +680,7 @@ namespace AssetStudioGUI } } - public static List MonoBehaviourToTypeTreeNodes(MonoBehaviour m_MonoBehaviour) + public static TypeTree MonoBehaviourToTypeTree(MonoBehaviour m_MonoBehaviour) { if (!assemblyLoader.Loaded) { @@ -695,7 +695,7 @@ namespace AssetStudioGUI assemblyLoader.Loaded = true; } } - return m_MonoBehaviour.ConvertToTypeTreeNodes(assemblyLoader); + return m_MonoBehaviour.ConvertToTypeTree(assemblyLoader); } public static string DumpAsset(Object obj) @@ -703,8 +703,8 @@ namespace AssetStudioGUI var str = obj.Dump(); if (str == null && obj is MonoBehaviour m_MonoBehaviour) { - var nodes = MonoBehaviourToTypeTreeNodes(m_MonoBehaviour); - str = m_MonoBehaviour.Dump(nodes); + var type = MonoBehaviourToTypeTree(m_MonoBehaviour); + str = m_MonoBehaviour.Dump(type); } return str; } diff --git a/AssetStudioUtility/MonoBehaviourConverter.cs b/AssetStudioUtility/MonoBehaviourConverter.cs index eb0b745..9365e12 100644 --- a/AssetStudioUtility/MonoBehaviourConverter.cs +++ b/AssetStudioUtility/MonoBehaviourConverter.cs @@ -4,21 +4,22 @@ namespace AssetStudio { public static class MonoBehaviourConverter { - public static List ConvertToTypeTreeNodes(this MonoBehaviour m_MonoBehaviour, AssemblyLoader assemblyLoader) + public static TypeTree ConvertToTypeTree(this MonoBehaviour m_MonoBehaviour, AssemblyLoader assemblyLoader) { - var nodes = new List(); + var m_Type = new TypeTree(); + m_Type.m_Nodes = new List(); var helper = new SerializedTypeHelper(m_MonoBehaviour.version); - helper.AddMonoBehaviour(nodes, 0); + helper.AddMonoBehaviour(m_Type.m_Nodes, 0); if (m_MonoBehaviour.m_Script.TryGet(out var m_Script)) { var typeDef = assemblyLoader.GetTypeDefinition(m_Script.m_AssemblyName, string.IsNullOrEmpty(m_Script.m_Namespace) ? m_Script.m_ClassName : $"{m_Script.m_Namespace}.{m_Script.m_ClassName}"); if (typeDef != null) { var typeDefinitionConverter = new TypeDefinitionConverter(typeDef, helper, 1); - nodes.AddRange(typeDefinitionConverter.ConvertToTypeTreeNodes()); + m_Type.m_Nodes.AddRange(typeDefinitionConverter.ConvertToTypeTreeNodes()); } } - return nodes; + return m_Type; } } }