private static string GetAssetNameFast(int fileId, long pathId, AssetsFileInstance inst) { if (pathId == 0) { return(""); } AssetsFile file = null; AssetsFileTable table = null; if (fileId == 0) { file = inst.file; table = inst.table; } else { AssetsFileInstance dep = inst.dependencies[fileId - 1]; file = dep.file; table = dep.table; } AssetFileInfoEx inf = table.getAssetInfo((ulong)pathId); AssetsFileReader reader = file.reader; if (allowed.Contains(inf.curFileType)) { reader.Position = inf.absoluteFilePos; return(reader.ReadCountStringInt32()); } if (inf.curFileType == 0x1) { reader.Position = inf.absoluteFilePos; int size = reader.ReadInt32(); reader.Position += (ulong)(size * 12); reader.Position += 4; return(reader.ReadCountStringInt32()); } else if (inf.curFileType == 0x72) { reader.Position = inf.absoluteFilePos; reader.Position += 28; string name = reader.ReadCountStringInt32(); if (name != "") { return(name); } } return(""); }
public void LoadFSM(AssetsManager am, AssetInfo info, string folderPath) { //risky but would technically work AssetsFileInstance assetsFileInstance = am.files.First(); AssetsFile assetsFile = assetsFileInstance.file; AssetsFileTable assetsTable = assetsFileInstance.table; AssetFileInfoEx afi = assetsTable.getAssetInfo(info.id); AssetTypeValueField baseField = Util.GetMonoBaseField(am, assetsFile, afi, folderPath); AssetTypeValueField fsm = baseField.Get("fsm"); AssetTypeValueField states = fsm.Get("states"); dataVersion = fsm.Get("dataVersion").GetValue().AsInt(); for (int i = 0; i < states.GetValue().AsArray().size; i++) { AssetTypeValueField state = states.Get((uint)i); string name = state.Get("name").GetValue().AsString(); AssetTypeValueField rect = state.Get("position"); float x = Mathf.Floor(rect.Get("x").GetValue().AsFloat()); float y = Mathf.Floor(rect.Get("y").GetValue().AsFloat()); float width = Mathf.Floor(rect.Get("width").GetValue().AsFloat()); float height = Mathf.Floor(rect.Get("height").GetValue().AsFloat()); HandleElement rectElem = new HandleElement(HandleType.Rectangle, new Vector2(x, y), new Vector2(x + width, y + height), new Color(0.5f, 0.5f, 0.5f, 0.7f)); elements.Add(rectElem); elements.Add(new HandleElement(HandleType.Label, new Vector2(x + (width / 2), y + 3), (int)width, name)); 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)); string transitionName = dotNetTransitions[j].fsmEvent.name; elements.Add(new HandleElement(HandleType.Label, new Vector2(x + (width / 2), y + 3 + ((j + 1) * 16)), (int)width, transitionName)); } Node node = new Node(name, new Rect(x, y, width, height), dotNetTransitions, rectElem); nodes.Add(node); //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); //}; // //graphCanvas.Children.Add(node.grid); } foreach (Node node in nodes) { if (node.transitions.Length > 0) { float yPos = 25; foreach (FsmTransition trans in node.transitions) { Node endNode = nodes.Where(n => n.text == trans.toState).FirstOrDefault(); if (endNode != null) { bool isLeft, dummy; Vector2 start = ComputeLocation(node, endNode, yPos, out isLeft); Vector2 end = ComputeLocation(endNode, node, 10, out dummy); Vector2 startMiddle, endMiddle; float dist = 70; if (!isLeft) { startMiddle = new Vector2(start.x - dist, start.y); endMiddle = new Vector2(end.x + dist, end.y); } else { startMiddle = new Vector2(start.x + dist, start.y); endMiddle = new Vector2(end.x - dist, end.y); } elements.Insert(0, new HandleElement(HandleType.ArrowLine, start, end, startMiddle, endMiddle)); } else { System.Diagnostics.Debug.WriteLine(node.text + " failed to connect to " + trans.toState); } yPos += 16; } } } }
//fast transform compare since most //changes will probably be transforms private void CompareTransform(GameObject obj, ulong origPathId, List <ComponentChangeOrAdd> changes) { Transform objTransform = obj.transform; AssetFileInfoEx goInfo = assetsTable.getAssetInfo(origPathId); AssetTypeInstance goInstance = am.GetATI(assetsFile, goInfo); AssetTypeValueField transformPPtr = goInstance.GetBaseField() .Get("m_Component") .Get("Array")[0] .Get("component"); AssetTypeInstance tfmInfo = am.GetExtAsset(assetsFileInstance, transformPPtr).instance; AssetTypeValueField tfmBaseField = tfmInfo.GetBaseField(); AssetTypeValueField m_LocalPosition = tfmBaseField.Get("m_LocalPosition"); AssetTypeValueField m_LocalRotation = tfmBaseField.Get("m_LocalRotation"); AssetTypeValueField m_LocalScale = tfmBaseField.Get("m_LocalScale"); Vector3 localPosition = new Vector3( m_LocalPosition.Get("x").GetValue().AsFloat(), m_LocalPosition.Get("y").GetValue().AsFloat(), m_LocalPosition.Get("z").GetValue().AsFloat() ); Quaternion localRotation = new Quaternion( m_LocalRotation.Get("x").GetValue().AsFloat(), m_LocalRotation.Get("y").GetValue().AsFloat(), m_LocalRotation.Get("z").GetValue().AsFloat(), m_LocalRotation.Get("w").GetValue().AsFloat() ); Vector3 localScale = new Vector3( m_LocalScale.Get("x").GetValue().AsFloat(), m_LocalScale.Get("y").GetValue().AsFloat(), m_LocalScale.Get("z").GetValue().AsFloat() ); if (objTransform.localPosition != localPosition || objTransform.localRotation != localRotation || objTransform.localScale != localScale) { List <FieldChange> fieldChanges = new List <FieldChange>(); if (localPosition.x != objTransform.localPosition.x) { fieldChanges.Add(new FieldChange("m_LocalPosition/x", objTransform.localPosition.x)); } if (localPosition.y != objTransform.localPosition.y) { fieldChanges.Add(new FieldChange("m_LocalPosition/y", objTransform.localPosition.y)); } if (localPosition.z != objTransform.localPosition.z) { fieldChanges.Add(new FieldChange("m_LocalPosition/z", objTransform.localPosition.z)); } if (localRotation.w != objTransform.localRotation.w) { fieldChanges.Add(new FieldChange("m_LocalRotation/w", objTransform.localRotation.w)); } if (localRotation.x != objTransform.localRotation.x) { fieldChanges.Add(new FieldChange("m_LocalRotation/x", objTransform.localRotation.x)); } if (localRotation.y != objTransform.localRotation.y) { fieldChanges.Add(new FieldChange("m_LocalRotation/y", objTransform.localRotation.y)); } if (localRotation.z != objTransform.localRotation.z) { fieldChanges.Add(new FieldChange("m_LocalRotation/z", objTransform.localRotation.z)); } if (localScale.x != objTransform.localScale.x) { fieldChanges.Add(new FieldChange("m_LocalScale/x", objTransform.localScale.x)); } if (localScale.y != objTransform.localScale.y) { fieldChanges.Add(new FieldChange("m_LocalScale/y", objTransform.localScale.y)); } if (localScale.z != objTransform.localScale.z) { fieldChanges.Add(new FieldChange("m_LocalScale/z", objTransform.localScale.z)); } changes.Add(new ComponentChangeOrAdd() { isNewComponent = false, componentIndex = 0, componentType = "Transform", changes = fieldChanges }); //Debug.Log("diffing " + obj.name + "'s transform"); } }
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 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()); } }