//if component doesn't know its father public GameObjectViewer(AssetsManager helper, AssetsFileInstance inst, AssetTypeValueField baseField, AssetFileInfoEx componentInfo) { InitializeComponent(); this.helper = helper; this.inst = inst; this.baseField = baseField; this.componentInfo = componentInfo; }
private static void FindNestedPointers(AssetsFileInstance file, AssetTypeValueField field, AssetFileInfoEx info, bool replace) { foreach (var child in field.pChildren) { if (child == null) { Debug.LogError("Found null child in under a " + field.GetFieldType() + " named " + field.GetName()); return; } if (!child.templateField.hasValue) { //not array of values either if (child.templateField.isArray && child.templateField.children[1].valueType != EnumValueTypes.ValueType_None) { return; } var type = child.templateField.type; if (type.StartsWith("PPtr<") && type.EndsWith(">") && child.childrenCount == 2) { var fileId = child.Get("m_FileID").GetValue().AsInt(); var pathId = child.Get("m_PathID").GetValue().AsInt64(); if (pathId == 0) { //Debug.LogWarning("A " + field.GetFieldType() + " called " + field.GetName() + " has a " + type + " child with a null path: " + pathId); continue; } var id = AssetID.FromPPtr(file, fileId, pathId); var asset = am.GetExtAsset(file, (uint)fileId, (ulong)pathId); var exists = pointers.ContainsKey(id); if (replace) { if (exists) { var newId = pointers[id]; var isSelfAsset = IsAsset(info); var isDepAsset = newId.fileName.Equals(ASSET_LEVEL_NAME); var newFileId = isDepAsset ^ isSelfAsset ? 1 : 0; child.Get("m_FileID").GetValue().Set(newFileId); child.Get("m_PathID").GetValue().Set(newId.pathId); } else { child.Get("m_FileID").GetValue().Set(0); child.Get("m_PathID").GetValue().Set(0); } } else { if (exists) { continue; } AddPointer(id, IsAsset(asset.info)); var baseField = asset.instance.GetBaseField(); if (asset.info.curFileType == 0x72) { var ms = baseField.Get("m_Script"); if (ms != null && ms.childrenCount == 2 && ms.GetFieldType().Equals("PPtr<MonoScript>")) { baseField = am.GetMonoBaseFieldCached(asset.file, asset.info, Path.Combine(hkDir, "Managed")); } } FindNestedPointers(asset.file, baseField, info, false); } } else { FindNestedPointers(file, child, info, replace); } } } }
public AssetTypeInstance GetTypeInstance(AssetsFile file, AssetFileInfoEx info, bool forceFromCldb = false) { return(new AssetTypeInstance(GetTemplateBaseField(file, info, forceFromCldb), file.reader, info.absoluteFilePos)); }
public FsmDataInstance LoadFSM(long id) { AssetFileInfoEx info = curFile.table.GetAssetInfo(id); AssetTypeValueField baseField = am.GetMonoBaseFieldCached(curFile, info, Path.Combine(Path.GetDirectoryName(curFile.path), "Managed")); AssetNameResolver namer = new AssetNameResolver(am, curFile); FsmDataInstance dataInstance = new FsmDataInstance(); AssetTypeValueField fsm = baseField.Get("fsm"); AssetTypeValueField states = fsm.Get("states"); AssetTypeValueField events = fsm.Get("events"); AssetTypeValueField variables = fsm.Get("variables"); AssetTypeValueField globalTransitions = fsm.Get("globalTransitions"); AssetTypeValueField dataVersionField = fsm.Get("dataVersion"); dataInstance.fsmName = fsm.Get("name").GetValue().AsString(); AssetTypeInstance goAti = am.GetExtAsset(curFile, baseField.Get("m_GameObject")).instance; if (goAti != null) { string m_Name = goAti.GetBaseField().Get("m_Name").GetValue().AsString(); dataInstance.goName = m_Name; } if (dataVersionField.IsDummy()) { dataInstance.dataVersion = fsm.Get("version").GetValue().AsInt() + 1; } else { dataInstance.dataVersion = dataVersionField.GetValue().AsInt(); } dataInstance.states = new List <FsmStateData>(); for (int i = 0; i < states.GetChildrenCount(); i++) { FsmStateData stateData = new FsmStateData(); stateData.ActionData = new List <ActionScriptEntry>(); stateData.state = new FsmState(namer, states[i]); stateData.node = new FsmNodeData(stateData.state); GetActionData(stateData.ActionData, stateData.state.actionData, dataInstance.dataVersion); dataInstance.states.Add(stateData); } dataInstance.events = new List <FsmEventData>(); for (int i = 0; i < events.GetChildrenCount(); i++) { FsmEventData eventData = new FsmEventData(); eventData.Global = events[i].Get("isGlobal").GetValue().AsBool(); eventData.Name = events[i].Get("name").GetValue().AsString(); dataInstance.events.Add(eventData); } dataInstance.variables = new List <FsmVariableData>(); GetVariableValues(dataInstance.variables, namer, variables); dataInstance.globalTransitions = new List <FsmNodeData>(); for (int i = 0; i < globalTransitions.GetChildrenCount(); i++) { AssetTypeValueField globalTransitionField = globalTransitions[i]; FsmGlobalTransition globalTransition = new FsmGlobalTransition() { fsmEvent = new FsmEvent(globalTransitionField.Get("fsmEvent")), toState = globalTransitionField.Get("toState").GetValue().AsString(), linkStyle = globalTransitionField.Get("linkStyle").GetValue().AsInt(), linkConstraint = globalTransitionField.Get("linkConstraint").GetValue().AsInt(), colorIndex = (byte)globalTransitionField.Get("colorIndex").GetValue().AsInt() }; FsmNodeData node = new FsmNodeData(dataInstance, globalTransition); dataInstance.globalTransitions.Add(node); } //dataInstance.events = new List<FsmEventData>(); //for (int i = 0; i < events.GetChildrenCount(); i++) //{ // FsmEventData eventData = new FsmEventData(); // AssetTypeValueField evt = events[i]; // eventData.Name = evt.Get("name").GetValue().AsString(); // eventData.Global = evt.Get("isGlobal").GetValue().AsBool(); //} // //dataInstance.variables = new List<FsmVariableData>(); //for (int i = 0; i < variables.GetChildrenCount(); i++) //{ // FsmVariableData variableData = new FsmVariableData(); // AssetTypeValueField vars = events[i]; //} return(dataInstance); }
public static AssetTypeValueField GetMonoBaseField(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, string managedPath) { AssetsFile file = inst.file; AssetTypeTemplateField baseField = new AssetTypeTemplateField(); baseField.FromClassDatabase(am.classFile, AssetHelper.FindAssetClassByID(am.classFile, info.curFileType), 0); AssetTypeInstance mainAti = new AssetTypeInstance(baseField, file.reader, false, info.absoluteFilePos); if (file.typeTree.pTypes_Unity5[info.curFileTypeOrIndex].scriptIndex != 0xFFFF) { AssetTypeInstance scriptAti = am.GetExtAsset(inst, mainAti.GetBaseField().Get("m_Script")).instance; string scriptName = scriptAti.GetBaseField().Get("m_Name").GetValue().AsString(); string assemblyName = scriptAti.GetBaseField().Get("m_AssemblyName").GetValue().AsString(); string assemblyPath = Path.Combine(managedPath, assemblyName); if (File.Exists(assemblyPath)) { MonoClass mc = new MonoClass(); mc.Read(scriptName, assemblyPath, inst.file.header.format); AssetTypeTemplateField[] monoTemplateFields = mc.children; AssetTypeTemplateField[] templateField = baseField.children.Concat(monoTemplateFields).ToArray(); baseField.children = templateField; baseField.childrenCount = (uint)baseField.children.Length; mainAti = new AssetTypeInstance(baseField, file.reader, false, info.absoluteFilePos); } } return(mainAti.GetBaseField()); }
private static void RecurseTypeReplace(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, AssetTypeValueField field, List <string> fileNames, Dictionary <AssetID, byte[]> ids, Dictionary <AssetID, long> aidToPid, Dictionary <long, long> gidToMid, int depth) { string p = new string(' ', depth); foreach (AssetTypeValueField child in field.pChildren) { //Console.WriteLine(p + child.templateField.type + " " + child.templateField.name); if (!child.templateField.hasValue) { if (child == null) { return; } string typeName = child.templateField.type; if (typeName.StartsWith("PPtr<") && typeName.EndsWith(">") && child.childrenCount == 2) { int fileId = child.Get("m_FileID").GetValue().AsInt(); long pathId = child.Get("m_PathID").GetValue().AsInt64(); if (pathId == 0) //removed asset { continue; } if (fileId > 0) { throw new Exception("file id was not set correctly!"); } fileId = -fileId; string fileName = fileNames[fileId]; AssetID actualId = new AssetID(fileName, pathId); if (!aidToPid.ContainsKey(actualId)) { Console.WriteLine("WARNING: MISSING ID FOR " + actualId.fileName + " " + actualId.pathId + " ON " + inst.name + " " + info.index); child.Get("m_PathID").GetValue().Set(0); } else { child.Get("m_PathID").GetValue().Set(aidToPid[actualId]); } child.Get("m_FileID").GetValue().Set(0); } RecurseTypeReplace(am, inst, info, child, fileNames, ids, aidToPid, gidToMid, depth + 1); } } if (depth == 0) { byte[] assetData; if (info.curFileType == 1) { assetData = FixGameObjectFast(inst, info, field, (ulong)gidToMid[(long)info.index]); } else { using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; field.Write(w); assetData = ms.ToArray(); } } AssetID thisId = new AssetID(inst.name, (long)info.index); ids[thisId] = assetData; } }
private void LoadComponentData(PGProperty root, AssetTypeValueField baseField, AssetFileInfoEx info, int index, int size) { string className = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType) .name.GetString(helper.classFile); AssetTypeValueField targetBaseField = baseField; if (className == "MonoBehaviour") { className += $" ({GetClassName(helper, inst, targetBaseField)})"; string managedPath = Path.Combine(Path.GetDirectoryName(inst.path), "Managed"); if (Directory.Exists(managedPath)) { targetBaseField = helper.GetMonoBaseFieldCached(inst, info, managedPath); } } string category = new string('\t', size - index) + className; PopulateDataGrid(targetBaseField, root, info, category); }
private static AssetsReplacerFromMemory MakeReplacer(ulong pathId, AssetsManager am, AssetsFileInstance file, AssetsFileInstance srcFile, AssetFileInfoEx inf, byte[] saData, List <Type_0D> types) { byte[] data = new byte[inf.curFileSize]; //UnityEngine.Debug.Log("making rep for " + inf.absoluteFilePos + " => " + (inf.absoluteFilePos+inf.curFileSize) + " of " + file.stream.Length); int typeId = file.file.typeTree.pTypes_Unity5[inf.curFileTypeOrIndex].classId; if (!types.Any(t => t.classId == typeId) && !srcFile.file.typeTree.pTypes_Unity5.Any(t => t.classId == typeId)) { if (!Hashes.hashes.ContainsKey(typeId)) { throw new NotImplementedException("hash not in hashtable, please add it!"); } types.Add(new Type_0D() { classId = typeId, unknown16_1 = 0, scriptIndex = 0xFFFF, unknown1 = 0, unknown2 = 0, unknown3 = 0, unknown4 = 0, unknown5 = Hashes.hashes[typeId][0], unknown6 = Hashes.hashes[typeId][1], unknown7 = Hashes.hashes[typeId][2], unknown8 = Hashes.hashes[typeId][3] }); //types.Add(C2T5.Cldb2TypeTree(am.classFile, typeId)); } switch (typeId) { case 0x1C: data = FixTexture2D(am.GetATI(file.file, inf).GetBaseField(), saData); break; case 0x15: data = FixMaterial(srcFile.file, am.GetATI(file.file, inf).GetBaseField(), saData); break; default: file.stream.Position = (int)inf.absoluteFilePos; file.stream.Read(data, 0, (int)inf.curFileSize); break; } return(new AssetsReplacerFromMemory(0, pathId, typeId, 0xFFFF, data)); }
public GameObject RecurseGameObjects(AssetFileInfoEx info, bool topRoot, bool hideOnCreation = false) { AssetTypeValueField gameObject = am.GetATI(assetsFile, info).GetBaseField(); string name = gameObject.Get("m_Name").GetValue().AsString(); AssetTypeValueField m_Component = gameObject.Get("m_Component").Get("Array"); AssetsManager.AssetExternal transformComponent = am.GetExtAsset(assetsFileInstance, m_Component[0].Get("component")); AssetTypeValueField transform = transformComponent.instance.GetBaseField(); if (name == "TileMap Render Data" || name == "Template-TileMap (1) Render Data") //should be .EndsWith(" Render Data") { return(TilemapRenderData(transform, name)); } if (topRoot && transform.Get("m_Father").Get("m_PathID").GetValue().AsInt64() != 0) { return(null); } if (!topRoot && transform.Get("m_Father").Get("m_PathID").GetValue().AsInt64() == 0) { return(null); } GameObject gameObjectInstance = new GameObject(name); //if this object or parent object is mask bool isMask = hideOnCreation; int m_Tag = (ushort)gameObject.Get("m_Tag").GetValue().AsUInt(); if (m_Tag >= 20000) { int tagIndex = m_Tag - 20000; gameObjectInstance.tag = UnityEditorInternal.InternalEditorUtility.tags[tagIndex]; } else if (m_Tag != 0) { string[] tags = new[] { "Respawn", "Finished", "EditorOnly", "MainCamera", "Player", "GameController" }; gameObjectInstance.tag = tags[m_Tag - 1]; } gameObjectInstance.layer = (int)gameObject.Get("m_Layer").GetValue().AsUInt(); EditDiffer differ = gameObjectInstance.AddComponent <EditDiffer>(); differ.fileId = 0; differ.pathId = info.index; differ.origPathId = differ.pathId; Transform transformInstance = gameObjectInstance.transform; AssetTypeValueField m_LocalPosition = transform.Get("m_LocalPosition"); AssetTypeValueField m_LocalRotation = transform.Get("m_LocalRotation"); AssetTypeValueField m_LocalScale = transform.Get("m_LocalScale"); Vector3 localPosition = GetVector3(m_LocalPosition); Quaternion localRotation = GetQuaternion(m_LocalRotation); Vector3 localScale = GetVector3(m_LocalScale); for (uint i = 1; i < m_Component.GetValue().AsArray().size; i++) { //faster to check for only info but also keeps us from reading //particle systems which tend to update literally every minor update //if we end up needing more types we can use typetree2cldb on an editor file AssetsManager.AssetExternal component = am.GetExtAsset(assetsFileInstance, m_Component[i].Get("component"), true); if (component.info.curFileType == SPRITERENDERER) { component = am.GetExtAsset(assetsFileInstance, m_Component[i].Get("component")); AssetTypeValueField baseField = component.instance.GetBaseField(); AssetTypeValueField m_Sprite = baseField.Get("m_Sprite"); int fileId = m_Sprite.Get("m_FileID").GetValue().AsInt(); long pathId = m_Sprite.Get("m_PathID").GetValue().AsInt64(); AssetsManager.AssetExternal sprite = am.GetExtAsset(assetsFileInstance, m_Sprite); if (sprite.info == null) //spriterenderer with no sprite lol { continue; } AssetsFileInstance spriteInst; if (m_Sprite.Get("m_FileID").GetValue().AsInt() == 0) { spriteInst = assetsFileInstance; } else { spriteInst = assetsFileInstance.dependencies[m_Sprite.Get("m_FileID").GetValue().AsInt() - 1]; } Sprite spriteInstance = bundleAssets[assetMap[new AssetID(Path.GetFileName(spriteInst.path), pathId)]] as Sprite; SpriteRenderer sr = gameObjectInstance.AddComponent <SpriteRenderer>(); string[] sortingLayers = new[] { "Default", "Far BG 2", "Far BG 1", "Mid BG", "Immediate BG", "Actors", "Player", "Tiles", "MID Dressing", "Immediate FG", "Far FG", "Vignette", "Over", "HUD" }; sr.sortingLayerName = sortingLayers[baseField.Get("m_SortingLayer").GetValue().AsInt()]; sr.sortingOrder = baseField.Get("m_SortingOrder").GetValue().AsInt(); sr.sprite = spriteInstance; AssetTypeValueField m_Materials = baseField.Get("m_Materials").Get("Array"); if (m_Materials.GetValue().AsArray().size > 0) { AssetTypeValueField m_Material = m_Materials[0]; int matFileId = m_Material.Get("m_FileID").GetValue().AsInt(); long matPathId = m_Material.Get("m_PathID").GetValue().AsInt64(); AssetsFileInstance materialInst; if (m_Material.Get("m_FileID").GetValue().AsInt() == 0) { materialInst = assetsFileInstance; } else { materialInst = assetsFileInstance.dependencies[matFileId - 1]; } if (assetMap.ContainsKey(new AssetID(Path.GetFileName(materialInst.path), matPathId))) { Material mat = bundleAssets[assetMap[new AssetID(Path.GetFileName(materialInst.path), matPathId)]] as Material; if (mat.shader.name != "Sprites/Lit") //honestly this shader confuses me. it is the only shader { //with no code and only references the generic material sr.material = mat; } //else //{ // mat.shader = sr.sharedMaterial.shader; // sr.sharedMaterial = mat; //} if (mat.shader.name == "Hollow Knight/Grass-Default" || mat.shader.name == "Hollow Knight/Grass-Diffuse") { sr.sharedMaterial.SetFloat("_SwayAmount", 0f); //stops grass animation } } //else //{ // Debug.Log("failed to find " + Path.GetFileName(materialInst.path) + "/" + matPathId + ".dat"); //} } } if (component.info.curFileType == MONOBEHAVIOUR) { component = am.GetExtAsset(assetsFileInstance, m_Component[i].Get("component")); AssetTypeValueField baseField = component.instance.GetBaseField(); int monoTypeId = assetsFileInstance.file.typeTree.pTypes_Unity5[component.info.curFileTypeOrIndex].scriptIndex; if (!monoBehaviourIds.ContainsKey(monoTypeId)) { //map out the monobehaviour script indexes to their name for fast lookup AssetTypeValueField m_Script = baseField.Get("m_Script"); AssetsManager.AssetExternal script = am.GetExtAsset(assetsFileInstance, m_Script); string scriptName = script.instance.GetBaseField().Get("m_Name").GetValue().AsString(); monoBehaviourIds[monoTypeId] = scriptName; } if (monoBehaviourIds[monoTypeId] == "tk2dSprite") { string managedPath = Path.Combine(Path.GetDirectoryName(assetsFileInstance.path), "Managed"); baseField = am.GetMonoBaseFieldCached(assetsFileInstance, component.info, managedPath); AssetTypeValueField collection = baseField.Get("collection"); int _spriteId = baseField.Get("_spriteId").GetValue().AsInt(); int fileId = collection.Get("m_FileID").GetValue().AsInt(); //long pathId = collection.Get("m_PathID").GetValue().AsInt64(); AssetsManager.AssetExternal sprite = am.GetExtAsset(assetsFileInstance, collection); if (sprite.info == null) { continue; } AssetsFileInstance spriteFileInstance = assetsFileInstance.dependencies[fileId - 1]; AssetTypeValueField spriteBaseField = am.GetMonoBaseFieldCached(spriteFileInstance, sprite.info, managedPath); //this is a bad hack but it works for some reason so here it is //the reason the pivot is being set and not the actual position //is so we don't modify the values on the transform component Texture2D image = spriteLoader.LoadTK2dSpriteNative(am, spriteBaseField, spriteFileInstance, _spriteId); AssetTypeValueField boundsData = spriteBaseField.Get("spriteDefinitions")[(uint)_spriteId].Get("boundsData")[0]; float xOff = boundsData.Get("x").GetValue().AsFloat() * 100; float yOff = boundsData.Get("y").GetValue().AsFloat() * 100; Vector2 offset = new Vector2((image.width / 2f - xOff) / image.width, (image.height / 2f - yOff) / image.height); Sprite spriteInstance = Sprite.Create(image, new Rect(0, 0, image.width, image.height), offset, 100f); SpriteRenderer sr = gameObjectInstance.AddComponent <SpriteRenderer>(); sr.sortingLayerName = "Default"; sr.sortingOrder = 0; sr.sprite = spriteInstance; } else if (monoBehaviourIds[monoTypeId] == "PlayMakerFSM") { //string managedPath = Path.Combine(Path.GetDirectoryName(assetsFileInstance.path), "Managed"); //baseField = am.GetMonoBaseFieldCached(assetsFileInstance, component.info, managedPath); string fsmName = ReadFSMName(component.info, assetsFileInstance.file.reader);//baseField.Get("fsm").Get("name").GetValue().AsString(); if (fsmName == "remasker" || fsmName == "unmasker" || fsmName == "remasker_inverse" || fsmName == "Remove") { isMask = true; } } } } transformInstance.localScale = localScale; transformInstance.localPosition = localPosition; transformInstance.localRotation = localRotation; Renderer ren = gameObjectInstance.GetComponent <Renderer>(); if (isMask && ren != null) { ren.enabled = false; } AssetTypeValueField childrenArray = transform.Get("m_Children").Get("Array"); uint childrenCount = childrenArray.GetValue().AsArray().size; for (uint i = 0; i < childrenCount; i++) { AssetTypeValueField childTf = am.GetExtAsset(assetsFileInstance, childrenArray[i]).instance.GetBaseField(); AssetFileInfoEx childGo = am.GetExtAsset(assetsFileInstance, childTf.Get("m_GameObject")).info; RecurseGameObjects(childGo, false, isMask).transform.SetParent(transformInstance, false); } return(gameObjectInstance); }
protected SerializingAssetReplacer(AssetsManager manager, AssetsFile assetsFile, AssetFileInfoEx asset) { this.manager = manager; this.assetsFile = assetsFile; this.asset = asset; }
public static byte[] CreateBundleFromLevel(AssetsManager am, /*byte[] data,*/ AssetsFileInstance inst, string sceneName, DiffFile diffFile, string bunPath) { AssetsFile file = inst.file; AssetsFileTable table = inst.table; string folderName = Path.GetDirectoryName(inst.path); //string sceneName = Path.GetFileNameWithoutExtension(inst.path) + "_mod"; List <AssetsReplacer> assetsSA = new List <AssetsReplacer>(); List <AssetFileInfoEx> infos = table.pAssetFileInfo.ToList(); //List<int> typeIds = new List<int>(); //foreach (AssetFileInfoEx info in infos) //{ // int typeId = (int)info.curFileType; // if (!typeIds.Contains(typeId) && typeId != 0x72) // typeIds.Add(typeId); //} assetsSA.Add(PreloadData.CreatePreloadData(1)); assetsSA.Add(BundleMeta.CreateBundleInformation(sceneName, 2)); //todo: pull from original assets file, cldb is not always update to date List <Type_0D> types = new List <Type_0D>(); //foreach (int typeId in typeIds) //{ // types.Add(C2T5.Cldb2TypeTree(am.classFile, typeId)); //} List <Type_0D> typesSA = new List <Type_0D> { C2T5.Cldb2TypeTree(am.classFile, 0x96), //PreloadData C2T5.Cldb2TypeTree(am.classFile, 0x8E) //AssetBundle }; const string ver = "2017.4.10f1"; List <AssetsReplacer> replacers = new List <AssetsReplacer>(); //UnityEngine.Debug.Log("HKWE DM " + diffFile.magic); //UnityEngine.Debug.Log("HKWE GC " + diffFile.changes.Count + diffFile.adds.Count + diffFile.removes.Count); //AssetsReplacerFromMemory mem = MoveTest.RunMoveTest(table.getAssetInfo(2642), am.GetATI(file, table.getAssetInfo(2642)).GetBaseField(), 2642) as AssetsReplacerFromMemory; foreach (GameObjectChange goChange in diffFile.changes) { //UnityEngine.Debug.Log("HKWE GO " + goChange.pathId); foreach (ComponentChangeOrAdd compChange in goChange.changes) { AssetFileInfoEx goInfo = table.getAssetInfo((ulong)goChange.pathId); AssetTypeValueField goBaseField = am.GetATI(file, goInfo).GetBaseField(); AssetTypeValueField compPptr = goBaseField.Get("m_Component").Get("Array")[(uint)compChange.componentIndex].Get("component"); AssetsManager.AssetExternal compExt = am.GetExtAsset(inst, compPptr); AssetFileInfoEx compInfo = compExt.info; AssetTypeValueField compBaseField = compExt.instance.GetBaseField(); //UnityEngine.Debug.Log("HKWE LR " + compInfo.index); AssetsReplacer imAlreadyReplacer = ComponentDiffReplacer.DiffComponent(compInfo, compBaseField, am.classFile, compChange, compInfo.index); replacers.Add(imAlreadyReplacer); } } AssetsManager amBun = new AssetsManager(); //we create a new manager because the two filenames will probably conflict amBun.classFile = am.classFile; //we can just reuse the classfile which is kinda hacky AssetsFileInstance bunInst = amBun.LoadAssetsFile(new MemoryStream(GetBundleData(bunPath, 0)), "HKWEDiffs", false); //placeholder path since we have no deps //rearrange the pathids immediately after the //last one from the level to keep unity happy ulong levelLargestPathID = 0; foreach (AssetFileInfoEx inf in table.pAssetFileInfo) { if (inf.index > levelLargestPathID) { levelLargestPathID = inf.index; } } ReferenceCrawler.ReorderIds(amBun, bunInst, levelLargestPathID + 1); byte[] bunSAInst = GetBundleData(bunPath, 1); //HashSet<ulong> addedDeps = new HashSet<ulong>(); foreach (AssetFileInfoEx inf in bunInst.table.pAssetFileInfo) { replacers.Add(MakeReplacer(inf.index, am, bunInst, inst, inf, bunSAInst, types)); } //foreach (GameObjectInfo inf in diffFile.infos) //{ // Debug.Log("7"); // ulong bunPathId = GetBundlePathId(amBun, bunInst, inf); // // AssetFileInfoEx objInf = bunInst.table.getAssetInfo(bunPathId); // replacers.Add(MakeReplacer(bunPathId, am, bunInst, inst, objInf, bunSAInst, types)); // // List<ulong> deps = ReferenceCrawler.CrawlPPtrs(amBun, bunInst, bunPathId); // foreach (ulong dep in deps) // { // if (!addedDeps.Contains(dep)) // { // addedDeps.Add(dep); // AssetFileInfoEx depInf = bunInst.table.getAssetInfo(dep); // //if (depInf.curFileType == 0x01 || depInf.curFileType == 0x04 || depInf.curFileType == 0xD4 || depInf.curFileType == 0x15 || depInf.curFileType == 0xD5) // //{ // // continue; // //} // replacers.Add(MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types)); // } // } // ////its possible to get a collision but very unlikely since unity already randomizes ids which are 8 bytes long // ////there's nothing here to test if a collision would be created so just hope that you don't win the lottery // //ulong bunPathId = GetBundlePathId(amBun, bunInst, inf); // ////AssetFileInfoEx afInf = bunInst.table.getAssetInfo(bunPathId); // ////replacers.Add(MakeReplacer(bunPathId, afInf, bunInst.stream)); // //List<ulong> deps = ReferenceCrawler.CrawlPPtrs(am, bunInst, bunPathId); // ////if (info.curFileType == 0x01 || info.curFileType == 0x04 || info.curFileType == 0xD4) // ////{ // //// continue; // ////} // //foreach (ulong dep in deps) // //{ // // AssetFileInfoEx depInf = bunInst.table.getAssetInfo(dep); // // //MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types); // // AssetsReplacerFromMemory ar = MakeReplacer(dep, am, bunInst, inst, depInf, bunSAInst, types); // // //todo- I guess this was just for testing purposes to block out everything, remove this at some point // // if (depInf.curFileType == 0x01 || depInf.curFileType == 0x04 || depInf.curFileType == 0xD4 || depInf.curFileType == 0x15 || depInf.curFileType == 0xD5) //depInf.curFileType == 0x1C // // { // // continue; // // } // // replacers.Add(ar); // //} //} byte[] data = null; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter writer = new AssetsFileWriter(ms)) { //file.typeTree.hasTypeTree = true; //so we don't have to calculate hashes //foreach (Type_0D type in file.typeTree.pTypes_Unity5) //{ // if (!types.Any(t => t.classId == type.classId)) // { // types.Insert(0, C2T5.Cldb2TypeTree(am.classFile, type.classId)); // } //} file.typeTree.pTypes_Unity5 = file.typeTree.pTypes_Unity5.Concat(types.ToArray()).ToArray(); //file.typeTree.pTypes_Unity5 = types.ToArray(); file.typeTree.fieldCount = (uint)file.typeTree.pTypes_Unity5.Length; //file.typeTree.fieldCount = (uint)types.Count; file.Write(writer, 0, replacers.ToArray(), 0); data = ms.ToArray(); } //File.WriteAllBytes("_bundlefinal1.unity3d", data); byte[] blankDataSA = BundleCreator.CreateBlankAssets(ver, typesSA); AssetsFile blankFileSA = new AssetsFile(new AssetsFileReader(new MemoryStream(blankDataSA))); byte[] dataSA = null; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter writer = new AssetsFileWriter(ms)) { blankFileSA.Write(writer, 0, assetsSA.ToArray(), 0); dataSA = ms.ToArray(); } using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter writer = new AssetsFileWriter(ms)) { AssetsBundleFile bundle = BundleCreator.CreateBlankBundle(ver, data.Length, dataSA.Length, sceneName); bundle.Write(writer); writer.Write(dataSA); writer.Write(data); return(ms.ToArray()); } }
protected SerializingAssetReplacer(AssetsManager manager, AssetsFileInstance assetsFile, AssetFileInfoEx asset) : this(manager, assetsFile.file, asset) { }
private static bool EnableVROptions(string path) { AssetsManager assetsManager = new AssetsManager(); AssetsFileInstance assetsFileInstance = assetsManager.LoadAssetsFile(path, false, ""); assetsManager.LoadClassDatabase(Path.Combine(VREnabler.VRPatcherPath, "cldb.dat")); int num = 0; while ((long)num < (long)((ulong)assetsFileInstance.table.assetFileInfoCount)) { try { AssetFileInfoEx assetInfo = assetsFileInstance.table.GetAssetInfo((long)num); AssetTypeInstance ati = assetsManager.GetATI(assetsFileInstance.file, assetInfo, false); AssetTypeValueField assetTypeValueField = (ati != null) ? ati.GetBaseField(0) : null; AssetTypeValueField assetTypeValueField2 = (assetTypeValueField != null) ? assetTypeValueField.Get("enabledVRDevices") : null; if (assetTypeValueField2 != null) { AssetTypeValueField assetTypeValueField3 = assetTypeValueField2.Get("Array"); if (assetTypeValueField3 != null) { AssetTypeValueField assetTypeValueField4 = ValueBuilder.DefaultValueFieldFromArrayTemplate(assetTypeValueField3); assetTypeValueField4.GetValue().Set("Oculus"); AssetTypeValueField assetTypeValueField5 = ValueBuilder.DefaultValueFieldFromArrayTemplate(assetTypeValueField3); assetTypeValueField5.GetValue().Set("OpenVR"); AssetTypeValueField assetTypeValueField6 = ValueBuilder.DefaultValueFieldFromArrayTemplate(assetTypeValueField3); assetTypeValueField6.GetValue().Set("None"); assetTypeValueField3.SetChildrenList(new AssetTypeValueField[] { assetTypeValueField6, assetTypeValueField4, assetTypeValueField5 }); byte[] array; using (MemoryStream memoryStream = new MemoryStream()) { using (AssetsFileWriter assetsFileWriter = new AssetsFileWriter(memoryStream)) { assetsFileWriter.bigEndian = false; AssetWriters.Write(assetTypeValueField, assetsFileWriter, 0); array = memoryStream.ToArray(); } } List <AssetsReplacer> list = new List <AssetsReplacer> { new AssetsReplacerFromMemory(0, (long)num, (int)assetInfo.curFileType, ushort.MaxValue, array) }; using (MemoryStream memoryStream2 = new MemoryStream()) { using (AssetsFileWriter assetsFileWriter2 = new AssetsFileWriter(memoryStream2)) { assetsFileInstance.file.Write(assetsFileWriter2, 0UL, list, 0U, null); assetsFileInstance.stream.Close(); File.WriteAllBytes(path, memoryStream2.ToArray()); } } return(true); } } } catch { } num++; } VREnabler.Logger.LogError("VR enable location not found!"); return(false); }
public static void GenerateDiffFile(AssetsManager am, AssetsFileInstance buildInst, AssetsFileInstance sceneInst, HKWEMeta meta) { EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f); am.UpdateDependencies(); ClassDatabaseFile cldb = am.classFile; DiffData result = new DiffData() { goChanges = new List <GameObjectChange>(), goAdditions = new List <GameObjectAddition>() }; Dictionary <EditDifferData, long> differToSceneId = new Dictionary <EditDifferData, long>(); Dictionary <long, EditDifferData> buildIdToDiffer = new Dictionary <long, EditDifferData>(); List <EditDifferData> differData = new List <EditDifferData>(); AssetsFileTable sceneTable = sceneInst.table; List <AssetFileInfoEx> sceneGos = sceneTable.GetAssetsOfType(0x01); for (int i = 0; i < sceneGos.Count; i++) { if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Finding diff IDs... (step 1/3)", (float)i / sceneGos.Count); } AssetFileInfoEx inf = sceneGos[i]; AssetTypeValueField baseField = am.GetATI(sceneInst.file, inf).GetBaseField(); AssetTypeValueField editDifferMono = GetEDMono(am, sceneInst, baseField); EditDifferData diff = new EditDifferData() { fileId = editDifferMono.Get("fileId").GetValue().AsInt(), pathId = editDifferMono.Get("pathId").GetValue().AsInt64(), origPathId = editDifferMono.Get("origPathId").GetValue().AsInt64(), newAsset = editDifferMono.Get("newAsset").GetValue().AsBool() }; buildIdToDiffer[diff.origPathId] = diff; differToSceneId[diff] = inf.index; differData.Add(diff); } ////////////////////////// AssetsFileTable origTable = buildInst.table; List <AssetFileInfoEx> origGos = origTable.GetAssetsOfType(0x01); List <long> origDeletIds = new List <long>(); //int nextBundleId = 1; //// == delete changes == // //for (int i = 0; i < origGos.Count; i++) //{ // if (i % 100 == 0) // EditorUtility.DisplayProgressBar("HKEdit", "Checking for deletes... (step 2/3)", (float)i / origGos.Count); // AssetFileInfoEx inf = sceneGos[i]; // if (!differData.Any(d => d.origPathId == inf.index)) // { // GameObjectChange change = new GameObjectChange // { // flags = GameObjectChangeFlags.Deleted // }; // result.goChanges.Add(change); // origDeletIds.Add(inf.index); // } //} // == add changes == // //to get this working in a built game, we need //built assets (ie pngs -> texture2d) the problem //is there's no easy way to direct unity to do that //without loading the scene and using unity's api //but we can pull out assets into a prefab and build //the prefab but there are problems with duplicate //dependencies being copied, so we pack them all //into one place so that doesn't happen //(for reference, in hkwe1, each gameobject got //its own prefab) //find dependencies ReferenceCrawlerBundle createdCrawler = new ReferenceCrawlerBundle(am); //assets created by the user in the ditor ReferenceCrawlerBundle existingCrawler = new ReferenceCrawlerBundle(am); //assets that already existed in the scene for (int i = 0; i < differData.Count; i++) { if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Checking for additions... (step 2/3)", (float)i / differData.Count); } EditDifferData dat = differData[i]; if (dat.newAsset) { long sceneId = differToSceneId[dat]; AssetFileInfoEx inf = sceneInst.table.GetAssetInfo(sceneId); createdCrawler.SetReferences(sceneInst, inf); GameObjectAddition addition = new GameObjectAddition { bundleId = createdCrawler.GetNextId(), //? sceneId = dat.pathId, dependencies = new List <GameObjectAdditionDependency>() }; //nextBundleId++; foreach (KeyValuePair <AssetID, AssetID> goRef in createdCrawler.references) { addition.dependencies.Add(new GameObjectAdditionDependency { sceneId = goRef.Key.pathId, bundleId = goRef.Value.pathId }); } result.goAdditions.Add(addition); } else { long newPathId = differToSceneId[dat]; AssetFileInfoEx inf = sceneInst.table.GetAssetInfo(newPathId); existingCrawler.SetReferences(sceneInst, inf); } } //load up all created assets into a prefab List <Type_0D> types = new List <Type_0D>(); List <string> typeNames = new List <string>(); foreach (AssetsReplacer rep in createdCrawler.sceneReplacers) { ClassDatabaseType clType = AssetHelper.FindAssetClassByID(cldb, (uint)rep.GetClassID()); string clName = clType.name.GetString(cldb); if (!typeNames.Contains(clName)) { Type_0D type0d = C2T5.Cldb2TypeTree(cldb, clName); type0d.classId = clType.classId; types.Add(type0d); typeNames.Add(clName); } } List <AssetsReplacer> replacers = new List <AssetsReplacer>(); replacers.Add(CreatePrefabAsset(2)); //better hope id 2 is a gameobject replacers.AddRange(createdCrawler.sceneReplacers); AssetsFile createdFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(ver, types)))); byte[] data; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter writer = new AssetsFileWriter(ms)) { createdFile.Write(writer, 0, replacers, 0); data = ms.ToArray(); } }
public static AssetTypeInstance GetTypeInstanceNewData(this AssetsManager _this, AssetsFile file, AssetFileInfoEx info, Stream data, bool forceFromCldb = false) { return(new AssetTypeInstance(_this.GetTemplateBaseField(file, info, forceFromCldb), new AssetsFileReader(data), 0)); }
public static byte[] CreateBundleFromLevel(AssetsManager am, AssetsFileInstance inst) { AssetsFile file = inst.file; AssetsFileTable table = inst.table; string folderName = Path.GetDirectoryName(inst.path); ulong pathId = 2; List <AssetsReplacer> assets = new List <AssetsReplacer>(); Dictionary <AssetID, ulong> assetMap = new Dictionary <AssetID, ulong>(); //get all sprites int i = 0; List <AssetFileInfoEx> infos = table.GetAssetsOfType(0xD4); List <ulong> spriteIds = new List <ulong>(); foreach (AssetFileInfoEx info in infos) { //honestly this is a really trash way to do this //we have a better scene exporter but it would //take some work to fix it up and block certain assets EditorUtility.DisplayProgressBar("HKEdit", "Creating scene bundle", i / (float)infos.Count); AssetTypeValueField baseField = GetBaseField(am, file, info); AssetTypeValueField m_Sprite = baseField.Get("m_Sprite"); AssetFileInfoEx spriteInfo = am.GetExtAsset(inst, m_Sprite, true).info; AssetsFileInstance spriteInst; if (m_Sprite.Get("m_FileID").GetValue().AsInt() == 0) { spriteInst = inst; } else { spriteInst = inst.dependencies[m_Sprite.Get("m_FileID").GetValue().AsInt() - 1]; } int spriteFileId = m_Sprite.Get("m_FileID").GetValue().AsInt(); long spritePathId = m_Sprite.Get("m_PathID").GetValue().AsInt64(); if (assetMap.ContainsKey(new AssetID(Path.GetFileName(spriteInst.path), spritePathId)) || (spriteFileId == 0 && spritePathId == 0)) { i++; continue; } AssetTypeValueField spriteBaseField = GetBaseField(am, spriteInst.file, spriteInfo); AssetTypeValueField m_RD = spriteBaseField.Get("m_RD"); AssetTypeValueField texture = m_RD.Get("texture"); AssetTypeValueField alphaTexture = m_RD.Get("alphaTexture"); AssetsFileInstance textureInst, alphaTextureInst; if (texture.Get("m_FileID").GetValue().AsInt() == 0) { textureInst = spriteInst; } else { textureInst = spriteInst.dependencies[texture.Get("m_FileID").GetValue().AsInt() - 1]; } if (alphaTexture.Get("m_FileID").GetValue().AsInt() == 0) { alphaTextureInst = spriteInst; } else { alphaTextureInst = spriteInst.dependencies[alphaTexture.Get("m_FileID").GetValue().AsInt() - 1]; } AssetTypeInstance textureAti = am.GetExtAsset(spriteInst, texture, false).instance; AssetTypeInstance alphaTextureAti = am.GetExtAsset(spriteInst, alphaTexture, false).instance; ulong textureId = 0, alphaTextureId = 0; if (textureAti != null) { AssetID id = new AssetID(Path.GetFileName(textureInst.path), texture.Get("m_PathID").GetValue().AsInt64()); if (!assetMap.ContainsKey(id)) { textureId = pathId; assetMap.Add(id, pathId); assets.Add(TextureConverter.ConvertTexture(textureAti.GetBaseField(), pathId++, folderName)); } else { textureId = assetMap[id]; } } if (alphaTextureAti != null) { AssetID id = new AssetID(Path.GetFileName(alphaTextureInst.path), alphaTexture.Get("m_PathID").GetValue().AsInt64()); if (!assetMap.ContainsKey(id)) { alphaTextureId = pathId; assetMap.Add(id, pathId); assets.Add(TextureConverter.ConvertTexture(alphaTextureAti.GetBaseField(), pathId++, folderName)); } else { alphaTextureId = assetMap[id]; } } AssetTypeValueField m_Materials = baseField.Get("m_Materials").Get("Array"); if (m_Materials.GetValue().AsArray().size > 0) { AssetTypeValueField material = baseField.Get("m_Materials").Get("Array")[0]; AssetsFileInstance materialInst; int materialFileId = material.Get("m_FileID").GetValue().AsInt(); if (materialFileId == 0) { materialInst = inst; } else { materialInst = inst.dependencies[materialFileId - 1]; } AssetID materialId = new AssetID(Path.GetFileName(materialInst.path), material.Get("m_PathID").GetValue().AsInt64()); if (!assetMap.ContainsKey(materialId)) { AssetTypeValueField materialBaseField = am.GetExtAsset(inst, material).instance.GetBaseField(); AssetTypeValueField shader = materialBaseField.Get("m_Shader"); ulong shaderPathId = RecurseShaderDependencies(am, materialInst, pathId, shader, assets, assetMap, out pathId); assetMap.Add(materialId, pathId); assets.Add(MaterialConverter.ConvertMaterial(materialBaseField, pathId++, shaderPathId)); } } assetMap.Add(new AssetID(Path.GetFileName(spriteInst.path), spritePathId), pathId); spriteIds.Add(pathId); assets.Add(SpriteConverter.ConvertSprite(spriteBaseField, pathId++, textureId, alphaTextureId)); i++; } assetMap.Add(new AssetID(0), pathId); assets.Add(HeaderInformation.CreateHeaderInformation(assetMap, pathId++)); assets.Insert(0, BundleMeta.CreateBundleInformation(assetMap, spriteIds, 1)); //assets.Add(BundleMeta.CreateBundleInformation(assetMap, 1)); //todo: pull from original assets file, cldb is not always update to date List <Type_0D> types = new List <Type_0D> { FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x8E)), //AssetBundle FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x1C)), //Texture2D FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x31)), //TextAsset FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0xD4)), //SpriteRenderer FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0xD5)), //Sprite //FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x31)), //TextAsset FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x15)), //Material FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x30)) //Shader }; const string ver = "2017.4.10f1"; //const string ver = "2018.2.1f1"; byte[] blankData = BundleCreator.CreateBlankAssets(ver, types); AssetsFile blankFile = new AssetsFile(new AssetsFileReader(new MemoryStream(blankData))); byte[] data = null; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter writer = new AssetsFileWriter(ms)) { blankFile.WriteFix(writer, 0, assets.ToArray(), 0); data = ms.ToArray(); } EditorUtility.DisplayProgressBar("HKEdit", "Creating bundle", 1); using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter writer = new AssetsFileWriter(ms)) { BundleCreator.CreateBlankBundle(ver, data.Length).Write(writer, data); return(ms.ToArray()); } }
private void LoadFSMs(string path) { string folderName = Path.GetDirectoryName(path); curFile = am.LoadAssetsFile(path, true); am.UpdateDependencies(); AssetsFile file = curFile.file; AssetsFileTable table = curFile.table; List <AssetInfo> assetInfos = new List <AssetInfo>(); uint assetCount = table.assetFileInfoCount; uint fsmTypeId = 0; foreach (AssetFileInfoEx info in table.pAssetFileInfo) { bool isMono = false; if (fsmTypeId == 0) { ushort monoType = file.typeTree.pTypes_Unity5[info.curFileTypeOrIndex].scriptIndex; if (monoType != 0xFFFF) { isMono = true; } } else if (info.curFileType == fsmTypeId) { isMono = true; } if (isMono) { AssetTypeInstance monoAti = am.GetATI(file, info); AssetTypeInstance scriptAti = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_Script")).instance; AssetTypeInstance goAti = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_GameObject")).instance; if (goAti == null) //found a scriptable object, oops { fsmTypeId = 0; continue; } string m_Name = goAti.GetBaseField().Get("m_Name").GetValue().AsString(); string m_ClassName = scriptAti.GetBaseField().Get("m_ClassName").GetValue().AsString(); if (m_ClassName == "PlayMakerFSM") { if (fsmTypeId == 0) { fsmTypeId = info.curFileType; } BinaryReader reader = file.reader; long oldPos = reader.BaseStream.Position; reader.BaseStream.Position = (long)info.absoluteFilePos; reader.BaseStream.Position += 28; uint length = reader.ReadUInt32(); reader.ReadBytes((int)length); long pad = 4 - (reader.BaseStream.Position % 4); if (pad != 4) { reader.BaseStream.Position += pad; } reader.BaseStream.Position += 16; uint length2 = reader.ReadUInt32(); string fsmName = Encoding.ASCII.GetString(reader.ReadBytes((int)length2)); reader.BaseStream.Position = oldPos; assetInfos.Add(new AssetInfo() { id = info.index, size = info.curFileSize, name = m_Name + "-" + fsmName }); } } } assetInfos.Sort((x, y) => x.name.CompareTo(y.name)); FSMSelector selector = new FSMSelector(assetInfos); selector.ShowDialog(); //todo separate into separate method(s) if (selector.selectedID == -1) { return; } AssetFileInfoEx afi = table.getAssetInfo((ulong)selector.selectedID); string tabName = assetInfos.FirstOrDefault(i => i.id == (ulong)selector.selectedID).name; TabItem tab = new TabItem { //Name = tabName.Replace(" ","").Replace("-","_").Replace("(","_").Replace(")","_"), Header = tabName }; ignoreChangeEvent = true; fsmTabControl.Items.Add(tab); fsmTabControl.SelectedItem = tab; ignoreChangeEvent = false; SaveAndClearNodes(); mt.Matrix = Matrix.Identity; currentTab++; AssetTypeValueField baseField = am.GetMonoBaseFieldCached(curFile, afi, Path.Combine(Path.GetDirectoryName(curFile.path), "Managed")); //from uabe //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 }, file.reader, false, afi.absoluteFilePos); //AssetTypeTemplateField[] desMonos; //desMonos = TryDeserializeMono(mainAti, am, folderName); //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 }, file.reader, false, afi.absoluteFilePos); //} //AssetTypeValueField baseField = mainAti.GetBaseField(); AssetTypeValueField fsm = baseField.Get("fsm"); AssetTypeValueField states = fsm.Get("states"); AssetTypeValueField globalTransitions = fsm.Get("globalTransitions"); dataVersion = fsm.Get("dataVersion").GetValue().AsInt(); for (int i = 0; i < states.GetValue().AsArray().size; i++) { AssetTypeValueField state = states.Get((uint)i); //move all of this into node string name = state.Get("name").GetValue().AsString(); AssetTypeValueField rect = state.Get("position"); Rect dotNetRect = new Rect(rect.Get("x").GetValue().AsFloat(), rect.Get("y").GetValue().AsFloat(), rect.Get("width").GetValue().AsFloat(), rect.Get("height").GetValue().AsFloat()); AssetTypeValueField transitions = state.Get("transitions"); uint transitionCount = transitions.GetValue().AsArray().size; FsmTransition[] dotNetTransitions = new FsmTransition[transitionCount]; for (int j = 0; j < transitionCount; j++) { dotNetTransitions[j] = new FsmTransition(transitions.Get((uint)j)); } Node node = new Node(state, name, dotNetRect, dotNetTransitions); nodes.Add(node); node.grid.MouseLeftButtonDown += (object sender, MouseButtonEventArgs e) => { foreach (Node node2 in nodes) { node2.Selected = false; } node.Selected = true; SidebarData(node, curFile); }; graphCanvas.Children.Add(node.grid); } for (int i = 0; i < globalTransitions.GetValue().AsArray().size; i++) { AssetTypeValueField transition = globalTransitions.Get((uint)i); FsmTransition dotNetTransition = new FsmTransition(transition); Node toNode = nodes.FirstOrDefault(n => n.name == dotNetTransition.toState); if (toNode == null) { System.Diagnostics.Debug.WriteLine("transition " + dotNetTransition.fsmEvent.name + " going to non-existant node " + dotNetTransition.toState); } else { Rect rect = new Rect( toNode.Transform.X, toNode.Transform.Y - 50, toNode.Transform.Width, 18); if (toNode != null) { Node node = new Node(null, dotNetTransition.fsmEvent.name, rect, new[] { dotNetTransition }); nodes.Add(node); graphCanvas.Children.Add(node.grid); } } } foreach (Node node in nodes) { if (node.transitions.Length <= 0) { continue; } float yPos = 24; foreach (FsmTransition trans in node.transitions) { Node endNode = nodes.FirstOrDefault(n => n.name == trans.toState); if (endNode != null) { Point start, end, startMiddle, endMiddle; if (node.state != null) { start = ComputeLocation(node, endNode, yPos, out bool isLeftStart); end = ComputeLocation(endNode, node, 10, out bool isLeftEnd); double dist = 70; if (isLeftStart == isLeftEnd) { dist *= 0.5; } if (!isLeftStart) { startMiddle = new Point(start.X - dist, start.Y); } else { startMiddle = new Point(start.X + dist, start.Y); } if (!isLeftEnd) { endMiddle = new Point(end.X - dist, end.Y); } else { endMiddle = new Point(end.X + dist, end.Y); } } else { start = new Point(node.Transform.X + node.Transform.Width / 2, node.Transform.Y + node.Transform.Height); end = new Point(endNode.Transform.X + endNode.Transform.Width / 2, endNode.Transform.Y); startMiddle = new Point(start.X, start.Y + 1); endMiddle = new Point(end.X, end.Y - 1); } CurvedArrow arrow = new CurvedArrow() { Points = new PointCollection(new List <Point>() { start, startMiddle, endMiddle, end }), StrokeThickness = 2, Stroke = Brushes.Black, Fill = Brushes.Black, IsHitTestVisible = true }; arrow.MouseEnter += (object sender, MouseEventArgs e) => { arrow.Stroke = Brushes.LightGray; arrow.Fill = Brushes.LightGray; }; arrow.MouseLeave += (object sender, MouseEventArgs e) => { arrow.Stroke = Brushes.Black; arrow.Fill = Brushes.Black; }; Panel.SetZIndex(arrow, -1); graphCanvas.Children.Add(arrow); } else { System.Diagnostics.Debug.WriteLine(node.name + " failed to connect to " + trans.toState); } yPos += 16; } } AssetTypeValueField events = fsm.Get("events"); for (int i = 0; i < events.GetValue().AsArray().size; i++) { AssetTypeValueField @event = events.Get((uint)i); string name = @event.Get("name").GetValue().AsString(); bool isSystemEvent = @event.Get("isSystemEvent").GetValue().AsBool(); bool isGlobal = @event.Get("isGlobal").GetValue().AsBool(); eventList.Children.Add(CreateSidebarRow(name, isSystemEvent, isGlobal)); } AssetTypeValueField variables = fsm.Get("variables"); AssetTypeValueField floatVariables = variables.Get("floatVariables"); AssetTypeValueField intVariables = variables.Get("intVariables"); AssetTypeValueField boolVariables = variables.Get("boolVariables"); AssetTypeValueField stringVariables = variables.Get("stringVariables"); AssetTypeValueField vector2Variables = variables.Get("vector2Variables"); AssetTypeValueField vector3Variables = variables.Get("vector3Variables"); AssetTypeValueField colorVariables = variables.Get("colorVariables"); AssetTypeValueField rectVariables = variables.Get("rectVariables"); AssetTypeValueField quaternionVariables = variables.Get("quaternionVariables"); AssetTypeValueField gameObjectVariables = variables.Get("gameObjectVariables"); AssetTypeValueField objectVariables = variables.Get("objectVariables"); AssetTypeValueField materialVariables = variables.Get("materialVariables"); AssetTypeValueField textureVariables = variables.Get("textureVariables"); AssetTypeValueField arrayVariables = variables.Get("arrayVariables"); AssetTypeValueField enumVariables = variables.Get("enumVariables"); variableList.Children.Add(CreateSidebarHeader("Floats")); for (int i = 0; i < floatVariables.GetValue().AsArray().size; i++) { string name = floatVariables.Get((uint)i).Get("name").GetValue().AsString(); string value = floatVariables.Get((uint)i).Get("value").GetValue().AsFloat().ToString(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("Ints")); for (int i = 0; i < intVariables.GetValue().AsArray().size; i++) { string name = intVariables.Get((uint)i).Get("name").GetValue().AsString(); string value = intVariables.Get((uint)i).Get("value").GetValue().AsInt().ToString(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("Bools")); for (int i = 0; i < boolVariables.GetValue().AsArray().size; i++) { string name = boolVariables.Get((uint)i).Get("name").GetValue().AsString(); string value = boolVariables.Get((uint)i).Get("value").GetValue().AsBool().ToString().ToLower(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("Strings")); for (int i = 0; i < stringVariables.GetValue().AsArray().size; i++) { string name = stringVariables.Get((uint)i).Get("name").GetValue().AsString(); string value = stringVariables.Get((uint)i).Get("value").GetValue().AsString(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("Vector2s")); for (int i = 0; i < vector2Variables.GetValue().AsArray().size; i++) { string name = vector2Variables.Get((uint)i).Get("name").GetValue().AsString(); AssetTypeValueField vector2 = vector2Variables.Get((uint)i).Get("value"); string value = vector2.Get("x").GetValue().AsFloat().ToString() + ", "; value += vector2.Get("y").GetValue().AsFloat().ToString(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("Vector3s")); for (int i = 0; i < vector3Variables.GetValue().AsArray().size; i++) { string name = vector3Variables.Get((uint)i).Get("name").GetValue().AsString(); AssetTypeValueField vector3 = vector3Variables.Get((uint)i).Get("value"); string value = vector3.Get("x").GetValue().AsFloat().ToString() + ", "; value += vector3.Get("x").GetValue().AsFloat().ToString() + ", "; value += vector3.Get("z").GetValue().AsFloat().ToString(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("Colors")); for (int i = 0; i < colorVariables.GetValue().AsArray().size; i++) { string name = colorVariables.Get((uint)i).Get("name").GetValue().AsString(); AssetTypeValueField color = colorVariables.Get((uint)i).Get("value"); string value = ((int)(color.Get("r").GetValue().AsFloat()) * 255).ToString("X2"); value += ((int)(color.Get("g").GetValue().AsFloat()) * 255).ToString("X2"); value += ((int)(color.Get("b").GetValue().AsFloat()) * 255).ToString("X2"); value += ((int)(color.Get("a").GetValue().AsFloat()) * 255).ToString("X2"); Grid sidebarRow = CreateSidebarRow(name, value); TextBox textBox = sidebarRow.Children.OfType <TextBox>().FirstOrDefault(); textBox.BorderBrush = (SolidColorBrush)(new BrushConverter().ConvertFrom("#" + value)); variableList.Children.Add(sidebarRow); } variableList.Children.Add(CreateSidebarHeader("Rects")); for (int i = 0; i < rectVariables.GetValue().AsArray().size; i++) { string name = rectVariables.Get((uint)i).Get("name").GetValue().AsString(); AssetTypeValueField rect = rectVariables.Get((uint)i).Get("value"); string value = rect.Get("x").GetValue().AsFloat().ToString() + ", "; value += rect.Get("y").GetValue().AsFloat().ToString() + ", "; value += rect.Get("width").GetValue().AsFloat().ToString() + ", "; value += rect.Get("height").GetValue().AsFloat().ToString(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("Quaternions")); for (int i = 0; i < quaternionVariables.GetValue().AsArray().size; i++) { string name = quaternionVariables.Get((uint)i).Get("name").GetValue().AsString(); AssetTypeValueField rect = quaternionVariables.Get((uint)i).Get("value"); string value = rect.Get("x").GetValue().AsFloat().ToString() + ", "; value += rect.Get("y").GetValue().AsFloat().ToString() + ", "; value += rect.Get("z").GetValue().AsFloat().ToString() + ", "; value += rect.Get("w").GetValue().AsFloat().ToString(); variableList.Children.Add(CreateSidebarRow(name, value)); } variableList.Children.Add(CreateSidebarHeader("GameObjects")); for (int i = 0; i < gameObjectVariables.GetValue().AsArray().size; i++) { string name = gameObjectVariables.Get((uint)i).Get("name").GetValue().AsString(); AssetTypeValueField gameObject = gameObjectVariables.Get((uint)i).Get("value"); int m_FileID = gameObject.Get("m_FileID").GetValue().AsInt(); long m_PathID = gameObject.Get("m_PathID").GetValue().AsInt64(); string value; if (m_PathID != 0) { value = $"[{m_FileID},{m_PathID}]"; } else { value = ""; } variableList.Children.Add(CreateSidebarRow(name, value)); } }
public static AssetTypeValueField GetBaseField(AssetsManager am, AssetsFile file, AssetFileInfoEx info) { AssetTypeInstance ati = am.GetATI(file, info); return(ati.GetBaseField()); }
//thats a nice function, be a shame if you ran out of memory private static void RecurseType(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, AssetTypeValueField field, List <string> fileNames, Dictionary <AssetID, byte[]> ids, int depth) { string p = new string(' ', depth); foreach (AssetTypeValueField child in field.pChildren) { //Console.WriteLine(p + child.templateField.type + " " + child.templateField.name); if (!child.templateField.hasValue) { if (child == null) { return; } string typeName = child.templateField.type; if (typeName.StartsWith("PPtr<") && typeName.EndsWith(">") && child.childrenCount == 2) { int fileId = child.Get("m_FileID").GetValue().AsInt(); long pathId = child.Get("m_PathID").GetValue().AsInt64(); if (pathId == 0) { continue; } AssetsFileInstance depInst = null; if (fileId == 0) { depInst = inst; } else { if (inst.dependencies.Count > 0 && inst.dependencies[0] == null) { Console.WriteLine("dependency null for " + inst.name); } depInst = inst.dependencies[fileId - 1]; } string depName = depInst.name; if (!fileNames.Contains(depName)) { fileNames.Add(depName); } AssetID id = new AssetID(depInst.name, pathId); if (!ids.ContainsKey(id)) { AssetsManager.AssetExternal depExt = am.GetExtAsset(inst, child); AssetFileInfoEx depInfo = depExt.info; if (depInfo.curFileType == 1 || depInfo.curFileType == 4 || depInfo.curFileType == 21 || depInfo.curFileType == 23 || depInfo.curFileType == 28 || depInfo.curFileType == 33 || depInfo.curFileType == 43 || depInfo.curFileType == 48 || depInfo.curFileType == 212 || depInfo.curFileType == 213) { ids.Add(id, null); AssetTypeValueField depBaseField; if (depInfo.curFileType != 0x72) { depBaseField = depExt.instance.GetBaseField(); } else { depBaseField = am.GetMonoBaseFieldCached(depExt.file, depInfo, Path.Combine(Path.GetDirectoryName(inst.path), "Managed")); } RecurseType(am, depInst, depInfo, depBaseField, fileNames, ids, 0); } } //make fileId negative to mark for replacement //we do the changes here since we're already iterating over each field child.Get("m_FileID").GetValue().Set(-fileNames.IndexOf(depName)); } RecurseType(am, inst, info, child, fileNames, ids, depth + 1); } } if (depth == 0) { byte[] assetData; if (info.curFileType == 28) { assetData = FixTexture2DFast(inst, info); } else { using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; field.Write(w); assetData = ms.ToArray(); } } AssetID thisId = new AssetID(inst.name, (long)info.index); ids[thisId] = assetData; } }
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; ReferenceCrawlerEditor crawler = new ReferenceCrawlerEditor(am); List <AssetFileInfoEx> initialGameObjects = table.GetAssetsOfType(0x01); for (int i = 0; i < initialGameObjects.Count; i++) { if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Finding necessary assets... (step 1/3)", (float)i / initialGameObjects.Count); } AssetFileInfoEx inf = initialGameObjects[i]; crawler.AddReference(new AssetID(inst.path, (long)inf.index), false); crawler.SetReferences(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", "Reordering path ids... (step 2/3)", (float)j / glblToLcl.Count); } AssetsFileInstance depInst = fileToInst[id.Key.fileName]; AssetFileInfoEx depInf = depInst.table.GetAssetInfo(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)); types.Add(CreateTk2dEmuTypeTree(cldb)); List <Type_0D> assetTypes = new List <Type_0D>() { C2T5.Cldb2TypeTree(cldb, 0x1c), C2T5.Cldb2TypeTree(cldb, 0x30), C2T5.Cldb2TypeTree(cldb, 0x53), //new /*C2T5.Cldb2TypeTree(cldb, 0x5b), * C2T5.Cldb2TypeTree(cldb, 0x4a),*/ //C2T5.Cldb2TypeTree(cldb, 0x28f3fdef) }; 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.dependencies = new List <AssetsFileDependency>() { CreateDependency(ExportedScenesData + "/" + origFileName + "-data.assets"), CreateScriptDependency(Constants.editDifferMsEditorScriptHash, Constants.editDifferLsEditorScriptHash), CreateScriptDependency(Constants.tk2dEmuMsEditorScriptHash, Constants.tk2dEmuLsEditorScriptHash), }; sceneFile.dependencies.dependencyCount = 3; sceneFile.preloadTable.items = new List <AssetPPtr>() { new AssetPPtr(2, 11500000), new AssetPPtr(3, 11500000) }; sceneFile.preloadTable.len = 2; sceneFile.Write(w, 0, crawler.sceneReplacers.Concat(crawler.sceneMonoReplacers).ToList(), 0); sceneFileData = ms.ToArray(); } byte[] assetFileData; using (MemoryStream ms = new MemoryStream()) using (AssetsFileWriter w = new AssetsFileWriter(ms)) { w.bigEndian = false; assetFile.dependencies.dependencies = new List <AssetsFileDependency>() { //CreateDependency("Assets/" + origFileName + ".unity"), }; assetFile.dependencies.dependencyCount = 0; assetFile.Write(w, 0, crawler.assetReplacers.ToList(), 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(); }
private void PopulateDataGrid(AssetTypeValueField atvf, PGProperty node, AssetFileInfoEx info, string category, bool arrayChildren = false) { if (atvf.childrenCount == 0) { return; } string arrayName = string.Empty; if (arrayChildren && atvf.childrenCount > 0) { arrayName = atvf.children[0].templateField.name; } for (int i = 0; i < atvf.childrenCount; i++) { AssetTypeValueField atvfc = atvf.children[i]; if (atvfc == null) { return; } string key; if (!arrayChildren) { key = atvfc.GetName(); } else { key = $"{arrayName}[{i}]"; } EnumValueTypes evt; if (atvfc.GetValue() != null) { evt = atvfc.GetValue().GetValueType(); if (evt != EnumValueTypes.None) { if (1 <= (int)evt && (int)evt <= 12) { string value = atvfc.GetValue().AsString(); PGProperty prop = new PGProperty(key, value); prop.category = category; SetSelectedStateIfSelected(info, prop); node.Add(prop); PopulateDataGrid(atvfc, prop, info, category); } else if (evt == EnumValueTypes.Array) { PGProperty childProps = new PGProperty("child", null, $"[size: {atvfc.childrenCount}]"); PGProperty prop = new PGProperty(key, childProps, $"[size: {atvfc.childrenCount}]"); prop.category = category; SetSelectedStateIfSelected(info, prop); node.Add(prop); PopulateDataGrid(atvfc, childProps, info, category, true); } else if (evt == EnumValueTypes.ByteArray) { PGProperty childProps = new PGProperty("child", null, $"[bytes size: {atvfc.GetValue().AsByteArray().size}]"); PGProperty prop = new PGProperty(key, childProps, $"[bytes size: {atvfc.GetValue().AsByteArray().size}]"); prop.category = category; SetSelectedStateIfSelected(info, prop); node.Add(prop); } } } else { PGProperty childProps; if (atvfc.childrenCount == 2) { AssetTypeValueField fileId = atvfc.children[0]; AssetTypeValueField pathId = atvfc.children[1]; string fileIdName = fileId.templateField.name; string fileIdType = fileId.templateField.type; string pathIdName = pathId.templateField.name; string pathIdType = pathId.templateField.type; if (fileIdName == "m_FileID" && fileIdType == "int" && pathIdName == "m_PathID" && pathIdType == "SInt64") { int fileIdValue = fileId.GetValue().AsInt(); long pathIdValue = pathId.GetValue().AsInt64(); childProps = new PGProperty("child", "", $"[fileid: {fileIdValue}, pathid: {pathIdValue}]"); } else { childProps = new PGProperty("child", ""); } } else { childProps = new PGProperty("child", ""); } PGProperty prop = new PGProperty(key, childProps); prop.category = category; SetSelectedStateIfSelected(info, prop); node.Add(prop); PopulateDataGrid(atvfc, childProps, info, category); } } }
public static AssetsReplacer CreateAssetReplacer(AssetsFile file, AssetFileInfoEx info, byte[] data) { return(new AssetsReplacerFromMemory(0, info.index, (int)info.curFileType, AssetHelper.GetScriptIndex(file, info), data)); }
private async void BtnImportDump_Click(object?sender, Avalonia.Interactivity.RoutedEventArgs e) { if (await FailIfNothingSelected()) { return; } OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "Open"; ofd.Filters = new List <FileDialogFilter>() { new FileDialogFilter() { Name = "UABE text dump", Extensions = new List <string>() { "txt" } }, new FileDialogFilter() { Name = "UABE json dump", Extensions = new List <string>() { "json" } } }; string[] fileList = await ofd.ShowAsync(this); if (fileList.Length == 0) { return; } string file = fileList[0]; if (file != null && file != string.Empty) { if (file.EndsWith(".json")) { await MessageBoxUtil.ShowDialog(this, "Not implemented", "There's no json dump support yet, sorry."); return; } using (FileStream fs = File.OpenRead(file)) using (StreamReader sr = new StreamReader(fs)) { AssetFileInfoEx selectedInfo = GetSelectedInfo(); long selectedId = selectedInfo.index; AssetImportExport importer = new AssetImportExport(); byte[]? bytes = importer.ImportTextAsset(sr); if (bytes == null) { await MessageBoxUtil.ShowDialog(this, "Parse error", "Something went wrong when reading the dump file."); return; } AssetsReplacer replacer = AssetImportExport.CreateAssetReplacer(assetsFile.file, selectedInfo, bytes); newAssets[selectedId] = replacer; newAssetDatas[selectedId] = new MemoryStream(bytes); SetSelectedFieldModified(); modified = true; } } }
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.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(type.name.GetString(cldb)); }
private static void FinalizeAsset(AssetsFileInstance file, AssetTypeValueField field, AssetFileInfoEx info) { if (info.curFileType == 0x01) // GameObject { var ComponentArray = field.Get("m_Component").Get("Array"); //remove all null pointers List <AssetTypeValueField> newFields = ComponentArray.pChildren.Where(f => f.pChildren[0].pChildren[1].GetValue().AsInt64() != 0 ).ToList(); var newSize = (uint)newFields.Count; ComponentArray.SetChildrenList(newFields.ToArray(), newSize); ComponentArray.GetValue().Set(new AssetTypeArray() { size = newSize }); } else if (info.curFileType == 0x73) // MonoScript { var m_AssemblyName = field.Get("m_AssemblyName").GetValue(); if (m_AssemblyName.AsString().Equals("Assembly-CSharp.dll")) { m_AssemblyName.Set("HKCode.dll"); } else if (m_AssemblyName.AsString().Equals("Assembly-CSharp-firstpass.dll")) { m_AssemblyName.Set("HKCode-firstpass.dll"); } } else if (info.curFileType == 0x1c) // Texture2D { var path = field.Get("m_StreamData").Get("path"); var pathString = path.GetValue().AsString(); var directory = Path.GetDirectoryName(file.path); if (directory == null) { Debug.LogWarning("Texture2D has null stream data path!"); return; } var fixedPath = Path.Combine(directory, pathString); path.GetValue().Set(fixedPath); } else if (info.curFileType == 0x53) // AudioClip { var path = field.Get("m_Resource").Get("m_Source"); var pathString = path.GetValue().AsString(); var directory = Path.GetDirectoryName(file.path); if (directory == null) { Debug.LogWarning("AudioClip has null resource source path!"); return; } var fixedPath = Path.Combine(directory, pathString); path.GetValue().Set(fixedPath); } }
public static void GenerateDiffFile(AssetsManager am, AssetsFileInstance origInst, AssetsFileInstance newInst, HKWEMeta meta) { EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f); am.UpdateDependencies(); DiffData result = new DiffData() { goChanges = new List <GameObjectChange>(), goAdditions = new List <GameObjectAddition>() }; Dictionary <EditDifferData, long> differToNewId = new Dictionary <EditDifferData, long>(); Dictionary <long, EditDifferData> origIdToDiffer = new Dictionary <long, EditDifferData>(); List <EditDifferData> differData = new List <EditDifferData>(); AssetsFileTable newTable = newInst.table; List <AssetFileInfoEx> newGos = newTable.GetAssetsOfType(0x01); for (int i = 0; i < newGos.Count; i++) { if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Finding diff IDs... (step 1/3)", (float)i / newGos.Count); } AssetFileInfoEx inf = newGos[i]; AssetTypeValueField baseField = am.GetATI(newInst.file, inf).GetBaseField(); AssetTypeValueField editDifferMono = GetEDMono(am, newInst, baseField); EditDifferData diff = new EditDifferData() { fileId = editDifferMono.Get("fileId").GetValue().AsInt(), pathId = editDifferMono.Get("pathId").GetValue().AsInt64(), origPathId = editDifferMono.Get("origPathId").GetValue().AsInt64(), newAsset = editDifferMono.Get("newAsset").GetValue().AsBool() }; origIdToDiffer[diff.origPathId] = diff; differData.Add(diff); } ////////////////////////// AssetsFileTable origTable = origInst.table; List <AssetFileInfoEx> origGos = origTable.GetAssetsOfType(0x01); List <long> origDeletIds = new List <long>(); int nextBundleId = 1; // == delete changes == // for (int i = 0; i < origGos.Count; i++) { if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Checking for deletes... (step 2/3)", (float)i / origGos.Count); } AssetFileInfoEx inf = newGos[i]; if (!differData.Any(d => d.origPathId == inf.index)) { GameObjectChange change = new GameObjectChange { flags = GameObjectChangeFlags.Deleted }; result.goChanges.Add(change); origDeletIds.Add(inf.index); } } // == add changes == // for (int i = 0; i < differData.Count; i++) { if (i % 100 == 0) { EditorUtility.DisplayProgressBar("HKEdit", "Checking for additions... (step 2/3)", (float)i / differData.Count); } EditDifferData dat = differData[i]; if (dat.newAsset) { ReferenceCrawlerBundle crawler = new ReferenceCrawlerBundle(am); long newPathId = differToNewId[dat]; AssetFileInfoEx inf = newInst.table.GetAssetInfo(newPathId); crawler.SetReferences(newInst, inf); GameObjectAddition addition = new GameObjectAddition { bundleId = nextBundleId, parentId = dat.pathId, dependencies = new List <GameObjectAdditionDependency>() }; nextBundleId++; foreach (KeyValuePair <AssetID, AssetID> goRef in crawler.references) { addition.dependencies.Add(new GameObjectAdditionDependency { parentId = goRef.Key.pathId, bundleId = goRef.Value.pathId }); } result.goAdditions.Add(addition); } else { ReferenceCrawlerBundle crawler = new ReferenceCrawlerBundle(am); long newPathId = differToNewId[dat]; AssetFileInfoEx inf = newInst.table.GetAssetInfo(newPathId); crawler.SetReferences(newInst, inf); } } }
// TODO: why does this only target three file types private static bool IsAsset(AssetFileInfoEx inf) { return(inf.curFileType == 0x1c || inf.curFileType == 0x30 || inf.curFileType == 0x53); }
public static AssetTypeValueField GetMonoBaseField(AssetsManager am, AssetsFileInstance inst, AssetFileInfoEx info, string managedPath, bool cached = true) { AssetsFile file = inst.file; AssetTypeTemplateField baseField = new AssetTypeTemplateField(); baseField.FromClassDatabase(am.classFile, AssetHelper.FindAssetClassByID(am.classFile, info.curFileType), 0); AssetTypeInstance mainAti = new AssetTypeInstance(baseField, file.reader, info.absoluteFilePos); ushort scriptIndex = AssetHelper.GetScriptIndex(file, info); if (scriptIndex != 0xFFFF) { AssetTypeInstance scriptAti = am.GetExtAsset(inst, mainAti.GetBaseField().Get("m_Script")).instance; string scriptName = scriptAti.GetBaseField().Get("m_ClassName").GetValue().AsString(); string scriptNamespace = scriptAti.GetBaseField().Get("m_Namespace").GetValue().AsString(); string assemblyName = scriptAti.GetBaseField().Get("m_AssemblyName").GetValue().AsString(); string assemblyPath = Path.Combine(managedPath, assemblyName); if (scriptNamespace != string.Empty) { scriptName = scriptNamespace + "." + scriptName; } if (File.Exists(assemblyPath)) { AssemblyDefinition asmDef; if (cached) { if (!loadedAssemblies.ContainsKey(assemblyName)) { loadedAssemblies.Add(assemblyName, GetAssemblyWithDependencies(assemblyPath)); } asmDef = loadedAssemblies[assemblyName]; } else { asmDef = GetAssemblyWithDependencies(assemblyPath); } MonoDeserializer mc = new MonoDeserializer(); mc.Read(scriptName, asmDef, new UnityVersion(inst.file.typeTree.unityVersion)); List <AssetTypeTemplateField> monoTemplateFields = mc.children; AssetTypeTemplateField[] templateField = baseField.children.Concat(monoTemplateFields).ToArray(); baseField.children = templateField; baseField.childrenCount = baseField.children.Length; mainAti = new AssetTypeInstance(baseField, file.reader, info.absoluteFilePos); } } return(mainAti.GetBaseField()); }
public AssetTypeInstance GetTypeInstance(AssetsFileInstance inst, AssetFileInfoEx info, bool forceFromCldb = false) { return(GetTypeInstance(inst.file, info, forceFromCldb)); }
private void LoadComponentData(PGProperty root, AssetTypeValueField baseField, AssetFileInfoEx info, int index, int size) { string className = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType) .name.GetString(helper.classFile); AssetTypeValueField targetBaseField = baseField; if (className == "MonoBehaviour") { if (AssetUtils.AllDependenciesLoaded(helper, inst)) { className += $" ({GetClassName(helper, inst, targetBaseField)})"; string managedPath = Path.Combine(Path.GetDirectoryName(inst.path), "Managed"); if (Directory.Exists(managedPath)) { targetBaseField = helper.GetMonoBaseFieldCached(inst, info, managedPath); } } else if (!firstTimeMBMessage) { firstTimeMBMessage = true; MessageBox.Show("Can't display MonoBehaviour data until dependencies are loaded", "Assets View"); } } string category = new string('\t', size - index) + className; RecursiveTreeLoad(targetBaseField, root, info, category); }