diff --git a/AssetStudio/AssetStudio-x86.csproj b/AssetStudio/AssetStudio-x86.csproj index 1e855c2..322c814 100644 --- a/AssetStudio/AssetStudio-x86.csproj +++ b/AssetStudio/AssetStudio-x86.csproj @@ -183,9 +183,6 @@ - - - @@ -231,6 +228,9 @@ + + + diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj index 3e82c25..cef5687 100644 --- a/AssetStudio/AssetStudio.csproj +++ b/AssetStudio/AssetStudio.csproj @@ -174,8 +174,8 @@ - - + + @@ -186,7 +186,7 @@ - + diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs index 0fbb688..f246ef7 100644 --- a/AssetStudio/AssetStudioForm.cs +++ b/AssetStudio/AssetStudioForm.cs @@ -178,11 +178,11 @@ namespace AssetStudio { if (!string.IsNullOrEmpty(productName)) { - Text = $"AssetStudio - {productName} - {assetsfileList[0].m_Version} - {assetsfileList[0].platformStr}"; + Text = $"AssetStudio - {productName} - {assetsfileList[0].unityVersion} - {assetsfileList[0].platformStr}"; } else if (assetsfileList.Count > 0) { - Text = $"AssetStudio - no productName - {assetsfileList[0].m_Version} - {assetsfileList[0].platformStr}"; + Text = $"AssetStudio - no productName - {assetsfileList[0].unityVersion} - {assetsfileList[0].platformStr}"; } if (!dontLoadAssetsMenuItem.Checked) { @@ -203,7 +203,7 @@ namespace AssetStudio if (buildClassStructuresMenuItem.Checked) { classesListView.BeginUpdate(); - foreach (var version in AllClassStructures) + foreach (var version in AllTypeMap) { ListViewGroup versionGroup = new ListViewGroup(version.Key); classesListView.Groups.Add(versionGroup); @@ -311,16 +311,16 @@ namespace AssetStudio private void exportClassStructuresMenuItem_Click(object sender, EventArgs e) { - if (AllClassStructures.Count > 0) + if (AllTypeMap.Count > 0) { var saveFolderDialog1 = new OpenFolderDialog(); if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK) { progressBar1.Value = 0; - progressBar1.Maximum = AllClassStructures.Count; + progressBar1.Maximum = AllTypeMap.Count; var savePath = saveFolderDialog1.Folder; - foreach (var version in AllClassStructures) + foreach (var version in AllTypeMap) { if (version.Value.Count > 0) { @@ -646,7 +646,7 @@ namespace AssetStudio { if (e.IsSelected) { - classTextBox.Text = ((ClassStruct)classesListView.SelectedItems[0]).ToString(); + classTextBox.Text = ((TypeItem)classesListView.SelectedItems[0]).ToString(); } } @@ -836,7 +836,7 @@ namespace AssetStudio case ClassIDReference.MonoBehaviour: { var m_MonoBehaviour = new MonoBehaviour(asset); - if (asset.Type1 != asset.Type2 && asset.sourceFile.ClassStructures.ContainsKey(asset.Type1)) + if (asset.Type1 != asset.Type2 && asset.sourceFile.m_Type.ContainsKey(asset.Type1)) { textPreviewBox.Text = asset.Dump(); } diff --git a/AssetStudio/Classes/Mesh.cs b/AssetStudio/Classes/Mesh.cs index e3583c1..548bb3a 100644 --- a/AssetStudio/Classes/Mesh.cs +++ b/AssetStudio/Classes/Mesh.cs @@ -595,7 +595,7 @@ namespace AssetStudio } } - if (preloadData.sourceFile.platform == 11 && componentByteSize > 1) //swap bytes for Xbox + if (preloadData.sourceFile.m_TargetPlatform == BuildTarget.XBOX360 && componentByteSize > 1) //swap bytes for Xbox { for (var i = 0; i < componentBytes.Length / componentByteSize; i++) { @@ -704,7 +704,7 @@ namespace AssetStudio } } - if (preloadData.sourceFile.platform == 11 && componentByteSize > 1) //swap bytes for Xbox + if (preloadData.sourceFile.m_TargetPlatform == BuildTarget.XBOX360 && componentByteSize > 1) //swap bytes for Xbox { for (var i = 0; i < componentBytes.Length / componentByteSize; i++) { diff --git a/AssetStudio/Classes/Object.cs b/AssetStudio/Classes/Object.cs index adf73fa..b87226e 100644 --- a/AssetStudio/Classes/Object.cs +++ b/AssetStudio/Classes/Object.cs @@ -21,7 +21,7 @@ namespace AssetStudio reader = preloadData.InitReader(); version = sourceFile.version; buildType = sourceFile.buildType; - platform = (BuildTarget)sourceFile.platform; + platform = sourceFile.m_TargetPlatform; if (platform == BuildTarget.NoTarget) { diff --git a/AssetStudio/StudioClasses/AssetPreloadData.cs b/AssetStudio/StudioClasses/AssetPreloadData.cs index cca5c51..78f5018 100644 --- a/AssetStudio/StudioClasses/AssetPreloadData.cs +++ b/AssetStudio/StudioClasses/AssetPreloadData.cs @@ -33,10 +33,10 @@ namespace AssetStudio public string Dump() { var reader = InitReader(); - if (sourceFile.ClassStructures.TryGetValue(Type1, out var classStructure)) + if (sourceFile.m_Type.TryGetValue(Type1, out var typeTreeList)) { var sb = new StringBuilder(); - ClassStructHelper.ReadClassString(sb, classStructure.members, reader); + TypeTreeHelper.ReadTypeString(sb, typeTreeList, reader); return sb.ToString(); } return null; @@ -44,7 +44,7 @@ namespace AssetStudio public bool HasStructMember(string name) { - return sourceFile.ClassStructures.TryGetValue(Type1, out var classStructure) && classStructure.members.Any(x => x.Name == name); + return sourceFile.m_Type.TryGetValue(Type1, out var typeTreeList) && typeTreeList.Any(x => x.m_Name == name); } } } diff --git a/AssetStudio/StudioClasses/AssetsFile.cs b/AssetStudio/StudioClasses/AssetsFile.cs index be000ea..1014dca 100644 --- a/AssetStudio/StudioClasses/AssetsFile.cs +++ b/AssetStudio/StudioClasses/AssetsFile.cs @@ -8,20 +8,35 @@ using System.Windows.Forms; namespace AssetStudio { + public class SerializedFileHeader + { + public uint m_MetadataSize; + public uint m_FileSize; + public uint m_Version; + public uint m_DataOffset; + public byte m_Endianess; + public byte[] m_Reserved; + } + public class AssetsFile { public EndianBinaryReader reader; + public SerializedFileHeader header; + private EndianType m_FileEndianess; + public string unityVersion = "2.5.0f5"; + public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform; + private bool serializedTypeTrees; + public SortedDictionary> m_Type = new SortedDictionary>(); + private List classIDs = new List();//use for 5.5.0 + public string filePath; public string parentPath; public string fileName; public string upperFileName; - public int fileGen; - public bool valid; - public string m_Version = "2.5.0f5"; public int[] version = { 0, 0, 0, 0 }; public string[] buildType; - public int platform = 100663296; public string platformStr = ""; + public Dictionary preloadTable = new Dictionary(); public Dictionary GameObjectList = new Dictionary(); public Dictionary TransformList = new Dictionary(); @@ -29,11 +44,7 @@ namespace AssetStudio public List exportableAssets = new List(); public List sharedAssetsList = new List { new SharedAssets() }; - public SortedDictionary ClassStructures = new SortedDictionary(); - - private bool baseDefinitions; - private List classIDs = new List();//use for 5.5.0 - + public bool valid; #region cmmon string private static Dictionary baseStrings = new Dictionary @@ -157,140 +168,103 @@ namespace AssetStudio upperFileName = fileName.ToUpper(); try { - int tableSize = this.reader.ReadInt32(); - int dataEnd = this.reader.ReadInt32(); - fileGen = this.reader.ReadInt32(); - uint dataOffset = this.reader.ReadUInt32(); - sharedAssetsList[0].fileName = fileName; //reference itself because sharedFileIDs start from 1 + //SerializedFile::ReadHeader + header = new SerializedFileHeader(); + header.m_MetadataSize = reader.ReadUInt32(); + header.m_FileSize = reader.ReadUInt32(); + header.m_Version = reader.ReadUInt32(); + header.m_DataOffset = reader.ReadUInt32(); - switch (fileGen) + if (header.m_Version >= 9) { - case 6: //2.5.0 - 2.6.1 - { - this.reader.Position = (dataEnd - tableSize); - this.reader.Position += 1; - break; - } - case 7: //3.0.0 beta - { - this.reader.Position = (dataEnd - tableSize); - this.reader.Position += 1; - m_Version = this.reader.ReadStringToNull(); - break; - } - case 8: //3.0.0 - 3.4.2 - { - this.reader.Position = (dataEnd - tableSize); - this.reader.Position += 1; - m_Version = this.reader.ReadStringToNull(); - platform = this.reader.ReadInt32(); - break; - } - case 9: //3.5.0 - 4.6.x - { - this.reader.Position += 4; //azero - m_Version = this.reader.ReadStringToNull(); - platform = this.reader.ReadInt32(); - break; - } - case 14: //5.0.0 beta and final - case 15: //5.0.1 - 5.4 - case 16: //??.. no sure - case 17: //5.5.0 and up - { - this.reader.Position += 4; //azero - m_Version = this.reader.ReadStringToNull(); - platform = this.reader.ReadInt32(); - baseDefinitions = this.reader.ReadBoolean(); - break; - } - default: - { - //MessageBox.Show("Unsupported version!" + fileGen, "AssetStudio Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } + header.m_Endianess = reader.ReadByte(); + header.m_Reserved = reader.ReadBytes(3); + m_FileEndianess = (EndianType)header.m_Endianess; + } + else + { + reader.Position = header.m_FileSize - header.m_MetadataSize; + m_FileEndianess = (EndianType)reader.ReadByte(); } - if (fileGen > 6 && m_Version == "") + //SerializedFile::ReadMetadata + if (m_FileEndianess == EndianType.LittleEndian) { - return; + reader.endian = EndianType.LittleEndian; } - - if (platform > 255 || platform < 0) + if (header.m_Version >= 7) { - byte[] b32 = BitConverter.GetBytes(platform); - Array.Reverse(b32); - platform = BitConverter.ToInt32(b32, 0); - this.reader.endian = EndianType.LittleEndian; + unityVersion = reader.ReadStringToNull(); } - - platformStr = Enum.IsDefined(typeof(BuildTarget), platform) ? ((BuildTarget)platform).ToString() : "Unknown Platform"; - - int baseCount = this.reader.ReadInt32(); - for (int i = 0; i < baseCount; i++) + if (header.m_Version >= 8) { - if (fileGen < 14) + m_TargetPlatform = (BuildTarget)reader.ReadInt32(); + if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform)) { - int classID = this.reader.ReadInt32(); - string baseType = this.reader.ReadStringToNull(); - string baseName = this.reader.ReadStringToNull(); - this.reader.Position += 20; - int memberCount = this.reader.ReadInt32(); + m_TargetPlatform = BuildTarget.UnknownPlatform; + } + } + platformStr = m_TargetPlatform.ToString(); + if (header.m_Version >= 14) + { + serializedTypeTrees = reader.ReadBoolean(); + } - var cb = new List(); - for (int m = 0; m < memberCount; m++) - { - readBase(cb, 1); - } - - var aClass = new ClassStruct { ID = classID, Text = (baseType + " " + baseName), members = cb }; - aClass.SubItems.Add(classID.ToString()); - ClassStructures.Add(classID, aClass); + // Read types + int typeCount = reader.ReadInt32(); + for (int i = 0; i < typeCount; i++) + { + if (header.m_Version < 14) + { + int classID = reader.ReadInt32(); + var typeTreeList = new List(); + ReadTypeTree(typeTreeList, 0); + m_Type.Add(classID, typeTreeList); } else { - readBase5(); + ReadTypeTree5(); } } - if (fileGen >= 7 && fileGen < 14) + if (header.m_Version >= 7 && header.m_Version < 14) { - this.reader.Position += 4; //azero + var bigIDEnabled = reader.ReadInt32(); } - int assetCount = this.reader.ReadInt32(); + // Read Objects + int objectCount = reader.ReadInt32(); - #region asset preload table - string assetIDfmt = "D" + assetCount.ToString().Length; //format for unique ID + string assetIDfmt = "D" + objectCount.ToString().Length; //format for unique ID - for (int i = 0; i < assetCount; i++) + for (int i = 0; i < objectCount; i++) { //each table entry is aligned individually, not the whole table - if (fileGen >= 14) + if (header.m_Version >= 14) { - this.reader.AlignStream(4); + reader.AlignStream(4); } AssetPreloadData asset = new AssetPreloadData(); - asset.m_PathID = fileGen < 14 ? this.reader.ReadInt32() : this.reader.ReadInt64(); - asset.Offset = this.reader.ReadUInt32(); - asset.Offset += dataOffset; - asset.Size = this.reader.ReadInt32(); - if (fileGen > 15) + asset.m_PathID = header.m_Version < 14 ? reader.ReadInt32() : reader.ReadInt64(); + asset.Offset = reader.ReadUInt32(); + asset.Offset += header.m_DataOffset; + asset.Size = reader.ReadInt32(); + if (header.m_Version > 15) { - int index = this.reader.ReadInt32(); + int index = reader.ReadInt32(); asset.Type1 = classIDs[index][0]; asset.Type2 = classIDs[index][1]; } else { - asset.Type1 = this.reader.ReadInt32(); - asset.Type2 = this.reader.ReadUInt16(); - this.reader.Position += 2; + asset.Type1 = reader.ReadInt32(); + asset.Type2 = reader.ReadUInt16(); + reader.Position += 2; } - if (fileGen == 15) + if (header.m_Version == 15) { - byte unknownByte = this.reader.ReadByte(); + byte unknownByte = reader.ReadByte(); //this is a single byte, not an int32 //the next entry is aligned after this //but not the last! @@ -315,22 +289,45 @@ namespace AssetStudio preloadTable.Add(asset.m_PathID, asset); #region read BuildSettings to get version for version 2.x files - if (asset.Type == ClassIDReference.BuildSettings && fileGen == 6) + if (asset.Type == ClassIDReference.BuildSettings && header.m_Version == 6) { - long nextAsset = this.reader.Position; + long nextAsset = reader.Position; BuildSettings BSettings = new BuildSettings(asset); - m_Version = BSettings.m_Version; + unityVersion = BSettings.m_Version; - this.reader.Position = nextAsset; + reader.Position = nextAsset; } #endregion } - #endregion - buildType = Regex.Replace(m_Version, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries); - var firstVersion = int.Parse(m_Version.Split('.')[0]); - version = Regex.Matches(m_Version, @"\d").Cast().Select(m => int.Parse(m.Value)).ToArray(); + if (header.m_Version >= 14) + { + //this looks like a list of assets that need to be preloaded in memory before anytihng else + int someCount = reader.ReadInt32(); + for (int i = 0; i < someCount; i++) + { + int num1 = reader.ReadInt32(); + reader.AlignStream(4); + long m_PathID = reader.ReadInt64(); + } + } + + sharedAssetsList[0].fileName = fileName; //reference itself because sharedFileIDs start from 1 + int sharedFileCount = reader.ReadInt32(); + for (int i = 0; i < sharedFileCount; i++) + { + var shared = new SharedAssets(); + shared.aName = reader.ReadStringToNull(); + reader.Position += 20; + var sharedFilePath = reader.ReadStringToNull(); //relative path + shared.fileName = Path.GetFileName(sharedFilePath); + sharedAssetsList.Add(shared); + } + + buildType = Regex.Replace(unityVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries); + var firstVersion = int.Parse(unityVersion.Split('.')[0]); + version = Regex.Matches(unityVersion, @"\d").Cast().Select(m => int.Parse(m.Value)).ToArray(); if (firstVersion > 5)//2017 and up { var nversion = new int[version.Length - 3]; @@ -338,28 +335,7 @@ namespace AssetStudio Array.Copy(version, 4, nversion, 1, version.Length - 4); version = nversion; } - if (fileGen >= 14) - { - //this looks like a list of assets that need to be preloaded in memory before anytihng else - int someCount = this.reader.ReadInt32(); - for (int i = 0; i < someCount; i++) - { - int num1 = this.reader.ReadInt32(); - this.reader.AlignStream(4); - long m_PathID = this.reader.ReadInt64(); - } - } - int sharedFileCount = this.reader.ReadInt32(); - for (int i = 0; i < sharedFileCount; i++) - { - var shared = new SharedAssets(); - shared.aName = this.reader.ReadStringToNull(); - this.reader.Position += 20; - var sharedFilePath = this.reader.ReadStringToNull(); //relative path - shared.fileName = Path.GetFileName(sharedFilePath); - sharedAssetsList.Add(shared); - } valid = true; } catch @@ -367,49 +343,58 @@ namespace AssetStudio } } - private void readBase(List cb, int level) + private void ReadTypeTree(List typeTreeList, int depth) { - string varType = reader.ReadStringToNull(); - string varName = reader.ReadStringToNull(); - int size = reader.ReadInt32(); - int index = reader.ReadInt32(); - int isArray = reader.ReadInt32(); - int num0 = reader.ReadInt32(); - int flag = reader.ReadInt32(); - int childrenCount = reader.ReadInt32(); - - cb.Add(new ClassMember + var typeTree = new TypeTree(); + typeTreeList.Add(typeTree); + typeTree.m_Depth = depth; + typeTree.m_Type = reader.ReadStringToNull(); + typeTree.m_Name = reader.ReadStringToNull(); + typeTree.m_ByteSize = reader.ReadInt32(); + if (header.m_Version == 2) { - Level = level - 1, - Type = varType, - Name = varName, - Size = size, - Flag = flag - }); - for (int i = 0; i < childrenCount; i++) { readBase(cb, level + 1); } + var variableCount = reader.ReadInt32(); + } + if (header.m_Version != 3) + { + typeTree.m_Index = reader.ReadInt32(); + } + typeTree.m_IsArray = reader.ReadInt32(); + typeTree.m_Version = reader.ReadInt32(); + if (header.m_Version != 3) + { + typeTree.m_MetaFlag = reader.ReadInt32(); + + } + + int childrenCount = reader.ReadInt32(); + for (int i = 0; i < childrenCount; i++) + { + ReadTypeTree(typeTreeList, depth + 1); + } } - private void readBase5() + private void ReadTypeTree5() { int classID = reader.ReadInt32(); - if (fileGen > 15)//5.5.0 and up + if (header.m_Version > 15)//5.5.0 and up { reader.ReadByte(); - int type1; - if ((type1 = reader.ReadInt16()) >= 0) + int typeID = reader.ReadInt16(); + if (typeID >= 0) { - type1 = -1 - type1; + typeID = -1 - typeID; } else { - type1 = classID; + typeID = classID; } - classIDs.Add(new[] { type1, classID }); + classIDs.Add(new[] { typeID, classID }); if (classID == 114) { reader.Position += 16; } - classID = type1; + classID = typeID; } else if (classID < 0) { @@ -417,7 +402,7 @@ namespace AssetStudio } reader.Position += 16; - if (baseDefinitions) + if (serializedTypeTrees) { int varCount = reader.ReadInt32(); int stringSize = reader.ReadInt32(); @@ -425,66 +410,46 @@ namespace AssetStudio reader.Position += varCount * 24; using (var stringReader = new BinaryReader(new MemoryStream(reader.ReadBytes(stringSize)))) { - string className = ""; - var classVar = new List(); - //build Class Structures + var typeTreeList = new List(); reader.Position -= varCount * 24 + stringSize; for (int i = 0; i < varCount; i++) { - ushort num0 = reader.ReadUInt16(); - byte level = reader.ReadByte(); - bool isArray = reader.ReadBoolean(); + var typeTree = new TypeTree(); + typeTreeList.Add(typeTree); + typeTree.m_Version = reader.ReadUInt16(); + typeTree.m_Depth = reader.ReadByte(); + typeTree.m_IsArray = reader.ReadBoolean() ? 1 : 0; ushort varTypeIndex = reader.ReadUInt16(); ushort test = reader.ReadUInt16(); - string varTypeStr; if (test == 0) //varType is an offset in the string block { stringReader.BaseStream.Position = varTypeIndex; - varTypeStr = stringReader.ReadStringToNull(); + typeTree.m_Type = stringReader.ReadStringToNull(); } else //varType is an index in an internal strig array { - varTypeStr = baseStrings.ContainsKey(varTypeIndex) ? baseStrings[varTypeIndex] : varTypeIndex.ToString(); + typeTree.m_Type = baseStrings.ContainsKey(varTypeIndex) ? baseStrings[varTypeIndex] : varTypeIndex.ToString(); } ushort varNameIndex = reader.ReadUInt16(); test = reader.ReadUInt16(); - string varNameStr; if (test == 0) { stringReader.BaseStream.Position = varNameIndex; - varNameStr = stringReader.ReadStringToNull(); + typeTree.m_Name = stringReader.ReadStringToNull(); } else { - varNameStr = baseStrings.ContainsKey(varNameIndex) ? baseStrings[varNameIndex] : varNameIndex.ToString(); + typeTree.m_Name = baseStrings.ContainsKey(varNameIndex) ? baseStrings[varNameIndex] : varNameIndex.ToString(); } - int size = reader.ReadInt32(); - int index = reader.ReadInt32(); - int flag = reader.ReadInt32(); - - if (index == 0) - { - className = varTypeStr + " " + varNameStr; - } - else - { - classVar.Add(new ClassMember - { - Level = level - 1, - Type = varTypeStr, - Name = varNameStr, - Size = size, - Flag = flag - }); - } + typeTree.m_ByteSize = reader.ReadInt32(); + typeTree.m_Index = reader.ReadInt32(); + typeTree.m_MetaFlag = reader.ReadInt32(); } reader.Position += stringSize; - var aClass = new ClassStruct { ID = classID, Text = className, members = classVar }; - aClass.SubItems.Add(classID.ToString()); - ClassStructures[classID] = aClass; + m_Type[classID] = typeTreeList; } } } diff --git a/AssetStudio/StudioClasses/BuildTarget.cs b/AssetStudio/StudioClasses/BuildTarget.cs index 7603805..a134f52 100644 --- a/AssetStudio/StudioClasses/BuildTarget.cs +++ b/AssetStudio/StudioClasses/BuildTarget.cs @@ -7,6 +7,7 @@ namespace AssetStudio { public enum BuildTarget { + UnknownPlatform = 3716, DashboardWidget = 1, StandaloneOSX = 2, StandaloneOSXPPC = 3, diff --git a/AssetStudio/StudioClasses/ClassMember.cs b/AssetStudio/StudioClasses/ClassMember.cs deleted file mode 100644 index a3bf248..0000000 --- a/AssetStudio/StudioClasses/ClassMember.cs +++ /dev/null @@ -1,16 +0,0 @@ -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 deleted file mode 100644 index 38d5cab..0000000 --- a/AssetStudio/StudioClasses/ClassStruct.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace AssetStudio -{ - public class ClassStruct : ListViewItem - { - public int ID; - public List members; - - public override string ToString() - { - 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(); - } - } -} diff --git a/AssetStudio/StudioClasses/EndianBinaryReader.cs b/AssetStudio/StudioClasses/EndianBinaryReader.cs index 1ee5197..12f11da 100644 --- a/AssetStudio/StudioClasses/EndianBinaryReader.cs +++ b/AssetStudio/StudioClasses/EndianBinaryReader.cs @@ -7,8 +7,8 @@ namespace AssetStudio { public enum EndianType { - BigEndian, - LittleEndian + LittleEndian, + BigEndian } public class EndianBinaryReader : BinaryReader diff --git a/AssetStudio/StudioClasses/Exporter.cs b/AssetStudio/StudioClasses/Exporter.cs index 638d07a..2695b7f 100644 --- a/AssetStudio/StudioClasses/Exporter.cs +++ b/AssetStudio/StudioClasses/Exporter.cs @@ -107,7 +107,7 @@ namespace AssetStudio return false; var m_MonoBehaviour = new MonoBehaviour(asset); string str; - if (asset.Type1 != asset.Type2 && asset.sourceFile.ClassStructures.ContainsKey(asset.Type1)) + if (asset.Type1 != asset.Type2 && asset.sourceFile.m_Type.ContainsKey(asset.Type1)) { str = asset.Dump(); } diff --git a/AssetStudio/StudioClasses/Importer.cs b/AssetStudio/StudioClasses/Importer.cs index 95d81a6..8aa5f52 100644 --- a/AssetStudio/StudioClasses/Importer.cs +++ b/AssetStudio/StudioClasses/Importer.cs @@ -44,19 +44,19 @@ namespace AssetStudio assetsfileListHash.Add(assetsFile.upperFileName); #region for 2.6.x find mainData and get string version - if (assetsFile.fileGen == 6 && fileName != "mainData") + if (assetsFile.header.m_Version == 6 && fileName != "mainData") { var mainDataFile = assetsfileList.Find(aFile => aFile.fileName == "mainData"); if (mainDataFile != null) { - assetsFile.m_Version = mainDataFile.m_Version; + assetsFile.unityVersion = mainDataFile.unityVersion; assetsFile.version = mainDataFile.version; assetsFile.buildType = mainDataFile.buildType; } else if (File.Exists(Path.GetDirectoryName(fullName) + "\\mainData")) { mainDataFile = new AssetsFile(Path.GetDirectoryName(fullName) + "\\mainData", new EndianBinaryReader(File.OpenRead(Path.GetDirectoryName(fullName) + "\\mainData"))); - assetsFile.m_Version = mainDataFile.m_Version; + assetsFile.unityVersion = mainDataFile.unityVersion; assetsFile.version = mainDataFile.version; assetsFile.buildType = mainDataFile.buildType; } @@ -112,10 +112,10 @@ namespace AssetStudio { assetsFile.parentPath = parentPath ?? fullName; - if (assetsFile.fileGen == 6) //2.6.x and earlier don't have a string version before the preload table + if (assetsFile.header.m_Version == 6) //2.6.x and earlier don't have a string version before the preload table { //make use of the bundle file version - assetsFile.m_Version = bundleFile.versionEngine; + assetsFile.unityVersion = bundleFile.versionEngine; assetsFile.version = Regex.Matches(bundleFile.versionEngine, @"\d").Cast().Select(m => int.Parse(m.Value)).ToArray(); assetsFile.buildType = Regex.Replace(bundleFile.versionEngine, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries); } diff --git a/AssetStudio/StudioClasses/PPtrHelpers.cs b/AssetStudio/StudioClasses/PPtrHelpers.cs index 48e9cd3..1af76fa 100644 --- a/AssetStudio/StudioClasses/PPtrHelpers.cs +++ b/AssetStudio/StudioClasses/PPtrHelpers.cs @@ -39,7 +39,7 @@ namespace AssetStudio result.m_FileID = index; } - result.m_PathID = sourceFile.fileGen < 14 ? reader.ReadInt32() : reader.ReadInt64(); + result.m_PathID = sourceFile.header.m_Version < 14 ? reader.ReadInt32() : reader.ReadInt64(); return result; } diff --git a/AssetStudio/StudioClasses/Studio.cs b/AssetStudio/StudioClasses/Studio.cs index 6499086..db6057f 100644 --- a/AssetStudio/StudioClasses/Studio.cs +++ b/AssetStudio/StudioClasses/Studio.cs @@ -20,7 +20,7 @@ namespace AssetStudio public static List exportableAssets = new List(); //used to hold all assets while the ListView is filtered private static HashSet assetsNameHash = new HashSet(); //avoid the same name asset public static List visibleAssets = new List(); //used to build the ListView from all or filtered assets - public static Dictionary> AllClassStructures = new Dictionary>(); + public static Dictionary> AllTypeMap = new Dictionary>(); public static string mainPath; public static string productName = ""; public static bool moduleLoaded; @@ -432,16 +432,16 @@ namespace AssetStudio //group class structures by versionv foreach (var assetsFile in assetsfileList) { - if (AllClassStructures.TryGetValue(assetsFile.m_Version, out var curVer)) + if (AllTypeMap.TryGetValue(assetsFile.unityVersion, out var curVer)) { - foreach (var uClass in assetsFile.ClassStructures) + foreach (var type in assetsFile.m_Type) { - curVer[uClass.Key] = uClass.Value; + curVer[type.Key] = new TypeItem(type.Key, type.Value); } } else { - AllClassStructures.Add(assetsFile.m_Version, assetsFile.ClassStructures); + AllTypeMap.Add(assetsFile.unityVersion, assetsFile.m_Type.ToDictionary(x => x.Key, y => new TypeItem(y.Key, y.Value))); } } } diff --git a/AssetStudio/StudioClasses/Texture2DConverter.cs b/AssetStudio/StudioClasses/Texture2DConverter.cs index 39a82a8..6ed9f02 100644 --- a/AssetStudio/StudioClasses/Texture2DConverter.cs +++ b/AssetStudio/StudioClasses/Texture2DConverter.cs @@ -95,7 +95,7 @@ namespace AssetStudio m_TextureFormat = m_Texture2D.m_TextureFormat; var mMipMap = m_Texture2D.m_MipMap; version = m_Texture2D.sourceFile.version; - var platform = m_Texture2D.sourceFile.platform; + var platform = m_Texture2D.sourceFile.m_TargetPlatform; if (version[0] < 5 || (version[0] == 5 && version[1] < 2))//5.2 down { @@ -587,9 +587,9 @@ namespace AssetStudio dwABitMask = -16777216; } - private void SwapBytesForXbox(int platform) + private void SwapBytesForXbox(BuildTarget platform) { - if (platform == 11) //swap bytes for Xbox confirmed, PS3 not encountered + if (platform == BuildTarget.XBOX360) //swap bytes for Xbox confirmed, PS3 not encountered { for (var i = 0; i < image_data_size / 2; i++) { diff --git a/AssetStudio/StudioClasses/TypeItem.cs b/AssetStudio/StudioClasses/TypeItem.cs new file mode 100644 index 0000000..c10a0c6 --- /dev/null +++ b/AssetStudio/StudioClasses/TypeItem.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace AssetStudio +{ + public class TypeItem : ListViewItem + { + public List typeTreeList; + + public TypeItem(int classID, List typeTreeList) + { + this.typeTreeList = typeTreeList; + Text = typeTreeList[0].m_Type + " " + typeTreeList[0].m_Name; + SubItems.Add(classID.ToString()); + } + + public override string ToString() + { + var sb = new StringBuilder(); + foreach (var i in typeTreeList) + { + sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.m_Depth), i.m_Type, i.m_Name, i.m_ByteSize, (i.m_MetaFlag & 0x4000) != 0); + } + return sb.ToString(); + } + } +} diff --git a/AssetStudio/StudioClasses/TypeTree.cs b/AssetStudio/StudioClasses/TypeTree.cs new file mode 100644 index 0000000..62c853b --- /dev/null +++ b/AssetStudio/StudioClasses/TypeTree.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AssetStudio +{ + public class TypeTree + { + public string m_Type; + public string m_Name; + public int m_ByteSize; + public int m_Index; + public int m_IsArray; + public int m_Version; + public int m_MetaFlag; + public int m_Depth; + } +} diff --git a/AssetStudio/StudioClasses/ClassStructHelper.cs b/AssetStudio/StudioClasses/TypeTreeHelper.cs similarity index 88% rename from AssetStudio/StudioClasses/ClassStructHelper.cs rename to AssetStudio/StudioClasses/TypeTreeHelper.cs index a85e515..16fa516 100644 --- a/AssetStudio/StudioClasses/ClassStructHelper.cs +++ b/AssetStudio/StudioClasses/TypeTreeHelper.cs @@ -7,9 +7,9 @@ using System.Text; namespace AssetStudio { - public static class ClassStructHelper + public static class TypeTreeHelper { - public static void ReadClassString(StringBuilder sb, List members, EndianBinaryReader reader) + public static void ReadTypeString(StringBuilder sb, List members, EndianBinaryReader reader) { for (int i = 0; i < members.Count; i++) { @@ -17,15 +17,15 @@ namespace AssetStudio } } - private static void ReadStringValue(StringBuilder sb, List members, EndianBinaryReader reader, ref int 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; + var level = member.m_Depth; + var varTypeStr = member.m_Type; + var varNameStr = member.m_Name; object value = null; var append = true; - var align = (member.Flag & 0x4000) != 0; + var align = (member.m_MetaFlag & 0x4000) != 0; switch (varTypeStr) { case "SInt8": @@ -76,7 +76,7 @@ namespace AssetStudio break; case "vector": { - if ((members[i + 1].Flag & 0x4000) != 0) + if ((members[i + 1].m_MetaFlag & 0x4000) != 0) align = true; append = false; sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); @@ -96,7 +96,7 @@ namespace AssetStudio } case "map": { - if ((members[i + 1].Flag & 0x4000) != 0) + if ((members[i + 1].m_MetaFlag & 0x4000) != 0) align = true; append = false; sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); @@ -106,7 +106,7 @@ namespace AssetStudio var map = GetMembers(members, level, i); i += map.Count - 1; map.RemoveRange(0, 4); - var first = GetMembers(map, map[0].Level, 0); + var first = GetMembers(map, map[0].m_Depth, 0); map.RemoveRange(0, first.Count); var second = map; for (int j = 0; j < size; j++) @@ -132,7 +132,7 @@ namespace AssetStudio } default: { - if (i != members.Count && members[i + 1].Type == "Array") + if (i != members.Count && members[i + 1].m_Type == "Array") { goto case "vector"; } @@ -154,26 +154,26 @@ namespace AssetStudio reader.AlignStream(4); } - public static ExpandoObject ReadDynamicClass(List members, EndianBinaryReader reader) + public static ExpandoObject ReadDynamicType(List members, EndianBinaryReader reader) { var obj = new ExpandoObject(); var objdic = (IDictionary)obj; for (int i = 0; i < members.Count; i++) { var member = members[i]; - var varNameStr = member.Name; + var varNameStr = member.m_Name; objdic[varNameStr] = ReadValue(members, reader, ref i); } return obj; } - private static object ReadValue(List members, EndianBinaryReader reader, ref int i) + private static object ReadValue(List members, EndianBinaryReader reader, ref int i) { var member = members[i]; - var level = member.Level; - var varTypeStr = member.Type; + var level = member.m_Depth; + var varTypeStr = member.m_Type; object value; - var align = (member.Flag & 0x4000) != 0; + var align = (member.m_MetaFlag & 0x4000) != 0; switch (varTypeStr) { case "SInt8": @@ -222,7 +222,7 @@ namespace AssetStudio break; case "vector": { - if ((members[i + 1].Flag & 0x4000) != 0) + if ((members[i + 1].m_MetaFlag & 0x4000) != 0) align = true; var size = reader.ReadInt32(); var list = new List(size); @@ -239,14 +239,14 @@ namespace AssetStudio } case "map": { - if ((members[i + 1].Flag & 0x4000) != 0) + if ((members[i + 1].m_MetaFlag & 0x4000) != 0) align = true; var size = reader.ReadInt32(); var dic = new List>(size); var map = GetMembers(members, level, i); i += map.Count - 1; map.RemoveRange(0, 4); - var first = GetMembers(map, map[0].Level, 0); + var first = GetMembers(map, map[0].m_Depth, 0); map.RemoveRange(0, first.Count); var second = map; for (int j = 0; j < size; j++) @@ -267,7 +267,7 @@ namespace AssetStudio } default: { - if (i != members.Count && members[i + 1].Type == "Array") + if (i != members.Count && members[i + 1].m_Type == "Array") { goto case "vector"; } @@ -279,7 +279,7 @@ namespace AssetStudio for (int j = 0; j < @class.Count; j++) { var classmember = @class[j]; - var name = classmember.Name; + var name = classmember.m_Name; objdic[name] = ReadValue(@class, reader, ref j); } value = obj; @@ -291,14 +291,14 @@ namespace AssetStudio return value; } - private static List GetMembers(List members, int level, int index) + private static List GetMembers(List members, int level, int index) { - var member2 = new List(); + 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; + var level2 = member.m_Depth; if (level2 <= level) { return member2; @@ -308,7 +308,7 @@ namespace AssetStudio return member2; } - public static byte[] WriteDynamicClass(ExpandoObject obj, List members) + public static byte[] WriteDynamicType(ExpandoObject obj, List members) { var stream = new MemoryStream(); var write = new BinaryWriter(stream); @@ -316,18 +316,18 @@ namespace AssetStudio for (int i = 0; i < members.Count; i++) { var member = members[i]; - var varNameStr = member.Name; + var varNameStr = member.m_Name; WriteValue(objdic[varNameStr], members, write, ref i); } return stream.ToArray(); } - private static void WriteValue(object value, List members, BinaryWriter write, ref int i) + private static void WriteValue(object value, List members, BinaryWriter write, ref int i) { var member = members[i]; - var level = member.Level; - var varTypeStr = member.Type; - var align = (member.Flag & 0x4000) != 0; + var level = member.m_Depth; + var varTypeStr = member.m_Type; + var align = (member.m_MetaFlag & 0x4000) != 0; switch (varTypeStr) { case "SInt8": @@ -376,7 +376,7 @@ namespace AssetStudio break; case "vector": { - if ((members[i + 1].Flag & 0x4000) != 0) + if ((members[i + 1].m_MetaFlag & 0x4000) != 0) align = true; var list = (List)value; var size = list.Count; @@ -393,7 +393,7 @@ namespace AssetStudio } case "map": { - if ((members[i + 1].Flag & 0x4000) != 0) + if ((members[i + 1].m_MetaFlag & 0x4000) != 0) align = true; var dic = (List>)value; var size = dic.Count; @@ -401,7 +401,7 @@ namespace AssetStudio var map = GetMembers(members, level, i); i += map.Count - 1; map.RemoveRange(0, 4); - var first = GetMembers(map, map[0].Level, 0); + var first = GetMembers(map, map[0].m_Depth, 0); map.RemoveRange(0, first.Count); var second = map; for (int j = 0; j < size; j++) @@ -424,7 +424,7 @@ namespace AssetStudio } default: { - if (i != members.Count && members[i + 1].Type == "Array") + if (i != members.Count && members[i + 1].m_Type == "Array") { goto case "vector"; } @@ -436,7 +436,7 @@ namespace AssetStudio for (int j = 0; j < @class.Count; j++) { var classmember = @class[j]; - var name = classmember.Name; + var name = classmember.m_Name; WriteValue(objdic[name], @class, write, ref j); } break;