using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace Unity_Studio { public class ClassMember { public int Level; public string Type; public string Name; public int Size; public int Flag; //use for read public bool alignBefore; } public class ClassStruct : ListViewItem { public int ID; public List members; public string membersstr { get { 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(); } } } public static class ClassStructHelper { public static string ViewStruct(this AssetPreloadData asset) { var a_Stream = asset.sourceFile.a_Stream; a_Stream.Position = asset.Offset; if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure)) { var sb = new StringBuilder(); ReadClassStruct(sb, classStructure.members, a_Stream); return sb.ToString(); } return null; } public static void ReadClassStruct(StringBuilder sb, List members, EndianBinaryReader a_Stream) { 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) a_Stream.AlignStream(4); if (varTypeStr == "SInt8")//sbyte { value = a_Stream.ReadSByte(); } else if (varTypeStr == "UInt8")//byte { value = a_Stream.ReadByte(); } else if (varTypeStr == "short" || varTypeStr == "SInt16")//Int16 { value = a_Stream.ReadInt16(); } else if (varTypeStr == "UInt16" || varTypeStr == "unsigned short")//UInt16 { value = a_Stream.ReadUInt16(); } else if (varTypeStr == "int" || varTypeStr == "SInt32")//Int32 { value = a_Stream.ReadInt32(); } else if (varTypeStr == "UInt32" || varTypeStr == "unsigned int" || varTypeStr == "Type*")//UInt32 { value = a_Stream.ReadUInt32(); } else if (varTypeStr == "long long" || varTypeStr == "SInt64")//Int64 { value = a_Stream.ReadInt64(); } else if (varTypeStr == "UInt64" || varTypeStr == "unsigned long long")//UInt64 { value = a_Stream.ReadUInt64(); } else if (varTypeStr == "float")//float { value = a_Stream.ReadSingle(); } else if (varTypeStr == "double")//double { value = a_Stream.ReadDouble(); } else if (varTypeStr == "bool")//bool { value = a_Stream.ReadBoolean(); } else if (varTypeStr == "string")//string { append = false; var str = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str); i += 3;//skip } else if (varTypeStr == "Array")//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 = a_Stream.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, a_Stream); } i += array.Count + 1;//skip } else if (varTypeStr == "TypelessData") { append = false; var size = a_Stream.ReadInt32(); a_Stream.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); } else { append = false; if (align) { align = false; SetAlignBefore(members, level, i + 1); } sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); } if (append) sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); if (align) a_Stream.AlignStream(4); } } public static List ReadArray(List members, int level, int index) { var member2 = new List(); for (int i = index + 2; i < members.Count; i++)//skip int size { var member = members[i]; var level2 = member.Level; if (level2 <= level) { return member2; } member2.Add(member); } 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; } } } } }