Пример #1
0
 private void LoadGGM(AssetsFileInstance mainFile)
 {
     //swap this with resources so we can actually see ggm assets
     foreach (AssetFileInfoEx info in mainFile.table.pAssetFileInfo)
     {
         ClassDatabaseType type = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType);
         if (type.name.GetString(helper.classFile) == "ResourceManager")
         {
             AssetTypeInstance   inst        = helper.GetATI(mainFile.file, info);
             AssetTypeValueField baseField   = inst.GetBaseField();
             AssetTypeValueField m_Container = baseField.Get("m_Container").Get("Array");
             //Dictionary<string, AssetDetails> paths = new Dictionary<string, AssetDetails>();
             List <AssetDetails> assets = new List <AssetDetails>();
             for (uint i = 0; i < m_Container.GetValue().AsArray().size; i++)
             {
                 AssetTypeValueField item = m_Container[i];
                 string path = item.Get("first").GetValue().AsString();
                 AssetTypeValueField pointerField = item.Get("second");
                 uint  fileID = (uint)pointerField.Get("m_FileID").GetValue().AsInt();
                 ulong pathID = (ulong)pointerField.Get("m_PathID").GetValue().AsInt64();
                 //paths[path] = new AssetDetails(new AssetPPtr(fileID, pathID));
                 assets.Add(new AssetDetails(new AssetPPtr(fileID, pathID), AssetIcon.Unknown, path));
             }
             rootDir = new FSDirectory();
             //rootDir.Create(paths);
             rootDir.Create(assets);
             ChangeDirectory("");
             helper.UpdateDependencies();
             CheckResourcesInfo();
             return;
         }
     }
 }
Пример #2
0
        private void LoadResources(AssetsFileInstance ggm)
        {
            foreach (AssetFileInfoEx info in ggm.table.assetFileInfo)
            {
                ClassDatabaseType type = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType);
                if (type.name.GetString(helper.classFile) == "ResourceManager")
                {
                    AssetTypeInstance   inst        = helper.GetATI(ggm.file, info);
                    AssetTypeValueField baseField   = inst.GetBaseField();
                    AssetTypeValueField m_Container = baseField.Get("m_Container").Get("Array");
                    List <AssetDetails> assets      = new List <AssetDetails>();
                    for (int i = 0; i < m_Container.GetValue().AsArray().size; i++)
                    {
                        AssetTypeValueField item = m_Container[i];
                        string path = item.Get("first").GetValue().AsString();
                        AssetTypeValueField pointerField = item.Get("second");
                        //paths[path] = new AssetDetails(new AssetPPtr(fileID, pathID));

                        AssetExternal     assetExt  = helper.GetExtAsset(ggm, pointerField, true);
                        AssetFileInfoEx   assetInfo = assetExt.info;
                        ClassDatabaseType assetType = AssetHelper.FindAssetClassByID(helper.classFile, assetInfo.curFileType);
                        if (assetType == null)
                        {
                            continue;
                        }
                        string assetTypeName = assetType.name.GetString(helper.classFile);
                        string assetName     = AssetInfo.GetAssetNameFast(assetInfo, helper.classFile, assetType, assetExt.file);
                        if (path.Contains("/"))
                        {
                            if (path.Substring(path.LastIndexOf('/') + 1) == assetName.ToLower())
                            {
                                path = path.Substring(0, path.LastIndexOf('/') + 1) + assetName;
                            }
                        }
                        else
                        {
                            if (path == assetName.ToLower())
                            {
                                path = path.Substring(0, path.LastIndexOf('/') + 1) + assetName;
                            }
                        }

                        assets.Add(new AssetDetails(new AssetPPtr(0, assetInfo.index), GetIconForName(assetTypeName), path, assetTypeName, (int)assetInfo.curFileSize));
                    }
                    rootDir = new FSDirectory();
                    //rootDir.Create(paths);
                    rootDir.Create(assets);
                    ChangeDirectory("");
                    helper.UpdateDependencies();
                    CheckResourcesInfo();
                    return;
                }
            }
        }
Пример #3
0
        public static void GenerateDiffFile(AssetsManager am, AssetsFileInstance inst, AssetsFileInstance newInst, HKWEMeta meta)
        {
            EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f);
            am.UpdateDependencies();

            Dictionary <AssetID, AssetID> newToOldIds = new Dictionary <AssetID, AssetID>();

            AssetsFileTable newTable = newInst.table;

            List <AssetFileInfoEx> initialGameObjects = newTable.GetAssetsOfType(0x01);

            for (int i = 0; i < initialGameObjects.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Finding diff IDs... (step 1/3)", (float)i / initialGameObjects.Count);
                }
                AssetFileInfoEx     inf       = initialGameObjects[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()
                };
            }
        }
