///////////////////////////////////////////////////////// private static Type_0D CreateEditDifferTypeTree(ClassDatabaseFile cldb) { Type_0D type = C2T5.Cldb2TypeTree(cldb, 0x72); type.scriptIndex = 0x0000; type.unknown1 = Constants.editDifferScriptNEHash[0]; type.unknown2 = Constants.editDifferScriptNEHash[1]; type.unknown3 = Constants.editDifferScriptNEHash[2]; type.unknown4 = Constants.editDifferScriptNEHash[3]; TypeTreeEditor editor = new TypeTreeEditor(type); TypeField_0D baseField = type.pTypeFieldsEx[0]; editor.AddField(baseField, editor.CreateTypeField("unsigned int", "fileId", 1, 4, 0, false)); editor.AddField(baseField, editor.CreateTypeField("UInt64", "pathId", 1, 8, 0, false)); editor.AddField(baseField, editor.CreateTypeField("UInt64", "origPathId", 1, 8, 0, false)); editor.AddField(baseField, editor.CreateTypeField("UInt8", "newAsset", 1, 1, 0, true)); uint componentIds = editor.AddField(baseField, editor.CreateTypeField("vector", "componentIds", 1, uint.MaxValue, 0, false, false, Flags.AnyChildUsesAlignBytesFlag)); uint Array = editor.AddField(editor.type.pTypeFieldsEx[componentIds], editor.CreateTypeField("Array", "Array", 2, uint.MaxValue, 0, true, true)); editor.AddField(editor.type.pTypeFieldsEx[Array], editor.CreateTypeField("int", "size", 3, 4, 0, false)); editor.AddField(editor.type.pTypeFieldsEx[Array], editor.CreateTypeField("SInt64", "data", 3, 8, 0, false)); editor.AddField(baseField, editor.CreateTypeField("int", "instanceId", 1, 4, 0, false)); type = editor.SaveType(); return(type); }
public void UnloadAll() { UnloadAllAssetsFiles(true); UnloadAllBundleFiles(); classPackage = null; classFile = null; }
public static string GetAssetNameFast(AssetFileInfoEx afi, ClassDatabaseFile cldb, ClassDatabaseType type, AssetsFileInstance inst) { AssetsFileReader reader = inst.file.reader; if (type.fields.Count < 2) { return(type.name.GetString(cldb)); } else 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 += 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 static ClassDatabaseType FindAssetClassByID(ClassDatabaseFile cldb, uint id) { uint fixedId = id; if (fixedId == 0xf1) //AudioMixerController { fixedId = 0xf0; //AudioMixer } else if (fixedId == 0xf3) //AudioMixerGroupController { fixedId = 0x111; //AudioMixerGroup } else if (fixedId == 0xf5) //AudioMixerSnapshotController { fixedId = 0x110; //AudioMixerSnapshot } foreach (ClassDatabaseType type in cldb.classes) { if (type.classId == fixedId) { return(type); } } return(null); }
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 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)); }
private static void CreateSceneMetadataTypeTree(ClassDatabaseFile cldb, AssetsFileInstance inst) { Type_0D type = C2T5.Cldb2TypeTree(cldb, 0x72); type.scriptIndex = 0x0001; type.unknown1 = Constants.sceneMetadataScriptNEHash[0]; type.unknown2 = Constants.sceneMetadataScriptNEHash[1]; type.unknown3 = Constants.sceneMetadataScriptNEHash[2]; type.unknown4 = Constants.sceneMetadataScriptNEHash[3]; TypeTreeEditor editor = new TypeTreeEditor(type); TypeField_0D baseField = type.pTypeFieldsEx[0]; uint sceneName = editor.AddField(baseField, editor.CreateTypeField("string", "sceneName", 1, uint.MaxValue, 0, false, false, Flags.AnyChildUsesAlignBytesFlag)); uint Array = editor.AddField(editor.type.pTypeFieldsEx[sceneName], editor.CreateTypeField("Array", "Array", 2, uint.MaxValue, 0, true, true, Flags.HideInEditorMask)); editor.AddField(editor.type.pTypeFieldsEx[Array], editor.CreateTypeField("int", "size", 3, 4, 0, false, false, Flags.HideInEditorMask)); editor.AddField(editor.type.pTypeFieldsEx[Array], editor.CreateTypeField("char", "data", 3, 1, 0, false, false, Flags.HideInEditorMask)); uint usedIds = editor.AddField(baseField, editor.CreateTypeField("vector", "usedIds", 1, uint.MaxValue, 0, false, false, Flags.AnyChildUsesAlignBytesFlag)); uint Array2 = editor.AddField(editor.type.pTypeFieldsEx[usedIds], editor.CreateTypeField("Array", "Array", 2, uint.MaxValue, 0, true, true)); editor.AddField(editor.type.pTypeFieldsEx[Array2], editor.CreateTypeField("int", "size", 3, 4, 0, false)); editor.AddField(editor.type.pTypeFieldsEx[Array2], editor.CreateTypeField("SInt64", "data", 3, 8, 0, false)); editor.AddField(baseField, editor.CreateTypeField("int", "hkweVersion", 1, 4, 0, false)); type = editor.SaveType(); inst.file.typeTree.pTypes_Unity5 = inst.file.typeTree.pTypes_Unity5.Concat(new Type_0D[] { type }).ToArray(); inst.file.typeTree.fieldCount++; }
private void btnOK_Click(object sender, EventArgs e) { if (lboxVersionList.SelectedItem is ClassFileInfo classTypeInf) { SelectedCldb = classTypeInf.Cldb; } Close(); }
public bool Read(AssetsFileReader reader, bool prefReplacersInMemory = false) { reader.bigEndian = false; magic = reader.ReadStringLength(4); if (magic != "EMIP") { return(false); } includesCldb = reader.ReadByte() != 0; modName = reader.ReadCountStringInt16(); modCreators = reader.ReadCountStringInt16(); modDescription = reader.ReadCountStringInt16(); if (includesCldb) { addedTypes = new ClassDatabaseFile(); addedTypes.Read(reader); //get past the string table since the reader goes back to the beginning reader.Position = addedTypes.header.stringTablePos + addedTypes.header.stringTableLen; } else { addedTypes = null; } int affectedFilesCount = reader.ReadInt32(); affectedFiles = new List <InstallerPackageAssetsDesc>(); for (int i = 0; i < affectedFilesCount; i++) { List <object> replacers = new List <object>(); InstallerPackageAssetsDesc desc = new InstallerPackageAssetsDesc() { isBundle = reader.ReadByte() != 0, path = reader.ReadCountStringInt16() }; int replacerCount = reader.ReadInt32(); for (int j = 0; j < replacerCount; j++) { object repObj = ParseReplacer(reader, prefReplacersInMemory); if (repObj is AssetsReplacer repAsset) { replacers.Add(repAsset); } else if (repObj is BundleReplacer repBundle) { replacers.Add(repBundle); } } desc.replacers = replacers; affectedFiles.Add(desc); } return(true); }
public ClassFileInfo(ClassDatabaseFile cldb) { Cldb = cldb; var unityVersions = cldb.header.unityVersions; var nonWildcardVersion = unityVersions.FirstOrDefault(v => !v.EndsWith(".*")); Name = nonWildcardVersion ?? unityVersions[0]; }
public IEnumerable <AssetFile> BuildAssetsFileInstance(Stream stream) { List <AssetFile> result = new List <AssetFile>(); classPackage = new ClassDatabasePackage(); Console.WriteLine("Reading class-data..."); using (var reader = new AssetsFileReader(new FileStream("classdata.tpk", FileMode.Open, FileAccess.Read, FileShare.Read))) { classPackage.Read(reader); } var file = new AssetBundleFile(); activeBundleFile = file; Console.WriteLine("Reading bundleFileStream..."); file.Read(new AssetsFileReader(stream), true); file.reader.Position = 0; Stream memoryStream = new MemoryStream(); Console.WriteLine("Unpacking bundleFile..."); file.Unpack(file.reader, new AssetsFileWriter(memoryStream)); memoryStream.Position = 0; file.Close(); file = new AssetBundleFile(); file.Read(new AssetsFileReader(memoryStream)); Console.WriteLine("file.bundleInf6.dirInf.Length: " + file.bundleInf6.dirInf.Length); for (int i = 0; i < file.bundleInf6.dirInf.Length; i++) { try { if (file.IsAssetsFile(file.reader, file.bundleInf6.dirInf[i])) { byte[] assetData = BundleHelper.LoadAssetDataFromBundle(file, i); var mainStream = new MemoryStream(assetData); activeStreams.Add(mainStream); string mainName = file.bundleInf6.dirInf[i].name; var fileInstance = new AssetsFileInstance(mainStream, mainName, ""); ClassDatabaseFile classDBFile = LoadClassDatabaseFromPackage(fileInstance.file.typeTree.unityVersion); if (classDBFile == null) { Console.WriteLine("classDatabaseFile was null? Okay, that's probably bad. Continuing anyway..."); } result.Add(new AssetFile(fileInstance, classDBFile)); } } catch (Exception e) { Console.WriteLine("caught exception while reading AssetsFile: " + e); //guess it's not an assetsFile then? } } Console.WriteLine("found " + result.Count + " AssetFiles"); return(result); }
public void UnloadAll(bool unloadClassData = false) { UnloadAllAssetsFiles(true); UnloadAllBundleFiles(); if (unloadClassData) { classPackage = null; classFile = null; } }
public static ClassDatabaseType FindAssetClassByID(ClassDatabaseFile cldb, uint id) { foreach (ClassDatabaseType type in cldb.classes) { if (type.classId == id) { return(type); } } return(null); }
public string GetString(ClassDatabaseFile file) { if (fromStringTable) { return(AssetsFileReader.ReadNullTerminatedArray(file.stringTable, str.stringTableOffset)); } else { return(str.@string); } }
public static ClassDatabaseType FindAssetClassByName(ClassDatabaseFile cldb, string name) { foreach (ClassDatabaseType type in cldb.classes) { if (type.name.GetString(cldb) == name) { return(type); } } return(null); }
private void GameObjectViewer_Load(object sender, EventArgs e) { //mono won't be able to do this so ignore it if (Type.GetType("Mono.Runtime") == null) { PInvoke.SetWindowTheme(goTree.Handle, "explorer", null); } valueGrid.PropertySort = PropertySort.Categorized; ClassDatabaseFile classFile = helper.classFile; AssetFileInfoEx info = inst.table.GetAssetInfo(selectedId); AssetTypeTemplateField typeTemplate = helper.GetTemplateBaseField(inst.file, info); string typeName = typeTemplate.type; if (typeName == "GameObject") { selectedGameObjectId = selectedId; AssetExternal firstExt = helper.GetExtAsset(inst, 0, selectedId); AssetExternal rootExt = GetRootGameObject(firstExt); PopulateHierarchyTree(null, rootExt); } else { bool hasGameObjectField = typeTemplate.children.Any(f => f.name == "m_GameObject"); if (hasGameObjectField) { AssetTypeValueField firstBaseField = helper.GetTypeInstance(inst.file, info).GetBaseField(); AssetExternal firstExt = helper.GetExtAsset(inst, firstBaseField.Get("m_GameObject")); if (firstExt.info != null) { selectedGameObjectId = firstExt.info.index; AssetExternal rootExt = GetRootGameObject(firstExt); PopulateHierarchyTree(null, rootExt); } else { TreeNode node = goTree.Nodes.Add($"[{typeName} (parentless)]"); node.Tag = helper.GetExtAsset(inst, 0, info.index); } } else { TreeNode node = goTree.Nodes.Add($"[{typeName}]"); node.Tag = helper.GetExtAsset(inst, 0, info.index); } } GetSelectedNodeData(); }
public ClassFileInfo(ClassDatabaseFile cldb) { this.cldb = cldb; string[] unityVersions = cldb.header.unityVersions; string? nonWildcardVersion = unityVersions.FirstOrDefault(v => !v.EndsWith(".*")); if (nonWildcardVersion != null) { name = nonWildcardVersion; } else { name = unityVersions[0]; } }
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); }
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(); } }
public ClassDatabaseFile LoadClassDatabaseFromPackage(string version, bool specific = false) { if (classPackage == null) { throw new Exception("No class package loaded!"); } if (specific) { if (!version.StartsWith("U")) { version = "U" + version; } int index = classPackage.header.files.FindIndex(f => f.name == version); if (index == -1) { return(null); } classFile = classPackage.files[index]; return(classFile); } else { if (version.StartsWith("U")) { version = version.Substring(1); } for (int i = 0; i < classPackage.files.Length; i++) { ClassDatabaseFile file = classPackage.files[i]; for (int j = 0; j < file.header.unityVersions.Length; j++) { string unityVersion = file.header.unityVersions[j]; if (WildcardMatches(version, unityVersion)) { classFile = file; return(classFile); } } } return(null); } }
private static Type_0D CreateTk2dEmuTypeTree(ClassDatabaseFile cldb) { Type_0D type = C2T5.Cldb2TypeTree(cldb, 0x72); type.scriptIndex = 0x0001; type.scriptHash1 = Constants.tk2dEmuScriptNEHash[0]; type.scriptHash2 = Constants.tk2dEmuScriptNEHash[1]; type.scriptHash3 = Constants.tk2dEmuScriptNEHash[2]; type.scriptHash4 = Constants.tk2dEmuScriptNEHash[3]; TypeTreeEditor editor = new TypeTreeEditor(type); TypeField_0D baseField = type.typeFieldsEx[0]; uint vertices = editor.AddField(baseField, editor.CreateTypeField("vector", "vertices", 1, -1, 0, false, false, Flags.AnyChildUsesAlignBytesFlag)); uint Array = editor.AddField(editor.type.typeFieldsEx[vertices], editor.CreateTypeField("Array", "Array", 2, -1, 0, true, true)); editor.AddField(editor.type.typeFieldsEx[Array], editor.CreateTypeField("int", "size", 3, 4, 0, false)); uint data = editor.AddField(editor.type.typeFieldsEx[Array], editor.CreateTypeField("Vector3", "data", 3, -1, 0, false)); editor.AddField(editor.type.typeFieldsEx[data], editor.CreateTypeField("float", "x", 4, 4, 0, false)); editor.AddField(editor.type.typeFieldsEx[data], editor.CreateTypeField("float", "y", 4, 4, 0, false)); editor.AddField(editor.type.typeFieldsEx[data], editor.CreateTypeField("float", "z", 4, 4, 0, false)); uint uvs = editor.AddField(baseField, editor.CreateTypeField("vector", "uvs", 1, -1, 0, false, false, Flags.AnyChildUsesAlignBytesFlag)); Array = editor.AddField(editor.type.typeFieldsEx[uvs], editor.CreateTypeField("Array", "Array", 2, -1, 0, true, true)); editor.AddField(editor.type.typeFieldsEx[Array], editor.CreateTypeField("int", "size", 3, 4, 0, false)); data = editor.AddField(editor.type.typeFieldsEx[Array], editor.CreateTypeField("Vector2", "data", 3, -1, 0, false)); editor.AddField(editor.type.typeFieldsEx[data], editor.CreateTypeField("float", "x", 4, 4, 0, false)); editor.AddField(editor.type.typeFieldsEx[data], editor.CreateTypeField("float", "y", 4, 4, 0, false)); uint indices = editor.AddField(baseField, editor.CreateTypeField("vector", "indices", 1, -1, 0, false, false, Flags.AnyChildUsesAlignBytesFlag)); Array = editor.AddField(editor.type.typeFieldsEx[indices], editor.CreateTypeField("Array", "Array", 2, -1, 0, true, true)); editor.AddField(editor.type.typeFieldsEx[Array], editor.CreateTypeField("int", "size", 3, 4, 0, false)); editor.AddField(editor.type.typeFieldsEx[Array], editor.CreateTypeField("int", "data", 3, 4, 0, false)); type = editor.SaveType(); return(type); }
public static string GetAssetNameFast(AssetFileInfoEx afi, ClassDatabaseFile cldb, ClassDatabaseType type, AssetsFileInstance inst) { AssetsFileReader reader = inst.file.reader; if (type.fields.Count == 0) { return(type.name.GetString(cldb)); } else if (type.fields.Count == 1) { // the dreamers lay sleeping to protect the vessel return(type.name.GetString(cldb)); } else 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 += 4UL; return(reader.ReadCountStringInt32()); } else if (type.name.GetString(cldb) == "MonoBehaviour") { reader.Position = afi.absoluteFilePos; reader.Position += 28UL; string name = reader.ReadCountStringInt32(); if (name != "") { return(name); } } return(type.name.GetString(cldb)); }
///////////////////////////////////////////////////////// private static void CreateEditDifferTypeTree(ClassDatabaseFile cldb, AssetsFileInstance inst) { Type_0D type = C2T5.Cldb2TypeTree(cldb, 0x72); type.scriptIndex = 0x0000; type.unknown1 = Constants.editDifferScriptNEHash[0]; type.unknown2 = Constants.editDifferScriptNEHash[1]; type.unknown3 = Constants.editDifferScriptNEHash[2]; type.unknown4 = Constants.editDifferScriptNEHash[3]; TypeTreeEditor editor = new TypeTreeEditor(type); TypeField_0D baseField = type.pTypeFieldsEx[0]; editor.AddField(baseField, editor.CreateTypeField("unsigned int", "fileId", 1, 4, 0, false)); editor.AddField(baseField, editor.CreateTypeField("UInt64", "pathId", 1, 8, 0, false)); editor.AddField(baseField, editor.CreateTypeField("UInt64", "origPathId", 1, 8, 0, false)); editor.AddField(baseField, editor.CreateTypeField("UInt8", "newAsset", 1, 1, 0, true)); editor.AddField(baseField, editor.CreateTypeField("int", "instanceId", 1, 4, 0, false)); type = editor.SaveType(); inst.file.typeTree.pTypes_Unity5 = inst.file.typeTree.pTypes_Unity5.Concat(new Type_0D[] { type }).ToArray(); inst.file.typeTree.fieldCount++; }
private bool TryParseClassDatabase(string typeIdText, bool createBlankAsset, out AssetTypeTemplateField tempField, out int typeId) { tempField = null; ClassDatabaseFile cldb = workspace.am.classFile; ClassDatabaseType cldbType; bool needsTypeId; if (int.TryParse(typeIdText, out typeId)) { cldbType = AssetHelper.FindAssetClassByID(cldb, (uint)typeId); needsTypeId = false; } else { cldbType = AssetHelper.FindAssetClassByName(cldb, typeIdText); needsTypeId = true; } if (cldbType == null) { return(false); } if (needsTypeId) { typeId = cldbType.classId; } if (createBlankAsset) { tempField = new AssetTypeTemplateField(); tempField.FromClassDatabase(cldb, cldbType, 0); } return(true); }
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}"); }
public void LoadClassFile(Stream stream) { classFile = stream; initialClassFile = new ClassDatabaseFile(); initialClassFile.Read(new AssetsFileReader(stream)); }
//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; }
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 void GetUABENameFast(AssetContainer cont, ClassDatabaseFile cldb, out string assetName, out string typeName) { GetUABENameFast(cont.FileInstance.file, cldb, cont.FileReader, cont.FilePosition, cont.ClassId, cont.MonoId, out assetName, out typeName); }
public ClassDatabaseFile LoadClassDatabase(Stream stream) { classFile = new ClassDatabaseFile(); classFile.Read(new AssetsFileReader(stream)); return(classFile); }