private void RecursiveChildSearch(TreeNode node, AssetTypeValueField field) { AssetTypeValueField children = helper.GetExtAsset(inst, field.Get("m_Component") .Get("Array") .Get(0) .Get("component")).instance .GetBaseField() .Get("m_Children") .Get("Array"); for (int i = 0; i < children.GetValue().AsArray().size; i++) { AssetTypeInstance newInstance = helper.GetExtAsset(inst, children.Get((uint)i)).instance; AssetsManager.AssetExternal gameObjExt = helper.GetExtAsset(inst, newInstance.GetBaseField().Get("m_GameObject")); AssetTypeInstance newAti = gameObjExt.instance; AssetTypeValueField newBaseField = newAti.GetBaseField(); TreeNode newNode = node.Nodes.Add(newBaseField.Get("m_Name").GetValue().AsString()); if (!newBaseField.Get("m_IsActive").GetValue().AsBool()) { newNode.ForeColor = Color.DarkRed; } newNode.Tag = newBaseField; if (gameObjExt.info.index == selectedIndex) { goTree.SelectedNode = newNode; } RecursiveChildSearch(newNode, newBaseField); } }
private PGProperty LoadGameObjectData(AssetTypeValueField field) { PGProperty root = new PGProperty("root"); AssetTypeValueField components = field.Get("m_Component").Get("Array"); int componentSize = (int)components.GetValue().AsArray().size; for (int i = 0; i < componentSize; i++) { AssetTypeValueField componentPtr = components[(uint)i].Get("component"); AssetsManager.AssetExternal ext = helper.GetExtAsset(inst, componentPtr); LoadComponentData(root, ext.instance.GetBaseField(), ext.info, i, componentSize); } return(root); }
private void FindReferencesRecurse(AssetsFileInstance inst, AssetTypeValueField field) { foreach (AssetTypeValueField child in field.pChildren) { //not a value (ie not an int) if (!child.templateField.hasValue) { //not null if (child == null) { return; } //not array of values either if (child.templateField.isArray && child.templateField.children[1].valueType != EnumValueTypes.ValueType_None) { break; } string typeName = child.templateField.type; //is a pptr 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(); //not a null pptr if (pathId == 0) { continue; } AssetID aid = ConvertToAssetID(inst, fileId, pathId); AssetsManager.AssetExternal ext = am.GetExtAsset(inst, fileId, pathId); //not already visited and not a gameobject or monobehaviour if (references.ContainsKey(aid) || ext.info.curFileType == 0x01 || ext.info.curFileType == 0x72) { continue; } AddReference(aid, IsAsset(ext.info)); //recurse through dependencies FindReferencesRecurse(ext.file, ext.instance.GetBaseField()); } FindReferencesRecurse(inst, child); } } }
private static AssetTypeValueField GetEDMono(AssetsManager am, AssetsFileInstance fileInst, AssetTypeValueField goBaseField) { AssetTypeValueField m_Components = goBaseField.Get("m_Components").Get("Array"); for (uint i = 0; i < m_Components.GetValue().AsArray().size; i++) { AssetTypeValueField component = m_Components[i]; AssetsManager.AssetExternal ext = am.GetExtAsset(fileInst, component, true); if (ext.info.curFileType == 0x72) { ext = am.GetExtAsset(fileInst, component, true, true); AssetTypeValueField monoBaseField = ext.instance.GetBaseField(); return(monoBaseField); } } return(null); }
private PGProperty LoadGameObjectData(AssetTypeValueField field) { PGProperty root = new PGProperty("root"); AssetTypeValueField components = field.Get("m_Component").Get("Array"); int componentSize = (int)components.GetValue().AsArray().size; for (int i = 0; i < componentSize; i++) { AssetTypeValueField componentPtr = components[(uint)i].Get("component"); if (ModifierKeys == Keys.Shift) { AssetsManager.AssetExternal ext = helper.GetExtAsset(inst, componentPtr); if (ext.instance != null) { LoadComponentData(root, ext.instance.GetBaseField(), ext.info, i, componentSize); } } else { try { AssetsManager.AssetExternal ext = helper.GetExtAsset(inst, componentPtr); if (ext.instance != null) { LoadComponentData(root, ext.instance.GetBaseField(), ext.info, i, componentSize); } } catch { if (loadedWithErrors == false) { loadedWithErrors = true; MessageBox.Show("a component failed to load. (tell nes or hold shift to throw)"); } } } } return(root); }
public static AssetsManager.AssetExternal GetExtAsset(this AssetsManager am, AssetsFileInstance relativeTo, int fileId, long pathId, bool onlyGetInfo = false) { AssetsManager.AssetExternal ext = new AssetsManager.AssetExternal(); if (fileId == 0 && pathId == 0) { ext.info = null; ext.instance = null; ext.file = null; } else if (fileId != 0) { AssetsFileInstance dep = relativeTo.dependencies[fileId - 1]; ext.info = dep.table.getAssetInfo((ulong)pathId); if (!onlyGetInfo) { ext.instance = am.GetATI(dep.file, ext.info); } else { ext.instance = null; } ext.file = dep; } else { ext.info = relativeTo.table.getAssetInfo((ulong)pathId); if (!onlyGetInfo) { ext.instance = am.GetATI(relativeTo.file, ext.info); } else { ext.instance = null; } ext.file = relativeTo; } return(ext); }
private void FollowBtn_Click(object sender, EventArgs e) { valueGrid.Focus(); GridItem item = valueGrid.SelectedGridItem; if (item.Label == "m_FileID" || item.Label == "m_PathID") { int fileId = -1; long pathId = -1; foreach (GridItem gi in item.Parent.EnumerateAllItems()) { if (gi.Label == "m_FileID") { fileId = int.Parse((string)gi.Value); } if (gi.Label == "m_PathID") { pathId = long.Parse((string)gi.Value); } } if (fileId == 0 && pathId == 0) { MessageBox.Show("cannot open null reference"); return; } else if (fileId == -1 || pathId == -1) { MessageBox.Show("could not find other id, is this really a pptr?"); return; } AssetsManager.AssetExternal ext = helper.GetExtAsset(inst, (uint)fileId, (ulong)pathId); GameObjectViewer view = new GameObjectViewer(helper, ext.file, ext.instance.GetBaseField(), ext.info); view.Show(); } }
//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; } if (child.templateField.isArray && child.templateField.children[1].valueType != EnumValueTypes.ValueType_None) { break; } 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) { UnityEngine.Debug.Log("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 || depInfo.curFileType == 224 || false) { 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); } //else // UnityEngine.Debug.Log("skipping asset with type " + depInfo.curFileType + " on " + depInfo.index); } //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) { AssetID thisId = new AssetID(inst.name, (long)info.index); 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(); } } ids[thisId] = assetData; } }
public GameObject TilemapRenderData(AssetTypeValueField transform, string name) { GameObject tileMapRenderData = new GameObject(name); GameObject scenemap = new GameObject("Scenemap"); scenemap.transform.parent = tileMapRenderData.transform; AssetTypeValueField trdChildArray = transform.Get("m_Children").Get("Array"); uint childrenCount = trdChildArray.GetValue().AsArray().size; AssetTypeValueField sceneMap = null; for (uint i = 0; i < childrenCount; i++) { AssetTypeValueField childTf = am.GetExtAsset(assetsFileInstance, trdChildArray[i]).instance.GetBaseField(); AssetTypeValueField childGo = am.GetExtAsset(assetsFileInstance, childTf.Get("m_GameObject")).instance.GetBaseField(); if (childGo.Get("m_Name").GetValue().AsString() == "Scenemap") { sceneMap = trdChildArray[i]; } } if (sceneMap == null) { return(tileMapRenderData); } AssetTypeValueField scenemapBaseField = am.GetExtAsset(assetsFileInstance, sceneMap).instance.GetBaseField(); AssetTypeValueField scenemapChildArray = scenemapBaseField.Get("m_Children").Get("Array"); childrenCount = scenemapChildArray.GetValue().AsArray().size; for (uint i = 0; i < childrenCount; i++) { AssetTypeValueField childTf = am.GetExtAsset(assetsFileInstance, scenemapChildArray[i]).instance.GetBaseField(); AssetTypeValueField childGo = am.GetExtAsset(assetsFileInstance, childTf.Get("m_GameObject")).instance.GetBaseField(); GameObject chunk = new GameObject(childGo.Get("m_Name").GetValue().AsString()); chunk.transform.parent = scenemap.transform; AssetTypeValueField m_LocalPosition = childTf.Get("m_LocalPosition"); chunk.transform.localPosition = GetVector3(m_LocalPosition); AssetTypeValueField childComp = childGo.Get("m_Component").Get("Array"); uint componentCount = childComp.GetValue().AsArray().size; for (uint j = 1; j < componentCount; j++) { AssetsManager.AssetExternal component = am.GetExtAsset(assetsFileInstance, childComp[j].Get("component")); if (component.info.curFileType == MESHFILTER) { component = am.GetExtAsset(assetsFileInstance, childComp[j].Get("component")); AssetTypeValueField mesh = component.instance.GetBaseField().Get("m_Mesh"); AssetTypeValueField meshBaseField = am.GetExtAsset(assetsFileInstance, mesh).instance.GetBaseField(); AssetTypeValueField m_VertexData = meshBaseField.Get("m_VertexData"); AssetTypeValueField m_Channels = m_VertexData.Get("m_Channels").Get("Array"); uint channelsSize = m_Channels.GetValue().AsArray().size; int skipSize = 0; //start at 1 to skip verts for (uint k = 1; k < channelsSize; k++) { skipSize += (int)m_Channels[k].Get("dimension").GetValue().AsUInt(); } byte[] m_DataSize = GetByteData(m_VertexData.Get("m_DataSize")); uint m_VertexCount = m_VertexData.Get("m_VertexCount").GetValue().AsUInt(); Vector3[] verts = new Vector3[m_VertexCount]; int pos = 0; for (uint k = 0; k < m_VertexCount; k++) { float x = ReadFloat(m_DataSize, pos); float y = ReadFloat(m_DataSize, pos + 4); float z = ReadFloat(m_DataSize, pos + 8); verts[k] = new Vector3(x, y, z); pos += 12 + (skipSize * 4); //go past verts, then any remaining channel's data } AssetTypeValueField m_IndexBuffer = meshBaseField.Get("m_IndexBuffer").Get("Array"); uint triCount = m_IndexBuffer.GetValue().AsArray().size; int[] tris = new int[triCount / 2]; for (uint k = 0; k < triCount; k += 2) { int tri = (int)(m_IndexBuffer[k + 0].GetValue().AsUInt() | (m_IndexBuffer[k + 1].GetValue().AsUInt() << 8)); tris[k / 2] = tri; } UnityEngine.Mesh meshComponent = new UnityEngine.Mesh(); chunk.AddComponent <MeshFilter>(); chunk.AddComponent <MeshRenderer>(); chunk.GetComponent <MeshFilter>().mesh = meshComponent; meshComponent.vertices = verts; meshComponent.triangles = tris; chunk.GetComponent <MeshRenderer>().material = Resources.Load <Material>("BackMat"); break; } } } return(tileMapRenderData); }
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); }
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()); } }