Пример #4
0
        static void PatchVR(string gameManagersBackupPath, string gameManagersPath, string classDataPath)
        {
            Console.WriteLine("Patching globalgamemanagers...");
            Console.WriteLine($"Using classData file from path '{classDataPath}'");

            AssetsManager am = new AssetsManager();

            am.LoadClassPackage(classDataPath);
            AssetsFileInstance ggm      = am.LoadAssetsFile(gameManagersBackupPath, false);
            AssetsFile         ggmFile  = ggm.file;
            AssetsFileTable    ggmTable = ggm.table;

            am.LoadClassDatabaseFromPackage(ggmFile.typeTree.unityVersion);

            List <AssetsReplacer> replacers = new List <AssetsReplacer>();

            AssetFileInfoEx        buildSettings     = ggmTable.GetAssetInfo(11);
            AssetTypeValueField    buildSettingsBase = am.GetATI(ggmFile, buildSettings).GetBaseField();
            AssetTypeValueField    enabledVRDevices  = buildSettingsBase.Get("enabledVRDevices").Get("Array");
            AssetTypeTemplateField stringTemplate    = enabledVRDevices.templateField.children[1];

            AssetTypeValueField[] vrDevicesList = new AssetTypeValueField[] { StringField("OpenVR", stringTemplate) };
            enabledVRDevices.SetChildrenList(vrDevicesList);

            replacers.Add(new AssetsReplacerFromMemory(0, buildSettings.index, (int)buildSettings.curFileType, 0xffff, buildSettingsBase.WriteToByteArray()));

            using (AssetsFileWriter writer = new AssetsFileWriter(File.OpenWrite(gameManagersPath)))
            {
                ggmFile.Write(writer, 0, replacers, 0);
            }
        }
Пример #5
0
    private static void ReplacePointers(AssetsFileInstance file, AssetFileInfoEx info, long pathId)
    {
        var baseField = am.GetATI(file.file, info).GetBaseField();

        FindNestedPointers(file, baseField, info, true);
        FinalizeAsset(file, baseField, info);

        byte[] baseFieldData;
        using (MemoryStream ms = new MemoryStream())
            using (AssetsFileWriter w = new AssetsFileWriter(ms))
            {
                w.bigEndian = false;

                // Copy all data from base field into byte array
                baseField.Write(w);
                baseFieldData = ms.ToArray();
            }
        AssetsReplacer replacer = new AssetsReplacerFromMemory(0, (ulong)pathId, (int)info.curFileType, 0xFFFF, baseFieldData);

        if (IsAsset(info))
        {
            assetReplacers.Add(replacer);
        }
        //else if (info.curFileType == 0x73) monoReplacers.Add(replacer);
        else
        {
            sceneReplacers.Add(replacer);
        }
    }
Пример #6
0
        private static List <ulong> CrawlPPtrs(AssetsManager am, AssetsFileInstance inst, ulong startingId, List <ulong> depIds)
        {
            AssetFileInfoEx     info      = inst.table.getAssetInfo(startingId);
            AssetTypeValueField baseField = am.GetATI(inst.file, info).GetBaseField();

            RecurseType(am, inst, baseField, depIds, 0);
            return(depIds);
        }
Пример #7
0
        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));
        }
Пример #8
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (startedScanning)
            {
                return;
            }
            listBox1.Items.Clear();
            startedScanning    = true;
            loadingBar.Maximum = details.Count;

            if (textBox1.Text == "")
            {
                return;
            }
            long searchNum = long.Parse(textBox1.Text);

            BackgroundWorker bw = new BackgroundWorker();

            bw.WorkerReportsProgress = true;
            bw.DoWork += delegate(object s, DoWorkEventArgs ev) {
                for (int i = 0; i < details.Count; i++)
                {
                    AssetDetails ad = details[i];
                    if (ad.fileID != 0 && !checkBox1.Checked)
                    {
                        continue;
                    }
                    if (ad.typeName == "GameObject")
                    {
                        AssetTypeInstance   gameObjectAti = manager.GetATI(manager.GetStream(ad.fileID), manager.GetInfo(ad.fileID, ad.pathID));
                        AssetTypeValueField components    = gameObjectAti.GetBaseField().Get("m_Component").Get("Array");
                        for (uint j = 0; j < components.GetValue().AsArray().size; j++)
                        {
                            int  fileId = components.Get(j).Get("component").Get("m_FileID").GetValue().AsInt();
                            long pathId = components.Get(j).Get("component").Get("m_PathID").GetValue().AsInt64();
                            if (pathId == searchNum)
                            {
                                bw.ReportProgress(i, gameObjectAti.GetBaseField().Get("m_Name").GetValue().AsString() + "(" + ad.fileID + "/" + ad.pathID + ")");
                            }
                        }
                        bw.ReportProgress(i);
                    }
                }
                startedScanning = false;
            };
            bw.ProgressChanged += delegate(object s, ProgressChangedEventArgs ev) {
                loadingBar.Value = ev.ProgressPercentage;
                if (ev.UserState != null)
                {
                    listBox1.Items.Add(ev.UserState);
                }
            };
            bw.RunWorkerAsync();
        }
