This commit is contained in:
Perfare 2018-09-27 05:23:10 +08:00
parent 97169ff6dd
commit f2b041741b
19 changed files with 285 additions and 310 deletions

View File

@ -183,9 +183,6 @@
<Compile Include="StudioClasses\BinaryReaderExtensions.cs" />
<Compile Include="StudioClasses\BinaryWriterExtensions.cs" />
<Compile Include="StudioClasses\BundleFile.cs" />
<Compile Include="StudioClasses\ClassMember.cs" />
<Compile Include="StudioClasses\ClassStruct.cs" />
<Compile Include="StudioClasses\ClassStructHelper.cs" />
<Compile Include="StudioClasses\FBXExporter.cs" />
<Compile Include="StudioClasses\BuildTarget.cs" />
<Compile Include="StudioClasses\GameObjectTreeNode.cs" />
@ -231,6 +228,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StudioClasses\AssetsFile.cs" />
<Compile Include="StudioClasses\Texture2DConverter.cs" />
<Compile Include="StudioClasses\TypeItem.cs" />
<Compile Include="StudioClasses\TypeTree.cs" />
<Compile Include="StudioClasses\TypeTreeHelper.cs" />
<Compile Include="StudioClasses\WebFile.cs" />
<Compile Include="TreeViewExtensions.cs" />
<EmbeddedResource Include="AssetStudioForm.resx">

View File

@ -174,8 +174,8 @@
<Compile Include="StudioClasses\BinaryWriterExtensions.cs" />
<Compile Include="StudioClasses\BuildTarget.cs" />
<Compile Include="StudioClasses\ClassIDReference.cs" />
<Compile Include="StudioClasses\ClassMember.cs" />
<Compile Include="StudioClasses\ClassStructHelper.cs" />
<Compile Include="StudioClasses\TypeTree.cs" />
<Compile Include="StudioClasses\TypeTreeHelper.cs" />
<Compile Include="StudioClasses\ResourcesHelper.cs" />
<Compile Include="Classes\AssetBundle.cs" />
<Compile Include="Classes\MovieTexture.cs" />
@ -186,7 +186,7 @@
<Compile Include="Classes\AudioClip.cs" />
<Compile Include="Classes\BuildSettings.cs" />
<Compile Include="StudioClasses\BundleFile.cs" />
<Compile Include="StudioClasses\ClassStruct.cs" />
<Compile Include="StudioClasses\TypeItem.cs" />
<Compile Include="StudioClasses\FBXExporter.cs" />
<Compile Include="StudioClasses\SpriteHelper.cs" />
<Compile Include="StudioClasses\Exporter.cs" />

View File

@ -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();
}

View File

@ -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++)
{

View File

@ -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)
{

View File

@ -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);
}
}
}

View File

@ -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<int, List<TypeTree>> m_Type = new SortedDictionary<int, List<TypeTree>>();
private List<int[]> classIDs = new List<int[]>();//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<long, AssetPreloadData> preloadTable = new Dictionary<long, AssetPreloadData>();
public Dictionary<long, GameObject> GameObjectList = new Dictionary<long, GameObject>();
public Dictionary<long, Transform> TransformList = new Dictionary<long, Transform>();
@ -29,11 +44,7 @@ namespace AssetStudio
public List<AssetPreloadData> exportableAssets = new List<AssetPreloadData>();
public List<SharedAssets> sharedAssetsList = new List<SharedAssets> { new SharedAssets() };
public SortedDictionary<int, ClassStruct> ClassStructures = new SortedDictionary<int, ClassStruct>();
private bool baseDefinitions;
private List<int[]> classIDs = new List<int[]>();//use for 5.5.0
public bool valid;
#region cmmon string
private static Dictionary<int, string> baseStrings = new Dictionary<int, string>
@ -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<ClassMember>();
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<TypeTree>();
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<Match>().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<Match>().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<ClassMember> cb, int level)
private void ReadTypeTree(List<TypeTree> 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<ClassMember>();
//build Class Structures
var typeTreeList = new List<TypeTree>();
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;
}
}
}

View File

@ -7,6 +7,7 @@ namespace AssetStudio
{
public enum BuildTarget
{
UnknownPlatform = 3716,
DashboardWidget = 1,
StandaloneOSX = 2,
StandaloneOSXPPC = 3,

View File

@ -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;
}
}

View File

@ -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<ClassMember> 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();
}
}
}

View File

@ -7,8 +7,8 @@ namespace AssetStudio
{
public enum EndianType
{
BigEndian,
LittleEndian
LittleEndian,
BigEndian
}
public class EndianBinaryReader : BinaryReader

View File

@ -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();
}

View File

@ -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<Match>().Select(m => int.Parse(m.Value)).ToArray();
assetsFile.buildType = Regex.Replace(bundleFile.versionEngine, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
}

View File

@ -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;
}

View File

@ -20,7 +20,7 @@ namespace AssetStudio
public static List<AssetPreloadData> exportableAssets = new List<AssetPreloadData>(); //used to hold all assets while the ListView is filtered
private static HashSet<string> assetsNameHash = new HashSet<string>(); //avoid the same name asset
public static List<AssetPreloadData> visibleAssets = new List<AssetPreloadData>(); //used to build the ListView from all or filtered assets
public static Dictionary<string, SortedDictionary<int, ClassStruct>> AllClassStructures = new Dictionary<string, SortedDictionary<int, ClassStruct>>();
public static Dictionary<string, Dictionary<int, TypeItem>> AllTypeMap = new Dictionary<string, Dictionary<int, TypeItem>>();
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)));
}
}
}

View File

@ -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++)
{

View File

@ -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<TypeTree> typeTreeList;
public TypeItem(int classID, List<TypeTree> 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();
}
}
}

View File

@ -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;
}
}

View File

@ -7,9 +7,9 @@ using System.Text;
namespace AssetStudio
{
public static class ClassStructHelper
public static class TypeTreeHelper
{
public static void ReadClassString(StringBuilder sb, List<ClassMember> members, EndianBinaryReader reader)
public static void ReadTypeString(StringBuilder sb, List<TypeTree> members, EndianBinaryReader reader)
{
for (int i = 0; i < members.Count; i++)
{
@ -17,15 +17,15 @@ namespace AssetStudio
}
}
private static void ReadStringValue(StringBuilder sb, List<ClassMember> members, EndianBinaryReader reader, ref int i)
private static void ReadStringValue(StringBuilder sb, List<TypeTree> 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<ClassMember> members, EndianBinaryReader reader)
public static ExpandoObject ReadDynamicType(List<TypeTree> members, EndianBinaryReader reader)
{
var obj = new ExpandoObject();
var objdic = (IDictionary<string, object>)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<ClassMember> members, EndianBinaryReader reader, ref int i)
private static object ReadValue(List<TypeTree> 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<object>(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<KeyValuePair<object, object>>(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<ClassMember> GetMembers(List<ClassMember> members, int level, int index)
private static List<TypeTree> GetMembers(List<TypeTree> members, int level, int index)
{
var member2 = new List<ClassMember>();
var member2 = new List<TypeTree>();
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<ClassMember> members)
public static byte[] WriteDynamicType(ExpandoObject obj, List<TypeTree> 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<ClassMember> members, BinaryWriter write, ref int i)
private static void WriteValue(object value, List<TypeTree> 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<object>)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<KeyValuePair<object, object>>)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;