private string GetAssetNameFast(AssetFileInfoEx afi, ClassDatabaseFile cldb, ClassDatabaseType type, AssetsFileReader reader) { if (type.fields.Count <= 1) { return(type.name.GetString(cldb)); } if (type.fields[1].fieldName.GetString(cldb) == "m_Name") { reader.Position = afi.absoluteFilePos; return(reader.ReadCountStringInt32()); } else if (type.name.GetString(cldb) == "GameObject") { reader.Position = afi.absoluteFilePos; int size = reader.ReadInt32(); reader.Position += (ulong)(size * 12); reader.Position += 4; return(reader.ReadCountStringInt32()); } else if (type.name.GetString(cldb) == "MonoBehaviour") { reader.Position = afi.absoluteFilePos; reader.Position += 28; string name = reader.ReadCountStringInt32(); if (name != "") { return(name); } } return(type.name.GetString(cldb)); }
public AssetTypeInstance GetATI(Stream file, AssetFileInfoEx info) { int index = 0; bool foundInList = false; ClassDatabaseType type = AssetHelper.FindAssetClassByID(initialClassFile, info.curFileType); for (int i = 0; i < attfs.Count; i++) { if (attfs[i].type == type.name.GetString(initialClassFile)) { index = i; foundInList = true; } } AssetTypeInstance ati; if (foundInList) { ati = new AssetTypeInstance(new[] { attfs[index] }, new AssetsFileReader(file), info.absoluteFilePos); } else { AssetTypeTemplateField baseField = new AssetTypeTemplateField(); baseField.FromClassDatabase(initialClassFile, AssetHelper.FindAssetClassByID(initialClassFile, info.curFileType), 0); attfs.Add(baseField); ati = new AssetTypeInstance(new[] { attfs.Last() }, new AssetsFileReader(file), info.absoluteFilePos); } return(ati); }
public static string GetAssetNameFast(AssetsFile file, ClassDatabaseFile cldb, AssetFileInfoEx info) { ClassDatabaseType type = FindAssetClassByID(cldb, info.curFileType); AssetsFileReader reader = file.reader; if (type.fields.Count == 0) { return(type.name.GetString(cldb)); } if (type.fields[1].fieldName.GetString(cldb) == "m_Name") { reader.Position = info.absoluteFilePos; return(reader.ReadCountStringInt32()); } else if (type.name.GetString(cldb) == "GameObject") { reader.Position = info.absoluteFilePos; int size = reader.ReadInt32(); reader.Position += size * 12; reader.Position += 4; return(reader.ReadCountStringInt32()); } else if (type.name.GetString(cldb) == "MonoBehaviour") { reader.Position = info.absoluteFilePos; reader.Position += 28; string name = reader.ReadCountStringInt32(); if (name != "") { return(name); } } return(type.name.GetString(cldb)); }
private void LoadGGM(AssetsFileInstance mainFile) { //swap this with resources so we can actually see ggm assets foreach (AssetFileInfoEx info in mainFile.table.pAssetFileInfo) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType); if (type.name.GetString(helper.classFile) == "ResourceManager") { AssetTypeInstance inst = helper.GetATI(mainFile.file, info); AssetTypeValueField baseField = inst.GetBaseField(); AssetTypeValueField m_Container = baseField.Get("m_Container").Get("Array"); //Dictionary<string, AssetDetails> paths = new Dictionary<string, AssetDetails>(); List <AssetDetails> assets = new List <AssetDetails>(); for (uint i = 0; i < m_Container.GetValue().AsArray().size; i++) { AssetTypeValueField item = m_Container[i]; string path = item.Get("first").GetValue().AsString(); AssetTypeValueField pointerField = item.Get("second"); uint fileID = (uint)pointerField.Get("m_FileID").GetValue().AsInt(); ulong pathID = (ulong)pointerField.Get("m_PathID").GetValue().AsInt64(); //paths[path] = new AssetDetails(new AssetPPtr(fileID, pathID)); assets.Add(new AssetDetails(new AssetPPtr(fileID, pathID), AssetIcon.Unknown, path)); } rootDir = new FSDirectory(); //rootDir.Create(paths); rootDir.Create(assets); ChangeDirectory(""); helper.UpdateDependencies(); CheckResourcesInfo(); return; } } }
private void LoadGeneric(AssetsFileInstance mainFile, bool isLevel) { List <AssetDetails> assets = new List <AssetDetails>(); foreach (AssetFileInfoEx info in mainFile.table.assetFileInfo) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType); if (type == null) { continue; } string typeName = type.name.GetString(helper.classFile); if (typeName != "GameObject" && isLevel) { continue; } string name = AssetHelper.GetAssetNameFast(mainFile.file, helper.classFile, info); if (name == "") { name = "[Unnamed]"; } assets.Add(new AssetDetails(new AssetPPtr(0, info.index), GetIconForName(typeName), name, typeName, (int)info.curFileSize)); } rootDir = new FSDirectory(); rootDir.Create(assets); ChangeDirectory(""); }
private void Ttr_list_SelectedIndexChanged(object sender, EventArgs e) { Type_0D type = file.typeTree.pTypes_Unity5[ttr_list.SelectedIndex]; if (type.typeFieldsExCount == 0) { ClassDatabaseType cldt = cldb.classes.First(c => c.classId == type.classId); ttr_type.Text = cldt.name.GetString(cldb); } else { TypeField_0D baseField = type.pTypeFieldsEx[0]; ttr_type.Text = baseField.GetTypeString(type.pStringTable); } ttr_typeid.Text = type.classId.ToString(); ttr_scriptid.Text = type.scriptIndex.ToString(); if (type.unknown5 != 0 || type.unknown6 != 0 || type.unknown7 != 0 || type.unknown8 != 0) { ttr_hash.Text = $"{type.unknown5.ToString("x8")}{type.unknown6.ToString("x8")}{type.unknown7.ToString("x8")}{type.unknown8.ToString("x8")}"; } else { ttr_hash.Text = ""; } if (type.unknown1 != 0 || type.unknown2 != 0 || type.unknown3 != 0 || type.unknown4 != 0) { ttr_monohash.Text = $"{type.unknown1.ToString("x8")}{type.unknown2.ToString("x8")}{type.unknown3.ToString("x8")}{type.unknown4.ToString("x8")}"; } else { ttr_monohash.Text = ""; } }
private void AddAssetItem(AssetsFile af, AssetFileInfoEx afi, AssetsFileReader worker, uint fileId) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(assetsManager.initialClassFile, afi.curFileType); string assetName = GetAssetNameFast(afi, assetsManager.initialClassFile, type, worker); string assetType = type.name.GetString(assetsManager.initialClassFile); string fileID = fileId.ToString(); string pathID = unchecked ((long)afi.index).ToString(); string size = afi.curFileSize.ToString(); string modified = ""; if (assetName.Trim() == "") { assetName = assetType; //todo, seems redundant now, check on this later } string[] items = new string[] { assetName, assetType, fileID, pathID, size, modified }; assetDetails.Add( new AssetDetails( assetName, assetType, afi.index, fileId, afi.curFileType, afi.absoluteFilePos, af.typeTree.pTypes_Unity5[afi.curFileTypeOrIndex].scriptIndex ) ); assetList.Items.Add(new ListViewItem(items)); }
private void AssetInfo_Load(object sender, EventArgs e) { AssetsFileHeader header = file.header; TypeTree typeTree = file.typeTree; //header hdr_mds.Text = header.metadataSize.ToString(); hdr_fs.Text = header.fileSize.ToString(); hdr_fmt.Text = $"{header.format.ToString()} (0x{header.format.ToString("x")})"; hdr_ffo.Text = $"{header.firstFileOffset.ToString()} (0x{header.firstFileOffset.ToString("x")})"; hdr_en.Text = header.endianness == 1 ? "big endian" : "little endian"; hdr_uvr.Text = typeTree.unityVersion; hdr_ver.Text = $"{typeTree.version.ToString()} (0x{typeTree.version.ToString("x")})"; hdr_htt.Text = typeTree.hasTypeTree == true ? "true" : "false"; //type tree if (!typeTree.hasTypeTree) { ttr_tree.Nodes.Add("There is no type tree data available."); } else { ttr_tree.Nodes.Add("Select a type to show the type tree data."); } foreach (Type_0D type in typeTree.unity5Types) { if (type.typeFieldsExCount == 0) { ClassDatabaseType cldt = cldb.classes.First(c => c.classId == type.classId); ttr_list.Items.Add($"[{cldt.name.GetString(cldb)}] (0x{type.classId.ToString("x")})"); } else { TypeField_0D baseField = type.typeFieldsEx[0]; ttr_list.Items.Add($"{baseField.GetTypeString(type.stringTable)} (0x{type.classId.ToString("x")})"); } } //preload list foreach (AssetPPtr pptr in file.preloadTable.items) { string pptrFileName = "[self]"; if (pptr.fileID != 0) { pptrFileName = file.dependencies.dependencies[pptr.fileID - 1].assetPath; } plt_list.Items.Add(new ListViewItem(new[] { pptrFileName, pptr.pathID.ToString() })); } plt_list.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); //dependencies foreach (AssetsFileDependency dep in file.dependencies.dependencies) { string guid = string.Empty; if (dep.guid.mostSignificant != 0 || dep.guid.leastSignificant != 0) { guid = $"{dep.guid.mostSignificant.ToString("x8")}{dep.guid.leastSignificant.ToString("x8")}"; } dep_list.Items.Add(new ListViewItem(new[] { dep.assetPath, "0x" + dep.type.ToString(), guid })); } dep_list.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); }
private void LoadResources(AssetsFileInstance ggm) { foreach (AssetFileInfoEx info in ggm.table.assetFileInfo) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType); if (type.name.GetString(helper.classFile) == "ResourceManager") { AssetTypeInstance inst = helper.GetTypeInstance(ggm.file, info); AssetTypeValueField baseField = inst.GetBaseField(); AssetTypeValueField m_Container = baseField.Get("m_Container").Get("Array"); List <AssetDetails> assets = new List <AssetDetails>(); for (int i = 0; i < m_Container.GetValue().AsArray().size; i++) { AssetTypeValueField item = m_Container[i]; string path = item.Get("first").GetValue().AsString(); AssetTypeValueField pointerField = item.Get("second"); //paths[path] = new AssetDetails(new AssetPPtr(fileID, pathID)); AssetExternal assetExt = helper.GetExtAsset(ggm, pointerField, true); AssetFileInfoEx assetInfo = assetExt.info; if (assetInfo == null) { continue; } ClassDatabaseType assetType = AssetHelper.FindAssetClassByID(helper.classFile, assetInfo.curFileType); if (assetType == null) { continue; } string assetTypeName = assetType.name.GetString(helper.classFile); string assetName = AssetHelper.GetAssetNameFast(assetExt.file.file, helper.classFile, assetInfo); if (path.Contains("/")) { if (path.Substring(path.LastIndexOf('/') + 1) == assetName.ToLower()) { path = path.Substring(0, path.LastIndexOf('/') + 1) + assetName; } } else { if (path == assetName.ToLower()) { path = path.Substring(0, path.LastIndexOf('/') + 1) + assetName; } } assets.Add(new AssetDetails(new AssetPPtr(0, assetInfo.index), GetIconForName(assetTypeName), path, assetTypeName, (int)assetInfo.curFileSize)); } rootDir = new FSDirectory(); //rootDir.Create(paths); rootDir.Create(assets); ChangeDirectory(""); helper.UpdateDependencies(); CheckResourcesInfo(); return; } } }
private void BuildBundleContent(ref List <string> result, string fileUrl, AssetFile file, AssetToolUtils assetToolUtils) { foreach (AssetFileInfoEx info in file.fileInstance.table.assetFileInfo) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(file.classDBFile, info.curFileType); if (type == null) { continue; } string typeName = type.name.GetString(file.classDBFile); if (typeName != "MonoBehaviour") { continue; } AssetTypeValueField baseField = AssetToolUtils.GetATI(file, info).GetBaseField(); List <AssetTypeValueField> targetFields = AssetToolUtils.GetFieldAtPath(file, baseField, configPath.Split(':')); if (targetFields.Count == 0) { continue; } if (!AssetToolUtils.IsMatchingPathConstraints(file, baseField, pathConstraints)) { continue; } Console.WriteLine("found " + targetFields.Count + " matches in mono-behaviour at path: " + configPath); foreach (AssetTypeValueField targetField in targetFields) { List <AssetTypeValueField> fileNameFields = AssetToolUtils.GetFieldAtPath(file, targetField, fileNamePath.Split(':')); Console.WriteLine("found " + fileNameFields.Count + " fileNameFields in targetField at path: " + fileNamePath); foreach (string value in fileNameFields .Select(fileNameField => fileNameField.GetValue().AsString().Trim()) .Where(fileName => CustomRegex.AllMatching(fileName, fileNameRegexFilters)) .SelectMany(fileName => ApplySubFilters(fileName, baseField, targetField, file, assetToolUtils))) { if (!result.Contains(value)) { result.Add(value); } } } } }
private static AssetFileInfoEx FindGameObject(AssetsManager am, AssetsFileInstance inst, string name) { foreach (AssetFileInfoEx info in inst.table.pAssetFileInfo) { if (info.curFileType == 0x01) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(am.classFile, info.curFileType); string infoName = AssetHelper.GetAssetNameFast(inst.file, am.classFile, info); if (infoName == name) { return(info); } } } return(null); }
public static AssetTypeValueField GetField(long id, out string className) { className = ""; string path = DirctoryPath; AssetsManager helper = AssetsManager; ClassDatabaseFile classFile = helper.classFile; AssetsFileInstance correctAti = AssetsFileInstance; AssetFileInfoEx info = correctAti.table.GetAssetInfo(id); if (info == null) { Console.WriteLine($"path_id:{id} is not found,maybe in other file"); return(null); } ClassDatabaseType classType = AssetHelper.FindAssetClassByID(classFile, info.curFileType); string typeName = classType.name.GetString(classFile); AssetTypeValueField baseField = helper.GetATI(correctAti.file, info).GetBaseField(); className = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType) .name.GetString(helper.classFile); AssetTypeValueField targetBaseField = baseField; if (className == "MonoBehaviour") { if (AssetUtils.AllDependenciesLoaded(helper, correctAti)) { className += $"--{GetClassName(helper, correctAti, targetBaseField)}--{targetBaseField[3].value.AsString().TrimEnd('\0')}--"; string managedPath = Path.Combine(Path.GetDirectoryName(correctAti.path), "Managed"); if (Directory.Exists(managedPath)) { targetBaseField = helper.GetMonoBaseFieldCached(correctAti, info, managedPath); } } else { MessageBox.Show("Can't display MonoBehaviour data until dependencies are loaded", "Assets View"); return(null); } } else { className += "--"; } return(targetBaseField); }
private AssetFileInfoEx FindGameObject(string name) { foreach (AssetFileInfoEx info in assetsTable.pAssetFileInfo) { //faster check for GameObject if (info.curFileType == 0x01) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(am.classFile, info.curFileType); string infoName = UABEExtras.GetAssetNameFast(info, am.classFile, type, assetsFile.reader); if (infoName == name) { return(info); } } } return(null); }
private void RecurseForResourcesInfo(FSDirectory dir, AssetsFileInstance afi) { foreach (FSAsset asset in dir.children.OfType <FSAsset>()) { AssetFileInfoEx info = afi.table.GetAssetInfo(asset.details.pointer.pathID); ClassDatabaseType type = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType); string typeName = type.name.GetString(helper.classFile); asset.details.type = typeName; asset.details.size = (int)info.curFileSize; asset.details.icon = GetIconForName(typeName); } foreach (FSDirectory directory in dir.children.OfType <FSDirectory>()) { RecurseForResourcesInfo(directory, afi); } }
public AssetTypeValueField GetByteArrayTexture(AssetWorkspace workspace, AssetExternal tex) { ClassDatabaseType textureType = AssetHelper.FindAssetClassByID(workspace.am.classFile, tex.info.curFileType); AssetTypeTemplateField textureTemp = new AssetTypeTemplateField(); textureTemp.FromClassDatabase(workspace.am.classFile, textureType, 0); AssetTypeTemplateField image_data = textureTemp.children.FirstOrDefault(f => f.name == "image data"); if (image_data == null) { return(null); } image_data.valueType = EnumValueTypes.ByteArray; AssetTypeInstance textureTypeInstance = new AssetTypeInstance(new[] { textureTemp }, tex.file.file.reader, tex.info.absoluteFilePos); AssetTypeValueField textureBase = textureTypeInstance.GetBaseField(); return(textureBase); }
public void OpenAsset(long id) { ClassDatabaseFile classFile = helper.classFile; AssetsFileInstance correctAti = currentFile; AssetFileInfoEx info = correctAti.table.GetAssetInfo(id); //todo this won't work for assets with typetrees ClassDatabaseType classType = AssetHelper.FindAssetClassByID(classFile, info.curFileType); string typeName = classType.name.GetString(classFile); bool hasGameobjectField = classType.fields.Any(f => f.fieldName.GetString(classFile) == "m_GameObject"); bool parentPointerNull = false; if (typeName != "GameObject" && hasGameobjectField) { //get gameobject parent AssetTypeValueField componentBaseField = helper.GetATI(correctAti.file, info).GetBaseField(); AssetFileInfoEx newInfo = helper.GetExtAsset(correctAti, componentBaseField["m_GameObject"], true).info; if (newInfo != null && newInfo.index != 0) { info = newInfo; } else { parentPointerNull = true; } } if ((typeName == "GameObject" || hasGameobjectField) && !parentPointerNull) { AssetTypeValueField baseField = helper.GetATI(correctAti.file, info).GetBaseField(); AssetTypeValueField transformPtr = baseField["m_Component"]["Array"][0]["component"]; AssetTypeValueField transform = helper.GetExtAsset(correctAti, transformPtr).instance.GetBaseField(); baseField = GetRootTransform(helper, currentFile, transform); AssetTypeValueField gameObjectPtr = baseField["m_GameObject"]; AssetTypeValueField gameObject = helper.GetExtAsset(correctAti, gameObjectPtr).instance.GetBaseField(); GameObjectViewer view = new GameObjectViewer(helper, correctAti, gameObject, info.index, id); view.Show(); } else { AssetTypeValueField baseField = helper.GetATI(correctAti.file, info).GetBaseField(); GameObjectViewer view = new GameObjectViewer(helper, correctAti, baseField, info); view.Show(); } }
private void XRefsDialog_Load(object sender, EventArgs e) { List <AssetID> xrefs = map.GetXRefs(id); if (xrefs == null) { xrefList.Items.Add("[no xrefs]"); } else { foreach (AssetID id in xrefs) { int instIndex = am.files.FindIndex(f => Path.GetFileName(f.path).ToLower() == Path.GetFileName(id.fileName).ToLower()); if (instIndex != -1) { AssetsFileInstance xrefInst = am.files[instIndex]; AssetsFile xrefFile = xrefInst.file; AssetFileInfoEx xrefInf = xrefInst.table.GetAssetInfo(id.pathID); uint fixedId = AssetHelper.FixAudioID(xrefInf.curFileType); bool hasTypeTree = xrefFile.typeTree.hasTypeTree; string assetName = AssetHelper.GetAssetNameFast(xrefFile, am.classFile, xrefInf); string typeName; if (hasTypeTree) { Type_0D xrefType = AssetHelper.FindTypeTreeTypeByID(xrefFile.typeTree, fixedId); typeName = xrefType.typeFieldsEx[0].GetTypeString(xrefType.stringTable); } else { ClassDatabaseType xrefType = AssetHelper.FindAssetClassByID(am.classFile, fixedId); typeName = xrefType.name.GetString(am.classFile); } xrefList.Items.Add(new ListBoxInfo($"{id.fileName} {id.pathID} ({typeName} {assetName})", id)); } else { xrefList.Items.Add(new ListBoxInfo($"{id.fileName} {id.pathID}", id)); } } } }
public static AssetTypeValueField GetMonoBaseField(AssetsManager am, AssetsFile af, AssetFileInfoEx afi, string folderPath) { ClassDatabaseType cldt = AssetHelper.FindAssetClassByID(am.classFile, afi.curFileType); AssetTypeTemplateField pBaseField = new AssetTypeTemplateField(); pBaseField.FromClassDatabase(am.classFile, cldt, 0); AssetTypeInstance mainAti = new AssetTypeInstance(1, new[] { pBaseField }, af.reader, false, afi.absoluteFilePos); AssetTypeTemplateField[] desMonos; desMonos = TryDeserializeMono(mainAti, am, folderPath); if (desMonos != null) { AssetTypeTemplateField[] templateField = pBaseField.children.Concat(desMonos).ToArray(); pBaseField.children = templateField; pBaseField.childrenCount = (uint)pBaseField.children.Length; mainAti = new AssetTypeInstance(1, new[] { pBaseField }, af.reader, false, afi.absoluteFilePos); } return(mainAti.GetBaseField()); }
private void Ttr_list_SelectedIndexChanged(object sender, EventArgs e) { TypeTree typeTree = file.typeTree; Type_0D type = typeTree.unity5Types[ttr_list.SelectedIndex]; if (type.typeFieldsExCount == 0) { ClassDatabaseType cldt = cldb.classes.First(c => c.classId == type.classId); ttr_type.Text = cldt.name.GetString(cldb); } else { TypeField_0D baseField = type.typeFieldsEx[0]; ttr_type.Text = baseField.GetTypeString(type.stringTable); } ttr_typeid.Text = type.classId.ToString(); ttr_scriptid.Text = type.scriptIndex.ToString(); if (type.typeHash1 != 0 || type.typeHash2 != 0 || type.typeHash3 != 0 || type.typeHash4 != 0) { ttr_hash.Text = $"{type.typeHash1.ToString("x8")}{type.typeHash2.ToString("x8")}{type.typeHash3.ToString("x8")}{type.typeHash4.ToString("x8")}"; } else { ttr_hash.Text = ""; } if (type.scriptHash1 != 0 || type.scriptHash2 != 0 || type.scriptHash3 != 0 || type.scriptHash4 != 0) { ttr_monohash.Text = $"{type.scriptHash1.ToString("x8")}{type.scriptHash2.ToString("x8")}{type.scriptHash3.ToString("x8")}{type.scriptHash4.ToString("x8")}"; } else { ttr_monohash.Text = ""; } if (typeTree.hasTypeTree) { GenerateTtrTree(type); } }
private void LoadGeneric(AssetsFileInstance mainFile, bool isLevel) { //Dictionary<string, AssetDetails> paths = new Dictionary<string, AssetDetails>(); List <AssetDetails> assets = new List <AssetDetails>(); foreach (AssetFileInfoEx info in mainFile.table.pAssetFileInfo) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType); if (type == null) { continue; } string typeName = type.name.GetString(helper.classFile); if (typeName != "GameObject" && isLevel) { continue; } string name = AssetInfo.GetAssetNameFast(info, helper.classFile, type, mainFile); if (name == "") { name = "[Unnamed]"; } //int count = 0; //string newName = name; //while (paths.Keys.Contains(newName)/* && count < 20*/) //{ // count++; // newName = $"{name} ({count})"; //} //if (count < 20) //{ //paths[newName] = new AssetDetails(new AssetPPtr(0, info.index), name, typeName, (int)info.curFileSize); assets.Add(new AssetDetails(new AssetPPtr(0, info.index), GetIconForName(typeName), name, typeName, (int)info.curFileSize)); //} } rootDir = new FSDirectory(); //rootDir.Create(paths); rootDir.Create(assets); ChangeDirectory(""); }
private void PopulateTree() { ClassDatabaseType cldt = AssetHelper.FindAssetClassByID(am.initialClassFile, assetDetails.type); AssetTypeTemplateField baseFieldTemp = new AssetTypeTemplateField(); baseFieldTemp.FromClassDatabase(am.initialClassFile, cldt, 0); mainAti = new AssetTypeInstance(new[] { baseFieldTemp }, af.reader, assetDetails.position); if (assetDetails.type == 0x72) { AssetTypeTemplateField[] desMonos = TryDeserializeMono(mainAti); if (desMonos != null) { AssetTypeTemplateField[] templateField = baseFieldTemp.children.Concat(desMonos).ToArray(); baseFieldTemp.children = templateField; baseFieldTemp.childrenCount = baseFieldTemp.children.Length; mainAti = new AssetTypeInstance(new[] { baseFieldTemp }, af.reader, assetDetails.position); } } AssetTypeValueField baseField = mainAti.GetBaseField(); rawViewTree.Nodes.Add(baseField.GetFieldType() + " " + baseField.GetName()); RecursiveTreeLoad(mainAti.GetBaseField(), rawViewTree.Nodes[0], 0); }
private string GetAssetNameFastModded(AssetsFile file, ClassDatabaseFile cldb, AssetFileInfoEx info) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(cldb, info.curFileType); AssetsFileReader reader = file.reader; if (type.fields.Count == 0) { return(type.name.GetString(cldb)); } if (type.fields.Count > 1 && type.fields[1].fieldName.GetString(cldb) == "m_Name") { reader.Position = info.absoluteFilePos; return(reader.ReadCountStringInt32()); } else if (type.name.GetString(cldb) == "GameObject") { reader.Position = info.absoluteFilePos; int size = reader.ReadInt32(); int componentSize = file.header.format > 0x10 ? 0xC : 0x10; reader.Position += size * componentSize; reader.Position += 4; return(reader.ReadCountStringInt32()); } else if (type.name.GetString(cldb) == "MonoBehaviour") { reader.Position = info.absoluteFilePos; reader.Position += 28; string name = reader.ReadCountStringInt32(); if (name != "") { return(name); } } return($"pathId_{info.index}"); }
//codeflow needs work but should be fine for now public static void GetUABENameFast(AssetsFile file, ClassDatabaseFile cldb, AssetsFileReader reader, long filePosition, uint classId, ushort monoId, out string assetName, out string typeName) { ClassDatabaseType type = AssetHelper.FindAssetClassByID(cldb, classId); if (file.typeTree.hasTypeTree) { Type_0D ttType; if (classId == 0x72) { ttType = AssetHelper.FindTypeTreeTypeByScriptIndex(file.typeTree, monoId); } else { ttType = AssetHelper.FindTypeTreeTypeByID(file.typeTree, classId); } if (ttType != null && ttType.typeFieldsEx.Length != 0) { typeName = ttType.typeFieldsEx[0].GetTypeString(ttType.stringTable); if (ttType.typeFieldsEx.Length > 1 && ttType.typeFieldsEx[1].GetNameString(ttType.stringTable) == "m_Name") { reader.Position = filePosition; assetName = reader.ReadCountStringInt32(); if (assetName == "") { assetName = "Unnamed asset"; } return; } else if (typeName == "GameObject") { reader.Position = filePosition; int size = reader.ReadInt32(); int componentSize = file.header.format > 0x10 ? 0x0c : 0x10; reader.Position += size * componentSize; reader.Position += 0x04; assetName = reader.ReadCountStringInt32(); assetName = $"GameObject {assetName}"; return; } else if (typeName == "MonoBehaviour") { reader.Position = filePosition; reader.Position += 0x1c; assetName = reader.ReadCountStringInt32(); if (assetName == "") { assetName = "Unnamed asset"; } return; } assetName = "Unnamed asset"; return; } } if (type == null) { typeName = $"0x{classId:X8}"; assetName = "Unnamed asset"; return; } typeName = type.name.GetString(cldb); if (type.fields.Count == 0) { assetName = "Unnamed asset"; return; } if (type.fields.Count > 1 && type.fields[1].fieldName.GetString(cldb) == "m_Name") { reader.Position = filePosition; assetName = reader.ReadCountStringInt32(); if (assetName == "") { assetName = "Unnamed asset"; } return; } else if (typeName == "GameObject") { reader.Position = filePosition; int size = reader.ReadInt32(); int componentSize = file.header.format > 0x10 ? 0x0c : 0x10; reader.Position += size * componentSize; reader.Position += 0x04; assetName = reader.ReadCountStringInt32(); assetName = $"GameObject {assetName}"; return; } else if (typeName == "MonoBehaviour") { reader.Position = filePosition; reader.Position += 0x1c; assetName = reader.ReadCountStringInt32(); if (assetName == "") { assetName = "Unnamed asset"; } return; } assetName = "Unnamed asset"; return; }
private void GetTk2dSprites(AssetsFileInstance inst) { collections = new List <TkSpriteCollection>(); animations = new List <TkSpriteAnimation>(); animationClips = new List <TkSpriteAnimationClip>(); List <TkSpriteFrame> sprFrames = new List <TkSpriteFrame>(); string managedPath = Path.Combine(Path.GetDirectoryName(inst.path), "Managed"); Dictionary <AssetID, TkSpriteCollection> collectionLookup = new Dictionary <AssetID, TkSpriteCollection>(); int tk2dSCid = -1; int tk2dSAid = -1; foreach (AssetFileInfoEx mbInf in inst.table.GetAssetsOfType(0x72)) { string scriptName = null; ushort scriptIndex = AssetHelper.GetScriptIndex(inst.file, mbInf); if (tk2dSCid != -1 && scriptIndex == tk2dSCid) { scriptName = "tk2dSpriteCollectionData"; } else if (tk2dSAid != -1 && scriptIndex == tk2dSAid) { scriptName = "tk2dSpriteAnimation"; } if (tk2dSCid == -1 || tk2dSAid == -1) //still looking for script ids { AssetTypeValueField mbBase = am.GetATI(inst.file, mbInf).GetBaseField(); AssetTypeValueField scBase = am.GetExtAsset(inst, mbBase.Get("m_Script")).instance.GetBaseField(); scriptName = scBase.Get("m_Name").GetValue().AsString(); if (scriptName == "tk2dSpriteCollectionData") { tk2dSCid = scriptIndex; } else if (scriptName == "tk2dSpriteAnimation") { tk2dSAid = scriptIndex; } else { continue; //nope, nobody cares } } if (scriptName == null) { continue; } AssetTypeValueField mbSerialBase = am.GetMonoBaseFieldCached(inst, mbInf, managedPath); if (scriptName == "tk2dSpriteCollectionData") { AssetTypeValueField textures = mbSerialBase.Get("textures"); List <AssetExternal> textureExts = new List <AssetExternal>(); List <int> textureWidths = new List <int>(); List <int> textureHeights = new List <int>(); for (int i = 0; i < textures.childrenCount; i++) { AssetExternal textureExt = am.GetExtAsset(inst, mbSerialBase.Get("textures")[i], true); if (textureExt.info.curFileSize > 100000) { //bad news, unity probably stored the entire image into an array which is gonna //take up too much memory when we decode it, so we'll change the data to a byte array ClassDatabaseType textureType = AssetHelper.FindAssetClassByID(am.classFile, textureExt.info.curFileType); AssetTypeTemplateField textureTemp = new AssetTypeTemplateField(); textureTemp.FromClassDatabase(am.classFile, textureType, 0); AssetTypeTemplateField image_data = textureTemp.children[textureTemp.childrenCount - 1]; image_data.valueType = EnumValueTypes.ByteArray; //convert array to bytearray, much better AssetTypeInstance textureTypeInstance = new AssetTypeInstance(new[] { textureTemp }, inst.file.reader, textureExt.info.absoluteFilePos); AssetTypeValueField textureBase = textureTypeInstance.GetBaseField(); textureExt.instance = textureTypeInstance; textureExts.Add(textureExt); textureWidths.Add(textureBase.Get("m_Width").GetValue().AsInt()); textureHeights.Add(textureBase.Get("m_Height").GetValue().AsInt()); } else { textureExt = am.GetExtAsset(inst, mbSerialBase.Get("textures")[i]); AssetTypeValueField textureBase = textureExt.instance.GetBaseField(); textureExts.Add(textureExt); textureWidths.Add(textureBase.Get("m_Width").GetValue().AsInt()); textureHeights.Add(textureBase.Get("m_Height").GetValue().AsInt()); } } TkSpriteCollection collection = new TkSpriteCollection() { name = mbSerialBase.Get("spriteCollectionName").GetValue().AsString(), version = mbSerialBase.Get("version").GetValue().AsInt(), baseTexture = null, //do later textures = new Dictionary <int, Bitmap>(), //same textureExts = textureExts, sprites = new List <TkSpriteDefinition>() }; collectionLookup[new AssetID(inst.name, mbInf.index)] = collection; AssetTypeValueField spriteDefinitions = mbSerialBase.Get("spriteDefinitions"); foreach (AssetTypeValueField def in spriteDefinitions.children) { bool flipped = def.Get("flipped").GetValue().AsInt() == 1; int materialId = def.Get("materialId").GetValue().AsInt(); int textureWidth = textureWidths[materialId]; int textureHeight = textureHeights[materialId]; double uxn = double.MaxValue; double uxp = 0; double uyn = double.MaxValue; double uyp = 0; double pxn = double.MaxValue; double pyn = double.MaxValue; AssetTypeValueField positions = def.Get("positions"); AssetTypeValueField uvs = def.Get("uvs"); for (int i = 0; i < 4; i++) { AssetTypeValueField pos = positions[i]; AssetTypeValueField uv = uvs[i]; double posX = pos.Get("x").GetValue().AsFloat(); double posY = pos.Get("y").GetValue().AsFloat(); double uvX = Math.Round(uv.Get("x").GetValue().AsFloat() * textureWidth); double uvY = textureHeight - Math.Round(uv.Get("y").GetValue().AsFloat() * textureHeight); if (posX < pxn) { pxn = posX; } if (posY < pyn) { pyn = posY; } if (uvX < uxn) { uxn = uvX; } if (uvX > uxp) { uxp = uvX; } if (uvY < uyn) { uyn = uvY; } if (uvY > uyp) { uyp = uvY; } } int spriteX = (int)uxn; int spriteY = (int)uyn; int spriteWidth = (int)(uxp - uxn); int spriteHeight = (int)(uyp - uyn); AssetTypeValueField boundsData = def.Get("boundsData"); AssetTypeValueField untrimmedBoundsData = def.Get("untrimmedBoundsData"); AssetTypeValueField texelSize = def.Get("texelSize"); float texelX = texelSize.Get("x").GetValue().AsFloat(); float texelY = texelSize.Get("y").GetValue().AsFloat(); float realX = ((float)pxn) / texelX; float realY = -((flipped ? spriteWidth : spriteHeight) + ((float)pyn) / texelY); TkSpriteDefinition sprite = new TkSpriteDefinition() { parent = collection, name = def.Get("name").GetValue().AsString(), x = spriteX, y = spriteY, width = spriteWidth, height = spriteHeight, xOff = realX, yOff = realY, materialId = materialId, fullWidth = untrimmedBoundsData[1].Get("x").GetValue().AsFloat() / texelX, fullHeight = untrimmedBoundsData[1].Get("y").GetValue().AsFloat() / texelY, flipped = flipped }; collection.sprites.Add(sprite); } collections.Add(collection); } else if (scriptName == "tk2dSpriteAnimation") { AssetFileInfoEx gameObjectInfo = inst.table.GetAssetInfo(mbSerialBase.Get("m_GameObject").Get("m_PathID").GetValue().AsInt64()); TkSpriteAnimation animation = new TkSpriteAnimation() { parents = new List <TkSpriteCollection>(), //do later parentIds = new List <AssetID>(), gameObjectName = AssetHelper.GetAssetNameFast(inst.file, am.classFile, gameObjectInfo), clips = new List <TkSpriteAnimationClip>() }; AssetTypeValueField clips = mbSerialBase.Get("clips"); foreach (AssetTypeValueField clip in clips.children) { TkSpriteAnimationClip aniClip = new TkSpriteAnimationClip() { parent = animation, name = clip.Get("name").GetValue().AsString(), fps = clip.Get("fps").GetValue().AsFloat(), loopStart = clip.Get("loopStart").GetValue().AsInt(), wrapMode = (WrapMode)clip.Get("wrapMode").GetValue().AsInt(), frames = new List <TkSpriteFrame>() }; animation.clips.Add(aniClip); animationClips.Add(aniClip); AssetTypeValueField frames = clip.Get("frames"); foreach (AssetTypeValueField frame in frames.children) { AssetExternal collectionExt = am.GetExtAsset(inst, frame.Get("spriteCollection")); AssetID collectionId = new AssetID(collectionExt.file.name, collectionExt.info.index); if (!animation.parentIds.Contains(collectionId)) { animation.parentIds.Add(collectionId); } TkSpriteFrame sprFrame = new TkSpriteFrame() { collection = null, //do later collectionId = collectionId, spriteId = frame.Get("spriteId").GetValue().AsInt() }; sprFrames.Add(sprFrame); aniClip.frames.Add(sprFrame); } } animations.Add(animation); } } foreach (TkSpriteAnimation animation in animations) { foreach (AssetID parentId in animation.parentIds) { if (collectionLookup.ContainsKey(parentId)) { animation.parents.Add(collectionLookup[parentId]); } } } foreach (TkSpriteFrame frame in sprFrames) { if (collectionLookup.ContainsKey(frame.collectionId)) { frame.collection = collectionLookup[frame.collectionId]; } } }
public static void GenerateLevelFiles(AssetsManager am, AssetsFileInstance inst) { EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f); am.UpdateDependencies(); //quicker asset id lookup for (int i = 0; i < am.files.Count; i++) { AssetsFileInstance afi = am.files[i]; if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Generating QLTs...", (float)i / am.files.Count); } afi.table.GenerateQuickLookupTree(); } ClassDatabaseFile cldb = am.classFile; AssetsFileTable table = inst.table; ReferenceCrawler crawler = new ReferenceCrawler(am); List <AssetFileInfoEx> initialGameObjects = table.GetAssetsOfType(0x01); for (int i = 0; i < initialGameObjects.Count; i++) { if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Recursing GameObject dependencies... (step 1/3)", (float)i / initialGameObjects.Count); } AssetFileInfoEx inf = initialGameObjects[i]; crawler.AddReference(new AssetID(inst.path, (long)inf.index), false); crawler.FindReferences(inst, inf); } Dictionary <AssetID, AssetID> glblToLcl = crawler.references; List <Type_0D> types = new List <Type_0D>(); List <string> typeNames = new List <string>(); Dictionary <string, AssetsFileInstance> fileToInst = am.files.ToDictionary(d => d.path); int j = 0; foreach (KeyValuePair <AssetID, AssetID> id in glblToLcl) { if (j % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Rewiring asset pointers... (step 2/3)", (float)j / glblToLcl.Count); } AssetsFileInstance depInst = fileToInst[id.Key.fileName]; AssetFileInfoEx depInf = depInst.table.getAssetInfo((ulong)id.Key.pathId); ClassDatabaseType clType = AssetHelper.FindAssetClassByID(cldb, depInf.curFileType); string clName = clType.name.GetString(cldb); if (!typeNames.Contains(clName)) { Type_0D type0d = C2T5.Cldb2TypeTree(cldb, clName); type0d.classId = (int)depInf.curFileType; types.Add(type0d); typeNames.Add(clName); } crawler.ReplaceReferences(depInst, depInf, id.Value.pathId); j++; } EditorUtility.DisplayProgressBar("HKEdit", "Saving scene... (step 3/3)", 1f); types.Add(CreateEditDifferTypeTree(cldb)); List <Type_0D> assetTypes = new List <Type_0D>() { C2T5.Cldb2TypeTree(cldb, 0x1c), C2T5.Cldb2TypeTree(cldb, 0x30), C2T5.Cldb2TypeTree(cldb, 0x53) }; string origFileName = Path.GetFileNameWithoutExtension(inst.path); string sceneGuid = CreateMD5(origFileName); string ExportedScenes = Path.Combine("Assets", "ExportedScenes"); //circumvents "!BeginsWithCaseInsensitive(file.pathName, AssetDatabase::kAssetsPathWithSlash)' assertion string ExportedScenesData = "ExportedScenesData"; CreateMetaFile(sceneGuid, Path.Combine(ExportedScenes, origFileName + ".unity.meta")); AssetsFile sceneFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(ver, types)))); AssetsFile assetFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(ver, assetTypes)))); byte[] sceneFileData; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; //unity editor won't load whole assets files by guid, so we have to use hardcoded paths sceneFile.dependencies.pDependencies = new AssetsFileDependency[] { CreateDependency(ExportedScenesData + "/" + origFileName + "-data.assets"), CreateScriptDependency(Constants.editDifferMsEditorScriptHash, Constants.editDifferLsEditorScriptHash) }; sceneFile.dependencies.dependencyCount = 2; sceneFile.preloadTable.items = new AssetPPtr[] { new AssetPPtr(2, 11500000) }; sceneFile.preloadTable.len = 1; sceneFile.Write(w, 0, crawler.sceneReplacers.Concat(crawler.sceneMonoReplacers).ToArray(), 0); sceneFileData = ms.ToArray(); } byte[] assetFileData; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; assetFile.Write(w, 0, crawler.assetReplacers.ToArray(), 0); assetFileData = ms.ToArray(); } File.WriteAllBytes(Path.Combine(ExportedScenes, origFileName + ".unity"), sceneFileData); File.WriteAllBytes(Path.Combine(ExportedScenesData, origFileName + "-data.assets"), assetFileData); File.WriteAllText(Path.Combine(ExportedScenesData, origFileName + ".metadata"), CreateHKWEMetaFile(am, inst)); EditorUtility.ClearProgressBar(); }
public static Type_0D Cldb2TypeTree(ClassDatabaseFile classes, string name) { ClassDatabaseType type = AssetHelper.FindAssetClassByName(classes, name); return(Cldb2TypeTree(classes, type)); }
private void AddAssetItem(AssetsFile af, AssetFileInfoEx afi, AssetsFileReader worker, uint fileId) { uint classId; ushort monoId; if (af.header.format <= 0x10) { classId = afi.inheritedUnityClass; if (classId == 0x72) { monoId = (ushort)(0xFFFFFFFF - afi.curFileTypeOrIndex); } else { monoId = 0xFFFF; } } else { classId = (uint)af.typeTree.pTypes_Unity5[afi.curFileTypeOrIndex].classId; monoId = af.typeTree.pTypes_Unity5[afi.curFileTypeOrIndex].scriptIndex; } ClassDatabaseType type = AssetHelper.FindAssetClassByID(assetsManager.initialClassFile, classId); if (type == null) { string tfileID = fileId.ToString(); string tpathID = unchecked ((long)afi.index).ToString(); string tsize = afi.curFileSize.ToString(); string tmodified = ""; string[] titems = new string[] { "Unknown", "??? Custom ???", tfileID, tpathID, tsize, tmodified }; assetDetails.Add( new AssetDetails( "Unknown", "??? Custom ???", afi.index, fileId, classId, afi.absoluteFilePos, monoId ) ); System.Diagnostics.Debug.WriteLine("unknown id " + tpathID + " classid " + afi.curFileType); assetList.Items.Add(new ListViewItem(titems)); return; } string assetName; if (classId == 0x72) { assetName = ""; } else { assetName = GetAssetNameFast(afi, assetsManager.initialClassFile, type, worker); } string assetType = type.name.GetString(assetsManager.initialClassFile); string fileID = fileId.ToString(); string pathID = unchecked ((long)afi.index).ToString(); string size = afi.curFileSize.ToString(); string modified = ""; if (assetName.Trim() == "") { assetName = assetType; //todo, seems redundant now, check on this later } string[] items = new string[] { assetName, assetType, fileID, pathID, size, modified }; assetDetails.Add( new AssetDetails( assetName, assetType, afi.index, fileId, classId, afi.absoluteFilePos, monoId ) ); assetList.Items.Add(new ListViewItem(items)); }
public static Type_0D Cldb2TypeTree(ClassDatabaseFile classes, int id) { ClassDatabaseType type = classes.classes.Where(c => c.classId == id).First(); Type_0D type0d = new Type_0D() { classId = type.classId, typeFieldsExCount = (uint)type.fields.Count, scriptIndex = 0xFFFF, unknown16_1 = 0, scriptHash1 = 0, scriptHash2 = 0, scriptHash3 = 0, scriptHash4 = 0, typeHash1 = 0, typeHash2 = 0, typeHash3 = 0, typeHash4 = 0 }; string stringTable = ""; Dictionary <string, uint> strTableList = new Dictionary <string, uint>(); Dictionary <string, uint> defTableList = new Dictionary <string, uint>(); uint strTablePos = 0; uint defTablePos = 0; string[] defaultTable = Type_0D.strTable.Split('\0'); foreach (string entry in defaultTable) { if (entry != "") { defTableList.Add(entry, defTablePos); defTablePos += (uint)entry.Length + 1; } } List <TypeField_0D> field0ds = new List <TypeField_0D>(); for (int i = 0; i < type.fields.Count; i++) { ClassDatabaseTypeField field = type.fields[i]; string fieldName = field.fieldName.GetString(classes); string typeName = field.typeName.GetString(classes); uint fieldNamePos = 0xFFFFFFFF; uint typeNamePos = 0xFFFFFFFF; if (strTableList.ContainsKey(fieldName)) { fieldNamePos = strTableList[fieldName]; } else if (defTableList.ContainsKey(fieldName)) { fieldNamePos = defTableList[fieldName] + 0x80000000; } else { fieldNamePos = strTablePos; strTableList.Add(fieldName, strTablePos); strTablePos += (uint)fieldName.Length + 1; } if (strTableList.ContainsKey(typeName)) { typeNamePos = strTableList[typeName]; } else if (defTableList.ContainsKey(typeName)) { typeNamePos = defTableList[typeName] + 0x80000000; } else { typeNamePos = strTablePos; strTableList.Add(typeName, strTablePos); strTablePos += (uint)typeName.Length + 1; } field0ds.Add(new TypeField_0D() { depth = field.depth, flags = field.flags2, index = (uint)i, isArray = field.isArray, nameStringOffset = fieldNamePos, size = field.size, typeStringOffset = typeNamePos, version = field.version }); } List <KeyValuePair <string, uint> > sortedStrTableList = strTableList.OrderBy(n => n.Value).ToList(); foreach (KeyValuePair <string, uint> entry in sortedStrTableList) { stringTable += entry.Key + '\0'; } type0d.stringTable = stringTable; type0d.stringTableLen = (uint)stringTable.Length; type0d.typeFieldsEx = field0ds.ToArray(); return(type0d); }
public static string GetAssetNameFast(AssetsFile file, ClassDatabaseFile cldb, AssetFileInfoEx info) { ClassDatabaseType type = FindAssetClassByID(cldb, info.curFileType); AssetsFileReader reader = file.reader; if (file.typeTree.hasTypeTree) { Type_0D ttType = file.typeTree.unity5Types[info.curFileTypeOrIndex]; string ttTypeName = ttType.typeFieldsEx[0].GetTypeString(ttType.stringTable); if (ttType.typeFieldsEx.Length == 0) { return(type.name.GetString(cldb)); //fallback to cldb } if (ttType.typeFieldsEx.Length > 1 && ttType.typeFieldsEx[1].GetNameString(ttType.stringTable) == "m_Name") { reader.Position = info.absoluteFilePos; return(reader.ReadCountStringInt32()); } //todo, use the typetree since we have it already, there could be extra fields else if (ttTypeName == "GameObject") { reader.Position = info.absoluteFilePos; int size = reader.ReadInt32(); int componentSize = file.header.format > 0x10 ? 0x0c : 0x10; reader.Position += size * componentSize; reader.Position += 0x04; return(reader.ReadCountStringInt32()); } else if (ttTypeName == "MonoBehaviour") { reader.Position = info.absoluteFilePos; reader.Position += 0x1c; string name = reader.ReadCountStringInt32(); if (name != "") { return(name); } } return(ttTypeName); } string typeName = type.name.GetString(cldb); if (type.fields.Count == 0) { return(type.name.GetString(cldb)); } if (type.fields.Count > 1 && type.fields[1].fieldName.GetString(cldb) == "m_Name") { reader.Position = info.absoluteFilePos; return(reader.ReadCountStringInt32()); } else if (typeName == "GameObject") { reader.Position = info.absoluteFilePos; int size = reader.ReadInt32(); int componentSize = file.header.format > 0x10 ? 0x0c : 0x10; reader.Position += size * componentSize; reader.Position += 0x04; return(reader.ReadCountStringInt32()); } else if (typeName == "MonoBehaviour") { reader.Position = info.absoluteFilePos; reader.Position += 0x1c; string name = reader.ReadCountStringInt32(); if (name != "") { return(name); } } return(typeName); }
private ObservableCollection <AssetInfoDataGridItem> MakeDataGridItems() { dataGridItems = new ObservableCollection <AssetInfoDataGridItem>(); bool usingTypeTree = assetsFile.file.typeTree.hasTypeTree; foreach (AssetFileInfoEx info in assetsFile.table.assetFileInfo) { string name; string container; string type; int fileId; long pathId; int size; string modified; ClassDatabaseType cldbType = AssetHelper.FindAssetClassByID(am.classFile, info.curFileType); name = AssetHelper.GetAssetNameFast(assetsFile.file, am.classFile, info); //handles both cldb and typetree container = string.Empty; fileId = 0; pathId = info.index; size = (int)info.curFileSize; modified = ""; if (usingTypeTree) { Type_0D ttType = assetsFile.file.typeTree.unity5Types[info.curFileTypeOrIndex]; if (ttType.typeFieldsEx.Length != 0) { type = ttType.typeFieldsEx[0].GetTypeString(ttType.stringTable); } else { if (cldbType != null) { type = cldbType.name.GetString(am.classFile); } else { type = $"0x{info.curFileType:X8}"; } } } else { if (cldbType != null) { type = cldbType.name.GetString(am.classFile); } else { type = $"0x{info.curFileType:X8}"; } } if (info.curFileType == 0x01) { name = $"GameObject {name}"; } if (name == string.Empty) { name = "Unnamed asset"; } var item = new AssetInfoDataGridItem() { Name = name, Container = container, Type = type, TypeID = info.curFileType, FileID = fileId, PathID = pathId, Size = size, Modified = modified }; dataGridItems.Add(item); } return(dataGridItems); }