Пример #9
0
        public static AssetExternal GetExtAsset(this AssetsManager am, AssetsFileInstance relativeTo, int fileId, long pathId, bool onlyGetInfo = false)
        {
            AssetExternal ext = new 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(pathId);
                if (!onlyGetInfo)
                {
                    ext.instance = am.GetATI(dep.file, ext.info);
                }
                else
                {
                    ext.instance = null;
                }
                ext.file = dep;
            }
            else
            {
                ext.info = relativeTo.table.GetAssetInfo(pathId);
                if (!onlyGetInfo)
                {
                    ext.instance = am.GetATI(relativeTo.file, ext.info);
                }
                else
                {
                    ext.instance = null;
                }
                ext.file = relativeTo;
            }
            return(ext);
        }
Пример #10
0
        public static void CrawlReplacePPtrs(AssetsManager am, AssetsFileInstance inst, ulong startingId, List <string> fileNames, Dictionary <AssetID, byte[]> depIds, Dictionary <AssetID, long> aidToPid, Dictionary <long, long> gidToMid)
        {
            AssetFileInfoEx     info = inst.table.getAssetInfo(startingId);
            AssetTypeValueField baseField;

            if (info.curFileType == 0x72)
            {
                baseField = am.GetMonoBaseFieldCached(inst, info, Path.Combine(Path.GetDirectoryName(inst.path), "Managed"), fileNames, aidToPid);
            }
            else
            {
                baseField = am.GetATI(inst.file, info).GetBaseField();
            }
            RecurseTypeReplace(am, inst, info, baseField, fileNames, depIds, aidToPid, gidToMid, 0);
        }
Пример #11
0
        private void ImportAssets()
        {
            var inf       = currentFile.table.GetAssetInfo("MyBoringAsset");
            var baseField = helper.GetATI(currentFile.file, inf).GetBaseField();

            baseField.Get("m_Name")
            .GetValue()
            .Set("MyCoolAsset");
            var newGoBytes = baseField.WriteToByteArray();
            //AssetsReplacerFromMemory's monoScriptIndex should always be 0xFFFF unless it's a MonoBehaviour
            var repl   = new AssetsReplacerFromMemory(0, inf.index, (int)inf.curFileType, 0xFFFF, newGoBytes);
            var writer = new AssetsFileWriter(File.OpenWrite("resources-modified.assets"));

            currentFile.file.Write(writer, 1, new AssetsReplacer[] { repl }.ToList(), 1);
        }
Пример #12
0
        public static AssetTypeValueField GetField(long id, out string className)
        {
            className = "";
            string             path       = DirctoryPath;
            AssetsManager      helper     = AssetsManager;
            ClassDatabaseFile  classFile  = helper.classFile;
            AssetsFileInstance correctAti = AssetsFileInstance;
            AssetFileInfoEx    info       = correctAti.table.GetAssetInfo(id);

            if (info == null)
            {
                Console.WriteLine($"path_id:{id} is not found,maybe in other file");
                return(null);
            }

            ClassDatabaseType   classType = AssetHelper.FindAssetClassByID(classFile, info.curFileType);
            string              typeName  = classType.name.GetString(classFile);
            AssetTypeValueField baseField = helper.GetATI(correctAti.file, info).GetBaseField();

            className = AssetHelper.FindAssetClassByID(helper.classFile, info.curFileType)
                        .name.GetString(helper.classFile);
            AssetTypeValueField targetBaseField = baseField;

            if (className == "MonoBehaviour")
            {
                if (AssetUtils.AllDependenciesLoaded(helper, correctAti))
                {
                    className += $"--{GetClassName(helper, correctAti, targetBaseField)}--{targetBaseField[3].value.AsString().TrimEnd('\0')}--";
                    string managedPath = Path.Combine(Path.GetDirectoryName(correctAti.path), "Managed");
                    if (Directory.Exists(managedPath))
                    {
                        targetBaseField = helper.GetMonoBaseFieldCached(correctAti, info, managedPath);
                    }
                }
                else
                {
                    MessageBox.Show("Can't display MonoBehaviour data until dependencies are loaded", "Assets View");
                    return(null);
                }
            }
            else
            {
                className += "--";
            }
            return(targetBaseField);
        }
