diff --git a/AssetStudio/AssetStudio-x86.csproj b/AssetStudio/AssetStudio-x86.csproj index 3840483..1174731 100644 --- a/AssetStudio/AssetStudio-x86.csproj +++ b/AssetStudio/AssetStudio-x86.csproj @@ -163,7 +163,9 @@ + + diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj index c566505..f826d37 100644 --- a/AssetStudio/AssetStudio.csproj +++ b/AssetStudio/AssetStudio.csproj @@ -150,6 +150,8 @@ + + True True diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs index 3884c21..36bb0b6 100644 --- a/AssetStudio/AssetStudioForm.cs +++ b/AssetStudio/AssetStudioForm.cs @@ -1013,7 +1013,7 @@ namespace AssetStudio } default: { - var str = asset.ViewStruct(); + var str = asset.Deserialize(); if (str != null) { textPreviewBox.Text = str; diff --git a/AssetStudio/Classes/MonoBehaviour.cs b/AssetStudio/Classes/MonoBehaviour.cs index a575fef..2a05431 100644 --- a/AssetStudio/Classes/MonoBehaviour.cs +++ b/AssetStudio/Classes/MonoBehaviour.cs @@ -21,7 +21,7 @@ namespace AssetStudio var m_Name = reader.ReadAlignedString(); if (readSwitch) { - if ((serializedText = preloadData.ViewStruct()) == null) + if ((serializedText = preloadData.Deserialize()) == null) { var str = "PPtr m_GameObject\r\n"; str += "\tint m_FileID = " + m_GameObject.m_FileID + "\r\n"; diff --git a/AssetStudio/Classes/Shader.cs b/AssetStudio/Classes/Shader.cs index 8fe69c8..055eadc 100644 --- a/AssetStudio/Classes/Shader.cs +++ b/AssetStudio/Classes/Shader.cs @@ -27,7 +27,7 @@ namespace AssetStudio var str = (string)ShaderResource.ResourceManager.GetObject($"Shader{sourceFile.version[0]}{sourceFile.version[1]}"); if (str == null) { - str = preloadData.ViewStruct(); + str = preloadData.Deserialize(); if (str == null) m_Script = Encoding.UTF8.GetBytes("Serialized Shader can't be read"); else @@ -38,9 +38,8 @@ namespace AssetStudio reader.Position = preloadData.Offset; var sb = new StringBuilder(); var members = new JavaScriptSerializer().Deserialize>(str); - ClassStructHelper.ReadClass(sb, members, reader); + ClassStructHelper.ReadClassString(sb, members, reader); m_Script = Encoding.UTF8.GetBytes(sb.ToString()); - //m_Script = ReadSerializedShader(members, a_Stream); } } else diff --git a/AssetStudio/StudioClasses/AssetPreloadData.cs b/AssetStudio/StudioClasses/AssetPreloadData.cs index c5e4db8..8fc885f 100644 --- a/AssetStudio/StudioClasses/AssetPreloadData.cs +++ b/AssetStudio/StudioClasses/AssetPreloadData.cs @@ -30,5 +30,17 @@ namespace AssetStudio reader.Position = Offset; return reader; } + + public string Deserialize() + { + var reader = InitReader(); + if (sourceFile.ClassStructures.TryGetValue(Type1, out var classStructure)) + { + var sb = new StringBuilder(); + ClassStructHelper.ReadClassString(sb, classStructure.members, reader); + return sb.ToString(); + } + return null; + } } } diff --git a/AssetStudio/StudioClasses/ClassMember.cs b/AssetStudio/StudioClasses/ClassMember.cs new file mode 100644 index 0000000..a3bf248 --- /dev/null +++ b/AssetStudio/StudioClasses/ClassMember.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + public class ClassMember + { + public int Level; + public string Type; + public string Name; + public int Size; + public int Flag; + } +} diff --git a/AssetStudio/StudioClasses/ClassStruct.cs b/AssetStudio/StudioClasses/ClassStruct.cs index cf82855..38d5cab 100644 --- a/AssetStudio/StudioClasses/ClassStruct.cs +++ b/AssetStudio/StudioClasses/ClassStruct.cs @@ -6,15 +6,6 @@ using System.Windows.Forms; namespace AssetStudio { - public class ClassMember - { - public int Level; - public string Type; - public string Name; - public int Size; - public int Flag; - } - public class ClassStruct : ListViewItem { public int ID; @@ -30,177 +21,4 @@ namespace AssetStudio return sb.ToString(); } } - - public static class ClassStructHelper - { - public static string ViewStruct(this AssetPreloadData asset) - { - var reader = asset.InitReader(); - if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure)) - { - var sb = new StringBuilder(); - ReadClass(sb, classStructure.members, reader); - return sb.ToString(); - } - return null; - } - - public static void ReadClass(StringBuilder sb, List members, EndianBinaryReader reader) - { - for (int i = 0; i < members.Count; i++) - { - ReadValue(sb, members, reader, ref i); - } - } - - public static void ReadValue(StringBuilder sb, List members, EndianBinaryReader reader, ref int i) - { - var member = members[i]; - var level = member.Level; - var varTypeStr = member.Type; - var varNameStr = member.Name; - object value = null; - var append = true; - var align = (member.Flag & 0x4000) != 0; - switch (varTypeStr) - { - case "SInt8": - value = reader.ReadSByte(); - break; - case "UInt8": - value = reader.ReadByte(); - break; - case "short": - case "SInt16": - value = reader.ReadInt16(); - break; - case "UInt16": - case "unsigned short": - value = reader.ReadUInt16(); - break; - case "int": - case "SInt32": - value = reader.ReadInt32(); - break; - case "UInt32": - case "unsigned int": - case "Type*": - value = reader.ReadUInt32(); - break; - case "long long": - case "SInt64": - value = reader.ReadInt64(); - break; - case "UInt64": - case "unsigned long long": - value = reader.ReadUInt64(); - break; - case "float": - value = reader.ReadSingle(); - break; - case "double": - value = reader.ReadDouble(); - break; - case "bool": - value = reader.ReadBoolean(); - break; - case "string": - append = false; - var str = reader.ReadAlignedString(); - sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str); - i += 3;//skip - break; - case "vector": - { - if ((members[i + 1].Flag & 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, level, i); - i += vector.Count - 1; - vector.RemoveRange(0, 3); - for (int j = 0; j < size; j++) - { - sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j); - int tmp = 0; - ReadValue(sb, vector, reader, ref tmp); - } - break; - } - case "map": - { - if ((members[i + 1].Flag & 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, level, i); - i += map.Count - 1; - map.RemoveRange(0, 4); - var first = GetMembers(map, map[0].Level, 0); - map.RemoveRange(0, first.Count); - var second = map; - for (int j = 0; j < size; j++) - { - sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j); - sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 2)), "pair", "data"); - int tmp1 = 0; - int tmp2 = 0; - ReadValue(sb, first, reader, ref tmp1); - ReadValue(sb, second, reader, ref tmp2); - } - break; - } - case "TypelessData": - { - append = false; - var size = reader.ReadInt32(); - reader.ReadBytes(size); - i += 2; - sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); - sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), "int", "size", size); - break; - } - default: - { - append = false; - sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); - var @class = GetMembers(members, level, i); - @class.RemoveAt(0); - i += @class.Count; - for (int j = 0; j < @class.Count; j++) - { - ReadValue(sb, @class, reader, ref j); - } - break; - } - } - if (append) - sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); - if (align) - reader.AlignStream(4); - } - - public static List GetMembers(List members, int level, int index) - { - var member2 = new List(); - member2.Add(members[0]); - for (int i = index + 1; i < members.Count; i++) - { - var member = members[i]; - var level2 = member.Level; - if (level2 <= level) - { - return member2; - } - member2.Add(member); - } - return member2; - } - } } diff --git a/AssetStudio/StudioClasses/ClassStructHelper.cs b/AssetStudio/StudioClasses/ClassStructHelper.cs new file mode 100644 index 0000000..0865ea1 --- /dev/null +++ b/AssetStudio/StudioClasses/ClassStructHelper.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + public static class ClassStructHelper + { + public static void ReadClassString(StringBuilder sb, List members, EndianBinaryReader reader) + { + for (int i = 0; i < members.Count; i++) + { + ReadStringValue(sb, members, reader, ref i); + } + } + + private static void ReadStringValue(StringBuilder sb, List members, EndianBinaryReader reader, ref int i) + { + var member = members[i]; + var level = member.Level; + var varTypeStr = member.Type; + var varNameStr = member.Name; + object value = null; + var append = true; + var align = (member.Flag & 0x4000) != 0; + switch (varTypeStr) + { + case "SInt8": + value = reader.ReadSByte(); + break; + case "UInt8": + value = reader.ReadByte(); + break; + case "short": + case "SInt16": + value = reader.ReadInt16(); + break; + case "UInt16": + case "unsigned short": + value = reader.ReadUInt16(); + break; + case "int": + case "SInt32": + value = reader.ReadInt32(); + break; + case "UInt32": + case "unsigned int": + case "Type*": + value = reader.ReadUInt32(); + break; + case "long long": + case "SInt64": + value = reader.ReadInt64(); + break; + case "UInt64": + case "unsigned long long": + value = reader.ReadUInt64(); + break; + case "float": + value = reader.ReadSingle(); + break; + case "double": + value = reader.ReadDouble(); + break; + case "bool": + value = reader.ReadBoolean(); + break; + case "string": + append = false; + var str = reader.ReadAlignedString(); + sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str); + i += 3;//skip + break; + case "vector": + { + if ((members[i + 1].Flag & 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, level, i); + i += vector.Count - 1; + vector.RemoveRange(0, 3); + for (int j = 0; j < size; j++) + { + sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j); + int tmp = 0; + ReadStringValue(sb, vector, reader, ref tmp); + } + break; + } + case "map": + { + if ((members[i + 1].Flag & 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, level, i); + i += map.Count - 1; + map.RemoveRange(0, 4); + var first = GetMembers(map, map[0].Level, 0); + map.RemoveRange(0, first.Count); + var second = map; + for (int j = 0; j < size; j++) + { + sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j); + sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 2)), "pair", "data"); + int tmp1 = 0; + int tmp2 = 0; + ReadStringValue(sb, first, reader, ref tmp1); + ReadStringValue(sb, second, reader, ref tmp2); + } + break; + } + case "TypelessData": + { + append = false; + var size = reader.ReadInt32(); + reader.ReadBytes(size); + i += 2; + sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), "int", "size", size); + break; + } + default: + { + append = false; + sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); + var @class = GetMembers(members, level, i); + @class.RemoveAt(0); + i += @class.Count; + for (int j = 0; j < @class.Count; j++) + { + ReadStringValue(sb, @class, reader, ref j); + } + break; + } + } + if (append) + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + if (align) + reader.AlignStream(4); + } + + public static List GetMembers(List members, int level, int index) + { + var member2 = new List(); + member2.Add(members[0]); + for (int i = index + 1; i < members.Count; i++) + { + var member = members[i]; + var level2 = member.Level; + if (level2 <= level) + { + return member2; + } + member2.Add(member); + } + return member2; + } + } +}