diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs index 23ba74b..3884c21 100644 --- a/AssetStudio/AssetStudioForm.cs +++ b/AssetStudio/AssetStudioForm.cs @@ -377,7 +377,7 @@ namespace AssetStudio string saveFile = $"{versionPath}\\{uclass.Key} {uclass.Value.Text}.txt"; using (StreamWriter TXTwriter = new StreamWriter(saveFile)) { - TXTwriter.Write(uclass.Value.membersstr); + TXTwriter.Write(uclass.Value.ToString()); } } } @@ -694,7 +694,7 @@ namespace AssetStudio { if (e.IsSelected) { - classTextBox.Text = ((ClassStruct)classesListView.SelectedItems[0]).membersstr; + classTextBox.Text = ((ClassStruct)classesListView.SelectedItems[0]).ToString(); } } diff --git a/AssetStudio/Classes/Shader.cs b/AssetStudio/Classes/Shader.cs index a7f804f..8fe69c8 100644 --- a/AssetStudio/Classes/Shader.cs +++ b/AssetStudio/Classes/Shader.cs @@ -38,7 +38,7 @@ namespace AssetStudio reader.Position = preloadData.Offset; var sb = new StringBuilder(); var members = new JavaScriptSerializer().Deserialize>(str); - ClassStructHelper.ReadClassStruct(sb, members, reader); + ClassStructHelper.ReadClass(sb, members, reader); m_Script = Encoding.UTF8.GetBytes(sb.ToString()); //m_Script = ReadSerializedShader(members, a_Stream); } @@ -67,128 +67,5 @@ namespace AssetStudio preloadData.Text = m_Name; } } - - /*private static byte[] ReadSerializedShader(List members, EndianBinaryReader a_Stream) - { - var offsets = new List(); - var compressedLengths = new List(); - var decompressedLengths = new List(); - for (int i = 0; i < members.Count; i++) - { - var member = members[i]; - var level = member.Level; - var varTypeStr = member.Type; - if (member.Name == "offsets") - { - var offsets_size = a_Stream.ReadInt32(); - for (int j = 0; j < offsets_size; j++) - { - offsets.Add(a_Stream.ReadUInt32()); - } - var compressedLengths_size = a_Stream.ReadInt32(); - for (int j = 0; j < compressedLengths_size; j++) - { - compressedLengths.Add(a_Stream.ReadUInt32()); - } - var decompressedLengths_size = a_Stream.ReadInt32(); - for (int j = 0; j < decompressedLengths_size; j++) - { - decompressedLengths.Add(a_Stream.ReadUInt32()); - } - var compressedBlob = a_Stream.ReadBytes(a_Stream.ReadInt32()); - var decompressedStream = new MemoryStream(); - for (int j = 0; j < offsets.Count; j++) - { - var compressedBytes = new byte[compressedLengths[j]]; - Array.Copy(compressedBlob, offsets[j], compressedBytes, 0, compressedLengths[j]); - var decompressedBytes = new byte[decompressedLengths[j]]; - using (var mstream = new MemoryStream(compressedBytes)) - { - var decoder = new Lz4DecoderStream(mstream); - decoder.Read(decompressedBytes, 0, (int)decompressedLengths[j]); - decoder.Dispose(); - } - decompressedStream.Write(decompressedBytes, 0, decompressedBytes.Length); - } - var decompressedBlob = decompressedStream.ToArray(); - return decompressedBlob; - } - var align = (member.Flag & 0x4000) != 0; - if (member.alignBefore) - a_Stream.AlignStream(4); - if (varTypeStr == "SInt8")//sbyte - { - a_Stream.ReadSByte(); - } - else if (varTypeStr == "UInt8")//byte - { - a_Stream.ReadByte(); - } - else if (varTypeStr == "short" || varTypeStr == "SInt16")//Int16 - { - a_Stream.ReadInt16(); - } - else if (varTypeStr == "UInt16" || varTypeStr == "unsigned short")//UInt16 - { - a_Stream.ReadUInt16(); - } - else if (varTypeStr == "int" || varTypeStr == "SInt32")//Int32 - { - a_Stream.ReadInt32(); - } - else if (varTypeStr == "UInt32" || varTypeStr == "unsigned int" || varTypeStr == "Type*")//UInt32 - { - a_Stream.ReadUInt32(); - } - else if (varTypeStr == "long long" || varTypeStr == "SInt64")//Int64 - { - a_Stream.ReadInt64(); - } - else if (varTypeStr == "UInt64" || varTypeStr == "unsigned long long")//UInt64 - { - a_Stream.ReadUInt64(); - } - else if (varTypeStr == "float")//float - { - a_Stream.ReadSingle(); - } - else if (varTypeStr == "double")//double - { - a_Stream.ReadDouble(); - } - else if (varTypeStr == "bool")//bool - { - a_Stream.ReadBoolean(); - } - else if (varTypeStr == "string")//string - { - a_Stream.ReadAlignedString(a_Stream.ReadInt32()); - i += 3;//skip - } - else if (varTypeStr == "Array")//Array - { - if ((members[i - 1].Flag & 0x4000) != 0) - align = true; - var size = a_Stream.ReadInt32(); - var array = ClassStructHelper.ReadArray(members, level, i); - for (int j = 0; j < size; j++) - { - ReadSerializedShader(array, a_Stream); - } - i += array.Count + 1;//skip - } - else - { - if (align) - { - align = false; - ClassStructHelper.SetAlignBefore(members, level, i + 1); - } - } - if (align) - a_Stream.AlignStream(4); - } - return null; - }*/ } } diff --git a/AssetStudio/StudioClasses/ClassStruct.cs b/AssetStudio/StudioClasses/ClassStruct.cs index 47f2d5e..cf82855 100644 --- a/AssetStudio/StudioClasses/ClassStruct.cs +++ b/AssetStudio/StudioClasses/ClassStruct.cs @@ -13,9 +13,6 @@ namespace AssetStudio public string Name; public int Size; public int Flag; - - //use for read - public bool alignBefore; } public class ClassStruct : ListViewItem @@ -23,17 +20,14 @@ namespace AssetStudio public int ID; public List members; - public string membersstr + public override string ToString() { - get + var sb = new StringBuilder(); + foreach (var i in members) { - var sb = new StringBuilder(); - foreach (var i in members) - { - sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.Level), i.Type, i.Name, i.Size, (i.Flag & 0x4000) != 0); - } - return sb.ToString(); + sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.Level), i.Type, i.Name, i.Size, (i.Flag & 0x4000) != 0); } + return sb.ToString(); } } @@ -45,121 +39,158 @@ namespace AssetStudio if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure)) { var sb = new StringBuilder(); - ReadClassStruct(sb, classStructure.members, reader); + ReadClass(sb, classStructure.members, reader); return sb.ToString(); } return null; } - public static void ReadClassStruct(StringBuilder sb, List members, EndianBinaryReader reader) + public static void ReadClass(StringBuilder sb, List members, EndianBinaryReader reader) { for (int i = 0; i < members.Count; i++) { - var member = members[i]; - var level = member.Level; - var varTypeStr = member.Type; - var varNameStr = member.Name; - object value = null; - var align = (member.Flag & 0x4000) != 0; - var append = true; - if (member.alignBefore) - reader.AlignStream(4); - 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 "Array": - { - append = false; - if ((members[i - 1].Flag & 0x4000) != 0) - align = true; - sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); - var size = reader.ReadInt32(); - sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), "int", "size", size); - var array = ReadArray(members, level, i); - for (int j = 0; j < size; j++) - { - sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 1)), j); - ReadClassStruct(sb, array, reader); - } - i += array.Count + 1;//skip - 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; - if (align) - { - align = false; - SetAlignBefore(members, level, i + 1); - } - sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); - break; - } - if (append) - sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); - if (align) - reader.AlignStream(4); + ReadValue(sb, members, reader, ref i); } } - public static List ReadArray(List members, int level, int index) + 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(); - for (int i = index + 2; i < members.Count; i++)//skip int size + member2.Add(members[0]); + for (int i = index + 1; i < members.Count; i++) { var member = members[i]; var level2 = member.Level; @@ -171,19 +202,5 @@ namespace AssetStudio } return member2; } - - public static void SetAlignBefore(List members, int level, int index) - { - for (int i = index; i < members.Count; i++) - { - var member = members[i]; - var level2 = member.Level; - if (level2 <= level) - { - member.alignBefore = true; - return; - } - } - } } }