Пример #13
0
        internal static void ChangeDisableUnityAudio(string path, bool newValue, QModGame game)
        {
            if (game != QModGame.Subnautica && game != QModGame.BelowZero)
            {
                throw new ArgumentException("Neither Subnautica nor Below Zero detected!");
            }
            AssetsManager      am  = new AssetsManager();
            AssetsFileInstance afi = am.LoadAssetsFile(path, false);

            if (game == QModGame.Subnautica)
            {
                am.LoadClassDatabase("cldb.dat");
            }
            else
            {
                am.LoadClassDatabase("cldb2018.dat");
            }
            AssetFileInfoEx     audioInfo      = afi.table.getAssetInfo(4);
            AssetTypeInstance   audioAti       = am.GetATI(afi.file, audioInfo);
            AssetTypeValueField audioBaseField = audioAti.GetBaseField();

            audioBaseField.Get("m_DisableAudio").GetValue().Set(newValue);
            byte[] audioAsset;
            using (MemoryStream memStream = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(memStream))
                {
                    writer.bigEndian = false;
                    audioBaseField.Write(writer);
                    audioAsset = memStream.ToArray();
                }
            List <AssetsReplacer> rep = new List <AssetsReplacer>()
            {
                new AssetsReplacerFromMemory(0, 4, 0x0B, 0xFFFF, audioAsset)
            };

            using (MemoryStream memStream = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(memStream))
                {
                    afi.file.Write(writer, 0, rep.ToArray(), 0);
                    afi.stream.Close();
                    File.WriteAllBytes(path, memStream.ToArray());
                }
        }
Пример #14
0
        private static string GetLevelName(AssetsManager am, int index)
        {
            AssetsFileInstance inst = am.files.FirstOrDefault(f => f.name == "globalgamemanagers");

            if (inst == null)
            {
                return(string.Empty);
            }
            AssetFileInfoEx bsInf = inst.table.GetAssetsOfType(0x8D).FirstOrDefault(); //BuildSettings

            if (bsInf == null)
            {
                return(string.Empty);
            }
            AssetTypeValueField bsBaseField = am.GetATI(inst.file, bsInf).GetBaseField();
            AssetTypeValueField scenes      = bsBaseField.Get("scenes").Get("Array");

            return(scenes[(uint)index].GetValue().AsString());
        }
Пример #15
0
    public static void OpenSceneByName()
    {
        AssetsManager am = new AssetsManager();

        am.LoadClassPackage(Path.Combine(Application.dataPath, "cldb.dat"));

        string gameDataPath = GetGamePath();

        AssetsFileInstance inst          = am.LoadAssetsFile(Path.Combine(gameDataPath, "globalgamemanagers"), false);
        AssetFileInfoEx    buildSettings = inst.table.getAssetInfo(11);

        List <string>       scenes     = new List <string>();
        AssetTypeValueField baseField  = am.GetATI(inst.file, buildSettings).GetBaseField();
        AssetTypeValueField sceneArray = baseField.Get("scenes").Get("Array");

        for (uint i = 0; i < sceneArray.GetValue().AsArray().size; i++)
        {
            scenes.Add(sceneArray[i].GetValue().AsString() + "[" + i + "]");
        }
        SceneSelector sel = SceneSelector.ShowDialog(am, scenes, gameDataPath);
    }
Пример #16
0
        public IList <AssetsToolsAsset> GetAssets()
        {
            var assets = new List <AssetsToolsAsset>();

            foreach (var info in assetsFile.table.assetFileInfo)
            {
                var type = AssetHelper.FindAssetClassByID(manager.classFile, info.curFileType);
                if (type == null)
                {
                    continue;
                }

                var typeName  = type.name.GetString(manager.classFile);
                var assetName = AssetHelper.GetAssetNameFast(assetsFile.file, manager.classFile, info);
                var baseField = manager.GetATI(assetsFile.file, info).GetBaseField();

                assets.Add(new AssetsToolsAsset(info, typeName, assetName, baseField));
            }

            return(assets);
        }
Пример #17
0
        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();
                }
        }
