mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-27 22:00:23 -04:00
change structure read logic
This commit is contained in:
parent
79af119cf4
commit
71c633b506
@ -377,7 +377,7 @@ namespace AssetStudio
|
|||||||
string saveFile = $"{versionPath}\\{uclass.Key} {uclass.Value.Text}.txt";
|
string saveFile = $"{versionPath}\\{uclass.Key} {uclass.Value.Text}.txt";
|
||||||
using (StreamWriter TXTwriter = new StreamWriter(saveFile))
|
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)
|
if (e.IsSelected)
|
||||||
{
|
{
|
||||||
classTextBox.Text = ((ClassStruct)classesListView.SelectedItems[0]).membersstr;
|
classTextBox.Text = ((ClassStruct)classesListView.SelectedItems[0]).ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ namespace AssetStudio
|
|||||||
reader.Position = preloadData.Offset;
|
reader.Position = preloadData.Offset;
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var members = new JavaScriptSerializer().Deserialize<List<ClassMember>>(str);
|
var members = new JavaScriptSerializer().Deserialize<List<ClassMember>>(str);
|
||||||
ClassStructHelper.ReadClassStruct(sb, members, reader);
|
ClassStructHelper.ReadClass(sb, members, reader);
|
||||||
m_Script = Encoding.UTF8.GetBytes(sb.ToString());
|
m_Script = Encoding.UTF8.GetBytes(sb.ToString());
|
||||||
//m_Script = ReadSerializedShader(members, a_Stream);
|
//m_Script = ReadSerializedShader(members, a_Stream);
|
||||||
}
|
}
|
||||||
@ -67,128 +67,5 @@ namespace AssetStudio
|
|||||||
preloadData.Text = m_Name;
|
preloadData.Text = m_Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private static byte[] ReadSerializedShader(List<ClassMember> members, EndianBinaryReader a_Stream)
|
|
||||||
{
|
|
||||||
var offsets = new List<uint>();
|
|
||||||
var compressedLengths = new List<uint>();
|
|
||||||
var decompressedLengths = new List<uint>();
|
|
||||||
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;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,6 @@ namespace AssetStudio
|
|||||||
public string Name;
|
public string Name;
|
||||||
public int Size;
|
public int Size;
|
||||||
public int Flag;
|
public int Flag;
|
||||||
|
|
||||||
//use for read
|
|
||||||
public bool alignBefore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClassStruct : ListViewItem
|
public class ClassStruct : ListViewItem
|
||||||
@ -23,17 +20,14 @@ namespace AssetStudio
|
|||||||
public int ID;
|
public int ID;
|
||||||
public List<ClassMember> members;
|
public List<ClassMember> members;
|
||||||
|
|
||||||
public string membersstr
|
public override string ToString()
|
||||||
{
|
{
|
||||||
get
|
var sb = new StringBuilder();
|
||||||
|
foreach (var i in members)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.Level), i.Type, i.Name, i.Size, (i.Flag & 0x4000) != 0);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,121 +39,158 @@ namespace AssetStudio
|
|||||||
if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure))
|
if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure))
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
ReadClassStruct(sb, classStructure.members, reader);
|
ReadClass(sb, classStructure.members, reader);
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ReadClassStruct(StringBuilder sb, List<ClassMember> members, EndianBinaryReader reader)
|
public static void ReadClass(StringBuilder sb, List<ClassMember> members, EndianBinaryReader reader)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < members.Count; i++)
|
for (int i = 0; i < members.Count; i++)
|
||||||
{
|
{
|
||||||
var member = members[i];
|
ReadValue(sb, members, reader, ref 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ClassMember> ReadArray(List<ClassMember> members, int level, int index)
|
public static void ReadValue(StringBuilder sb, List<ClassMember> 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<ClassMember> GetMembers(List<ClassMember> members, int level, int index)
|
||||||
{
|
{
|
||||||
var member2 = new List<ClassMember>();
|
var member2 = new List<ClassMember>();
|
||||||
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 member = members[i];
|
||||||
var level2 = member.Level;
|
var level2 = member.Level;
|
||||||
@ -171,19 +202,5 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
return member2;
|
return member2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetAlignBefore(List<ClassMember> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user