Пример #18
0
    private static void LoadScene()
    {
        am = new AssetsManager();
        am.LoadClassPackage("cldb.dat");
        am.useTemplateFieldCache = true;
        am.updateAfterLoad       = false;

        hkDir = Util.SteamHelper.GetHollowKnightDataPath();

        var globalgamemanagers = am.LoadAssetsFile(Path.Combine(hkDir, "globalgamemanagers"), false);
        var buildSettings      = globalgamemanagers.table.getAssetInfo(11);

        var baseField = am.GetATI(globalgamemanagers.file, buildSettings).GetBaseField();

        var scenesArray = baseField.Get("scenes").Get("Array");

        // TODO: Allow level to be selected
        const int level = 0;

        var levelName = scenesArray[level].GetValue().AsString().Substring(14);

        levelName = levelName.Substring(0, levelName.Length - 6);

        progressBarTitle = "Loading Scene #" + level + ": " + levelName;

        if (ShouldCancel("Checking workspace", 0.2f))
        {
            return;
        }

        if (!baseField.Get("m_Version").GetValue().AsString().Equals(Application.unityVersion))
        {
            EditorUtility.ClearProgressBar();
            EditorUtility.DisplayDialog("Incorrect Unity version!", " You are using " +
                                        Application.unityVersion + " but the assets are compiled for version " +
                                        baseField.Get("m_Version").GetValue().AsString(), "Ok");
            return;
        }

        unityVersion = Application.unityVersion;

        if (!Directory.Exists(scenesDir))
        {
            Directory.CreateDirectory(scenesDir);
        }

        if (!Directory.Exists(dataDir))
        {
            Directory.CreateDirectory(dataDir);
        }

        var metaFilePath   = Path.Combine(scenesDir, "level" + level + ".unity.meta");
        var sceneFilePath  = Path.Combine(scenesDir, "level" + level + ".unity");
        var assetsFilePath = Path.Combine(dataDir, "level" + level + ".assets");

        if (File.Exists(sceneFilePath))
        {
            if (EditorUtility.DisplayDialog("Overwrite scene?", "" +
                                            " You have already exported this scene. Would you like to overwrite it or open the existing scene? ",
                                            "Open Existing", "Overwrite"))
            {
                if (ShouldCancel("Opening Scene", 0.5f))
                {
                    return;
                }
                EditorSceneManager.OpenScene(sceneFilePath);
                EditorUtility.ClearProgressBar();
                return;
            }
            else
            {
                File.Delete(sceneFilePath);
            }
        }

        if (File.Exists(metaFilePath))
        {
            File.Delete(metaFilePath);
        }
        if (File.Exists(assetsFilePath))
        {
            File.Delete(assetsFilePath);
        }

        curSceneId = 1;
        curAssetId = 1;

        pointers       = new Dictionary <AssetID, AssetID>();
        sceneReplacers = new List <AssetsReplacer>();
        assetReplacers = new List <AssetsReplacer>();
        monoReplacers  = new List <AssetsReplacer>();

        if (ShouldCancel("Reading level file", 0.5f))
        {
            return;
        }
        var scenePath = Path.Combine(Util.SteamHelper.GetHollowKnightDataPath(), "level" + level);
        var scene     = am.LoadAssetsFile(scenePath, true);

        if (ShouldCancel("Updating Dependencies", 0.8f))
        {
            return;
        }
        am.UpdateDependencies();

        for (var i = 0; i < am.files.Count; i++)
        {
            if (i % 100 == 0 && ShouldCancel("Generating QLTs", (float)i / am.files.Count))
            {
                return;
            }
            am.files[i].table.GenerateQuickLookupTree();
        }

        var table                = scene.table;
        var gameObjects          = table.GetAssetsOfType(0x01);
        var gameObjectBaseFields = new Dictionary <AssetFileInfoEx, AssetTypeValueField>();

        var c = 0;

        for (c = 0; c < gameObjects.Count; c++)
        {
            if (c % 100 == 0 && ShouldCancel("Finding initial GameObjects", (float)c / gameObjects.Count))
            {
                return;
            }

            var gameObjectInfo      = gameObjects[c];
            var gameObjectBaseField = am.GetATI(scene.file, gameObjectInfo).GetBaseField();

            AddPointer(new AssetID(scene.path, (long)gameObjectInfo.index), false);
            gameObjectBaseFields.Add(gameObjectInfo, gameObjectBaseField);
        }
        c = 0;

        foreach (var pair in gameObjectBaseFields)
        {
            if (c % 100 == 0 && ShouldCancel("Recursing GameObject dependencies", (float)c / gameObjectBaseFields.Count))
            {
                return;
            }
            FindNestedPointers(scene, pair.Value, pair.Key, false);
            c++;
        }

        var types     = new List <Type_0D>();
        var typeNames = new List <string>();

        var fileToInst = am.files.ToDictionary(d => d.path);
        var j          = 0;

        foreach (var pair in pointers)
        {
            if (j % 100 == 0 && ShouldCancel("Rewiring asset pointers", (float)j / pointers.Count))
            {
                return;
            }

            var file = fileToInst[pair.Key.fileName];
            var info = file.table.getAssetInfo((ulong)pair.Key.pathId);

            var assetClass = AssetHelper.FindAssetClassByID(am.classFile, info.curFileType);
            var assetName  = assetClass.name.GetString(am.classFile);

            if (!typeNames.Contains(assetName))
            {
                var type0d = C2T5.Cldb2TypeTree(am.classFile, assetName);
                type0d.classId = (int)info.curFileType;
                types.Add(type0d);
                typeNames.Add(assetName);
            }

            ReplacePointers(file, info, pair.Value.pathId);
            j++;
        }

        if (ShouldCancel("Saving scene", 1))
        {
            return;
        }

        List <Type_0D> assetTypes = new List <Type_0D>()
        {
            C2T5.Cldb2TypeTree(am.classFile, 0x1c), // audioclip
            C2T5.Cldb2TypeTree(am.classFile, 0x30), // shader
            C2T5.Cldb2TypeTree(am.classFile, 0x53)  // texture2d
        };

        var sceneGuid = Util.UnityHelper.CreateMD5(levelName);

        UnityHelper.CreateMetaFile(sceneGuid, metaFilePath);

        var sceneFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(unityVersion, types))));
        var assetFile = new AssetsFile(new AssetsFileReader(new MemoryStream(BundleCreator.CreateBlankAssets(unityVersion, assetTypes))));

        byte[] sceneFileData;
        using (MemoryStream ms = new MemoryStream())
            using (AssetsFileWriter w = new AssetsFileWriter(ms))
            {
                w.bigEndian = false;
                sceneFile.dependencies.pDependencies = new AssetsFileDependency[]
                {
                    UnityHelper.CreateDependency(assetsFilePath),
                };
                sceneFile.dependencies.dependencyCount = 1;

                sceneFile.preloadTable.items = new AssetPPtr[] {};
                sceneFile.preloadTable.len   = 0;

                sceneFile.Write(w, 0, sceneReplacers.Concat(monoReplacers).ToArray(), 0);
                sceneFileData = ms.ToArray();
            }
        byte[] assetFileData;
        using (var ms = new MemoryStream())
            using (var w = new AssetsFileWriter(ms))
            {
                w.bigEndian = false;
                assetFile.Write(w, 0, assetReplacers.ToArray(), 0);
                assetFileData = ms.ToArray();
            }

        File.WriteAllBytes(sceneFilePath, sceneFileData);
        File.WriteAllBytes(assetsFilePath, assetFileData);

        if (ShouldCancel("Refreshing Assets", 0.95f))
        {
            return;
        }
        AssetDatabase.Refresh();
        EditorUtility.ClearProgressBar();
    }
Пример #19
0
        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);
        }
Пример #20
0
        private List <AssetInfo> GetFSMInfos(AssetsFile file, AssetsFileTable table, bool hasDataField)
        {
            List <AssetInfo> assetInfos = new List <AssetInfo>();
            uint             assetCount = table.assetFileInfoCount;
            uint             fsmTypeId  = 0;

            foreach (AssetFileInfoEx info in table.assetFileInfo)
            {
                bool isMono = false;
                if (fsmTypeId == 0)
                {
                    ushort monoType;
                    if (file.header.format <= 0x10)
                    {
                        monoType = info.scriptIndex;
                    }
                    else
                    {
                        monoType = file.typeTree.unity5Types[info.curFileTypeOrIndex].scriptIndex;
                    }

                    if (monoType != 0xFFFF)
                    {
                        isMono = true;
                    }
                }
                else if (info.curFileType == fsmTypeId)
                {
                    isMono = true;
                }
                if (isMono)
                {
                    AssetTypeInstance monoAti   = am.GetATI(file, info);
                    AssetExternal     ext       = am.GetExtAsset(curFile, monoAti.GetBaseField().Get("m_Script"));
                    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;
                        }

                        AssetsFileReader reader = file.reader;

                        long oldPos = reader.BaseStream.Position;
                        reader.BaseStream.Position  = info.absoluteFilePos;
                        reader.BaseStream.Position += 28;
                        uint length = reader.ReadUInt32();
                        reader.ReadBytes((int)length);

                        reader.Align();

                        reader.BaseStream.Position += 16;

                        if (!hasDataField)
                        {
                            reader.BaseStream.Position -= 4;
                        }

                        uint   length2 = reader.ReadUInt32();
                        string fsmName = Encoding.UTF8.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));

            return(assetInfos);
        }
Пример #21
0
        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));
            }
        }
Пример #22
0
        public static AssetTypeValueField GetBaseField(AssetsManager am, AssetsFile file, AssetFileInfoEx info)
        {
            AssetTypeInstance ati = am.GetATI(file, info);

            return(ati.GetBaseField());
        }
Пример #23
0
        private void button1_Click(object sender, EventArgs e)
        {
            if (startedScanning || finishedScanning)
            {
                return;
            }
            startedScanning    = true;
            loadingBar.Maximum = details.Count;

            Dictionary <ulong, string> monos = new Dictionary <ulong, string>();

            BackgroundWorker bw = new BackgroundWorker();

            bw.WorkerReportsProgress = true;
            bw.DoWork += delegate(object s, DoWorkEventArgs ev) {
                for (int i = 0; i < details.Count; i++)
                {
                    AssetDetails ad = details[i];
                    if (ad.fileID != 0 && !checkBox1.Checked)
                    {
                        continue;
                    }
                    string text = null;
                    if (ad.typeName == "MonoBehaviour")
                    {
                        if (ad.name != "MonoBehaviour")
                        {
                            text = ad.name + " (" + ad.fileID + "/" + ad.pathID + ")";
                        }
                        else
                        {
                            AssetTypeInstance behaviourAti = manager.GetATI(manager.GetStream(ad.fileID), manager.GetInfo(ad.fileID, ad.pathID));
                            AssetTypeInstance scriptAti    = manager.GetExtAsset(behaviourAti.GetBaseField().Get("m_Script")).instance;
                            string            scriptName   = scriptAti.GetBaseField().Get("m_Name").GetValue().AsString();
                            text = scriptName + " (" + ad.fileID + "/" + ad.pathID + ")";
                        }
                        monos.Add(ad.pathID, text);
                    }
                    bw.ReportProgress(i);
                }
                for (int i = 0; i < details.Count; i++)
                {
                    AssetDetails ad = details[i];
                    if (ad.fileID != 0 && !checkBox1.Checked)
                    {
                        continue;
                    }
                    if (ad.typeName == "GameObject")
                    {
                        AssetTypeInstance   gameObjectAti = manager.GetATI(manager.GetStream(ad.fileID), manager.GetInfo(ad.fileID, ad.pathID));
                        AssetTypeValueField components    = gameObjectAti.GetBaseField().Get("m_Component").Get("Array");
                        for (uint j = 0; j < components.GetValue().AsArray().size; j++)
                        {
                            long id = components.Get(j).Get("component").Get("m_PathID").GetValue().AsInt64();
                            if (monos.ContainsKey((ulong)id))
                            {
                                monos[(ulong)id] += " -> " + gameObjectAti.GetBaseField().Get("m_Name").GetValue().AsString() + "(" + ad.fileID + "/" + ad.pathID + ")";
                            }
                        }
                        bw.ReportProgress(i);
                    }
                }
                foreach (string str in monos.Values)
                {
                    bw.ReportProgress(details.Count, str);
                }
                startedScanning  = false;
                finishedScanning = true;
            };
            bw.ProgressChanged += delegate(object s, ProgressChangedEventArgs ev) {
                loadingBar.Value = ev.ProgressPercentage;
                if (ev.UserState != null)
                {
                    listBox1.Items.Add(ev.UserState);
                }
            };
            bw.RunWorkerAsync();
        }
Пример #24
0
    //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");
        }
    }
Пример #25
0
        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());
                }
        }
Пример #26
0
    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);
    }
Пример #27
0
        private void automaticallyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!File.Exists("pathinfo.txt"))
            {
                DialogResult res = MessageBox.Show("pathinfo.txt does not exist, would you like to create it?", "sse-adv",
                                                   MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (res == DialogResult.Yes)
                {
                    res = MessageBox.Show("are you using steam?", "sse-adv",
                                          MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (res == DialogResult.Yes)
                    {
                        File.WriteAllLines("pathinfo.txt", new[] { "steam", "appid", "game title", "game data folder name" });
                        MessageBox.Show("please fill in the values in pathinfo.txt with your game info", "sse-adv");
                        return;
                    }
                    else
                    {
                        string newGameDataPath = SelectFolder("select game's _data path");
                        if (newGameDataPath != string.Empty)
                        {
                            File.WriteAllLines("pathinfo.txt", new[] { "path", newGameDataPath });
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                else
                {
                    return;
                }
            }

            string[] pathInfoCfg = File.ReadAllLines("pathinfo.txt");
            string   gameDataPath;

            if (pathInfoCfg[0] == "steam")
            {
                int    appId          = int.Parse(pathInfoCfg[1]);
                string gameName       = pathInfoCfg[2];
                string dataFolderName = pathInfoCfg[3];
                gameDataPath = Path.Combine(SteamHelper.FindSteamGamePath(appId, gameName), dataFolderName);
            }
            else if (pathInfoCfg[0] == "path")
            {
                gameDataPath = pathInfoCfg[1];
            }
            else
            {
                MessageBox.Show("pathinfo.txt invalid", "sse-adv");
                return;
            }

            if (string.IsNullOrEmpty(gameDataPath))
            {
                return;
            }

            AssetsFileInstance inst = am.LoadAssetsFile(Path.Combine(gameDataPath, "globalgamemanagers"), false);

            am.LoadClassDatabaseFromPackage(inst.file.typeTree.unityVersion);
            AssetFileInfoEx buildSettings = inst.table.GetAssetInfo(11);

            List <string>       scenes     = new List <string>();
            AssetTypeValueField baseField  = am.GetATI(inst.file, buildSettings).GetBaseField();
            AssetTypeValueField sceneArray = baseField.Get("scenes").Get("Array");

            for (int i = 0; i < sceneArray.GetValue().AsArray().size; i++)
            {
                scenes.Add(sceneArray[i].GetValue().AsString());
            }
            sceneselect sel = new sceneselect(scenes);

            sel.ShowDialog();
            if (sel.selectedFile != string.Empty)
            {
                OpenFile(Path.Combine(gameDataPath, sel.selectedFile));
            }
        }
Пример #28
0
        //creates a lookup where assets from different built game files
        //with different fileIds and pathIds can be converted to a list
        //of pathIds in order with fileId 0 or 1 depending on the asset type
        //(stored in the references dictionary)
        public void SetReferences(AssetsFileInstance inst, AssetFileInfoEx inf)
        {
            AssetTypeValueField baseField = am.GetATI(inst.file, inf).GetBaseField();

            SetReferencesRecurse(inst, baseField);
        }
Пример #29
0
        //this is going to be a slow operation, so it's probably best to move
        //this to a post process action after unity has built the bundle
        public static void ReorderIds(AssetsManager am, AssetsFileInstance inst, ulong idOffset)
        {
            List <ulong> oldIds  = new List <ulong>();
            List <ulong> tempIds = new List <ulong>();
            Dictionary <ulong, ulong>  oldToTemp = new Dictionary <ulong, ulong>();
            Dictionary <ulong, ulong>  tempToNew = new Dictionary <ulong, ulong>();
            Dictionary <ulong, byte[]> tempData  = new Dictionary <ulong, byte[]>();
            Dictionary <ulong, byte[]> newData   = new Dictionary <ulong, byte[]>();

            //move 1:
            //move everything to the end of where it will go to
            //prevent from hitting collisions with their own ids
            foreach (AssetFileInfoEx inf in inst.table.pAssetFileInfo)
            {
                oldIds.Add(inf.index);
            }
            ulong nextId = idOffset + inst.table.assetFileInfoCount;

            foreach (AssetFileInfoEx inf in inst.table.pAssetFileInfo)
            {
                if (InClassBlacklist(inf.curFileType))
                {
                    continue;
                }
                ulong repId = nextId++;
                while (oldIds.Contains(repId))
                {
                    repId = nextId++;
                }
                tempIds.Add(repId);
                oldToTemp[inf.index] = repId;
            }
            foreach (AssetFileInfoEx inf in inst.table.pAssetFileInfo)
            {
                if (InClassBlacklist(inf.curFileType))
                {
                    continue;
                }
                AssetTypeValueField baseField = am.GetATI(inst.file, inf).GetBaseField();

                List <ulong> depIds = new List <ulong>();
                depIds.Add(inf.index);

                RecurseTypeReplace(am, inst, baseField, depIds, 0, oldToTemp);

                using (MemoryStream ms = new MemoryStream())
                    using (AssetsFileWriter w = new AssetsFileWriter(ms))
                    {
                        w.bigEndian = false;
                        baseField.Write(w);
                        tempData[inf.index] = ms.ToArray();
                    }
            }
            //update everything to a new assets file with the first move
            List <AssetsReplacer> reps = new List <AssetsReplacer>();

            foreach (AssetFileInfoEx inf in inst.table.pAssetFileInfo)
            {
                reps.Add(new AssetsRemover(0, inf.index, (int)inf.curFileType));
                if (InClassBlacklist(inf.curFileType))
                {
                    continue;
                }
                reps.Add(new AssetsReplacerFromMemory(0, oldToTemp[inf.index], (int)inf.curFileType, 0xFFFF, tempData[inf.index]));
            }
            byte[] firstMoveBytes;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    inst.file.Write(w, 0, reps.ToArray(), 0);
                    firstMoveBytes = ms.ToArray();
                }
            //File.WriteAllBytes("_bundletest1.unity3d", firstMoveBytes);
            //load our modifications (btw super hacky and slow)
            inst.stream = new MemoryStream(firstMoveBytes);
            inst.file   = new AssetsFile(new AssetsFileReader(inst.stream));
            inst.table  = new AssetsFileTable(inst.file);

            //move 2:
            //move the assets right after the existing ones
            nextId = idOffset;
            foreach (AssetFileInfoEx inf in inst.table.pAssetFileInfo)
            {
                if (InClassBlacklist(inf.curFileType))
                {
                    continue;
                }
                ulong repId = nextId++;

                tempToNew[inf.index] = repId;
            }
            foreach (AssetFileInfoEx inf in inst.table.pAssetFileInfo)
            {
                AssetTypeValueField baseField = am.GetATI(inst.file, inf).GetBaseField();

                List <ulong> depIds = new List <ulong>();
                depIds.Add(inf.index);

                RecurseTypeReplace(am, inst, baseField, depIds, 0, tempToNew);

                using (MemoryStream ms = new MemoryStream())
                    using (AssetsFileWriter w = new AssetsFileWriter(ms))
                    {
                        w.bigEndian = false;
                        baseField.Write(w);
                        newData[inf.index] = ms.ToArray();
                    }
            }
            reps.Clear();
            foreach (AssetFileInfoEx inf in inst.table.pAssetFileInfo)
            {
                reps.Add(new AssetsRemover(0, inf.index, (int)inf.curFileType));
                reps.Add(new AssetsReplacerFromMemory(0, tempToNew[inf.index], (int)inf.curFileType, 0xFFFF, newData[inf.index]));
            }
            byte[] secondMoveBytes;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    inst.file.Write(w, 0, reps.ToArray(), 0);
                    secondMoveBytes = ms.ToArray();
                }
            //File.WriteAllBytes("_bundletest2.unity3d", secondMoveBytes);
            inst.stream = new MemoryStream(secondMoveBytes);
            inst.file   = new AssetsFile(new AssetsFileReader(inst.stream));
            inst.table  = new AssetsFileTable(inst.file);
            Debug.Log("done");
        }
Пример #30
0
        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);
                }
            }
        }