コード例 #1
0
ファイル: Saver.cs プロジェクト: xueliuxing28/HKWorldEdit2
        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()
                };
            }
        }
コード例 #2
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);
            }
        }
コード例 #3
0
 public Dependency(string name, Stream file, AssetsFile af, AssetsFileTable aft)
 {
     this.name = name;
     this.file = file;
     this.af   = af;
     this.aft  = aft;
 }
コード例 #4
0
 public AssetsFileInstance(FileStream stream, string root)
 {
     path  = stream.Name;
     name  = Path.Combine(root, Path.GetFileName(path));
     file  = new AssetsFile(new AssetsFileReader(stream));
     table = new AssetsFileTable(file);
     dependencies.AddRange(
         Enumerable.Range(0, file.dependencies.dependencyCount)
         .Select(d => (AssetsFileInstance)null)
         );
 }
コード例 #5
0
 public AssetsFileInstance(Stream stream, string filePath, string root)
 {
     this.stream = stream;
     path        = Path.GetFullPath(filePath);
     name        = Path.Combine(root, Path.GetFileName(path));
     file        = new AssetsFile(new AssetsFileReader(stream));
     table       = new AssetsFileTable(file);
     dependencies.AddRange(
         Enumerable.Range(0, (int)file.dependencies.dependencyCount)
         .Select(d => (AssetsFileInstance)null)
         );
 }
コード例 #6
0
        public static ResourceAssets Parse()
        {
            ResourceAssets resourceAssets = new ResourceAssets();

            using (FileStream resStream = new FileStream(FindPath(), FileMode.Open))
                using (AssetsFileReader resReader = new AssetsFileReader(resStream))
                {
                    AssetsFile      resourcesFile      = new AssetsFile(resReader);
                    AssetsFileTable resourcesFileTable = new AssetsFileTable(resourcesFile);
                    foreach (AssetFileInfoEx afi in resourcesFileTable.pAssetFileInfo)
                    {
                        if (afi.curFileType == TEXT_CLASS_ID)
                        {
                            resourcesFile.reader.Position = afi.absoluteFilePos;
                            string assetName = resourcesFile.reader.ReadCountStringInt32();
                            if (assetName == "EntityDistributions")
                            {
                                resourcesFile.reader.Align();
                                resourceAssets.LootDistributionsJson = resourcesFile.reader.ReadCountStringInt32().Replace("\\n", "");
                            }
                        }
                        else if (afi.curFileType == MONOBEHAVIOUR_CLASS_ID)
                        {
                            resourcesFile.reader.Position  = afi.absoluteFilePos;
                            resourcesFile.reader.Position += 28;
                            string assetName = resourcesFile.reader.ReadCountStringInt32();
                            if (assetName == "WorldEntityData")
                            {
                                resourcesFile.reader.Align();
                                uint            size = resourcesFile.reader.ReadUInt32();
                                WorldEntityInfo wei;
                                for (int i = 0; i < size; i++)
                                {
                                    wei           = new WorldEntityInfo();
                                    wei.classId   = resourcesFile.reader.ReadCountStringInt32();
                                    wei.techType  = (TechType)resourcesFile.reader.ReadInt32();
                                    wei.slotType  = (EntitySlot.Type)resourcesFile.reader.ReadInt32();
                                    wei.prefabZUp = resourcesFile.reader.ReadBoolean();
                                    resourcesFile.reader.Align();
                                    wei.cellLevel  = (LargeWorldEntity.CellLevel)resourcesFile.reader.ReadInt32();
                                    wei.localScale = new UnityEngine.Vector3(resourcesFile.reader.ReadSingle(), resourcesFile.reader.ReadSingle(), resourcesFile.reader.ReadSingle());
                                    resourceAssets.WorldEntitiesByClassId.Add(wei.classId, wei);
                                }
                            }
                        }
                    }
                }

            Validate.IsTrue(resourceAssets.WorldEntitiesByClassId.Count > 0);
            Validate.IsTrue(resourceAssets.LootDistributionsJson != "");

            return(resourceAssets);
        }
コード例 #7
0
        public static List <AssetFileInfoEx> GetAssetsOfType(this AssetsFileTable table, int typeId)
        {
            List <AssetFileInfoEx> infos = new List <AssetFileInfoEx>();

            foreach (AssetFileInfoEx info in table.pAssetFileInfo)
            {
                if (info.curFileType == typeId)
                {
                    infos.Add(info);
                }
            }
            return(infos);
        }
コード例 #8
0
        private static string GetAssetNameFast(int fileId, long pathId, AssetsFileInstance inst)
        {
            if (pathId == 0)
            {
                return("");
            }

            AssetsFile      file  = null;
            AssetsFileTable table = null;

            if (fileId == 0)
            {
                file  = inst.file;
                table = inst.table;
            }
            else
            {
                AssetsFileInstance dep = inst.dependencies[fileId - 1];
                file  = dep.file;
                table = dep.table;
            }

            AssetFileInfoEx  inf    = table.getAssetInfo((ulong)pathId);
            AssetsFileReader reader = file.reader;

            if (allowed.Contains(inf.curFileType))
            {
                reader.Position = inf.absoluteFilePos;
                return(reader.ReadCountStringInt32());
            }
            if (inf.curFileType == 0x1)
            {
                reader.Position = inf.absoluteFilePos;
                int size = reader.ReadInt32();
                reader.Position += (ulong)(size * 12);
                reader.Position += 4;
                return(reader.ReadCountStringInt32());
            }
            else if (inf.curFileType == 0x72)
            {
                reader.Position  = inf.absoluteFilePos;
                reader.Position += 28;
                string name = reader.ReadCountStringInt32();
                if (name != "")
                {
                    return(name);
                }
            }
            return("");
        }
コード例 #9
0
        private static void ParseAssetManifest(string basePath, string fileName, ResourceAssets resourceAssets)
        {
            string path = Path.Combine(basePath, fileName).Replace("resources/", "Resources/");

            if (parsedManifests.Contains(path))
            {
                return;
            }
            Dictionary <int, string> relativeFileIdToPath = new Dictionary <int, string>();

            using (FileStream resStream = new FileStream(path, FileMode.Open, FileAccess.Read))
                using (AssetsFileReader reader = new AssetsFileReader(resStream))
                {
                    AssetsFile      file = new AssetsFile(reader);
                    AssetsFileTable resourcesFileTable = new AssetsFileTable(file);

                    parsedManifests.Add(path);


                    relativeFileIdToPath.Add(0, path);
                    int fileId = 1;
                    foreach (AssetsFileDependency dependency in file.dependencies.dependencies)
                    {
                        relativeFileIdToPath.Add(fileId++, Path.Combine(basePath, dependency.assetPath));
                    }

                    foreach (AssetsFileDependency dependency in file.dependencies.dependencies)
                    {
                        ParseAssetManifest(basePath, dependency.assetPath, resourceAssets);
                    }

                    foreach (AssetFileInfoEx assetFileInfo in resourcesFileTable.assetFileInfo)
                    {
                        reader.Position = assetFileInfo.absoluteFilePos;

                        AssetIdentifier identifier = new AssetIdentifier(path, assetFileInfo.index);

                        AssetParser assetParser;

                        if (assetParsersByClassId.TryGetValue(assetFileInfo.curFileType, out assetParser))
                        {
                            assetParser.Parse(identifier, reader, resourceAssets, relativeFileIdToPath);
                        }

                        assetIdentifierToClassId.Add(identifier, assetFileInfo.curFileType);
                    }
                }
        }
コード例 #10
0
        public void LoadAssets(Stream stream, string directory)
        {
            file         = stream;
            initialFile  = new AssetsFile(new AssetsFileReader(file));
            initialTable = new AssetsFileTable(initialFile);

            for (int i = 0; i < initialFile.dependencies.dependencyCount; i++)
            {
                Dependency      assetDependency;
                string          depName            = initialFile.dependencies.pDependencies[i].assetPath;
                FileStream      depFile            = new FileStream(directory + "\\" + depName.Replace("library/", "Resources\\"), FileMode.Open, FileAccess.Read, FileShare.Read);
                AssetsFile      depAssetsFile      = new AssetsFile(new AssetsFileReader(depFile));
                AssetsFileTable depAssetsFileTable = new AssetsFileTable(depAssetsFile);
                assetDependency = new Dependency(depName, depFile, depAssetsFile, depAssetsFileTable);
                dependencies.Add(assetDependency);
            }
        }
コード例 #11
0
ファイル: Program.cs プロジェクト: cnSchwarzer/Christine
        static void Main(string[] args)
        {
            byte[]          b               = File.ReadAllBytes(@"resources.assets");
            int             Reader          = AssetsFileReader.CreateAssetsReaderFromMemory(b, (uint)b.Length, true);
            AssetsFile      assetsFile      = new AssetsFile(AssetsFileReader.AssetsReaderFromMemory, Reader);
            AssetsFileTable assetsFileTable = new AssetsFileTable(assetsFile, true);

            for (int i = 0; i < assetsFileTable.AssetFileInfoCount; ++i)
            {
                AssetFileInfoEx Asset = assetsFileTable.GetAssetInfo((ulong)i);
                if (Asset == null)
                {
                    continue;
                }
                Console.WriteLine(Asset.NameString);
            }
        }
コード例 #12
0
        // All dependencies are stored in the root resource.assets file.  The order they
        // are listed corresponds to the fileId order.  We store this value, so we can
        // fetch the fileId of different assets to build AssetIdentifiers.
        private static void CalculateDependencyFileIds(string basePath, string fileName)
        {
            string path = Path.Combine(basePath, fileName);

            using (FileStream resStream = new FileStream(path, FileMode.Open, FileAccess.Read))
                using (AssetsFileReader reader = new AssetsFileReader(resStream))
                {
                    AssetsFile      file = new AssetsFile(reader);
                    AssetsFileTable resourcesFileTable = new AssetsFileTable(file);

                    int fileId = 1;

                    foreach (AssetsFileDependency dependency in file.dependencies.dependencies)
                    {
                        fileIdByResourcePath.Add(dependency.assetPath, fileId);
                        fileId++;
                    }
                }
        }
コード例 #13
0
        private static void ParseAssetManifest(string basePath, string fileName, int fileId, ResourceAssets resourceAssets)
        {
            fileName = fileName.Replace("resources/", "Resources/");

            if (parsedManifests.Contains(fileName))
            {
                return;
            }

            parsedManifests.Add(fileName);

            string path = Path.Combine(basePath, fileName);

            using (FileStream resStream = new FileStream(path, FileMode.Open, FileAccess.Read))
                using (AssetsFileReader reader = new AssetsFileReader(resStream))
                {
                    AssetsFile      file = new AssetsFile(reader);
                    AssetsFileTable resourcesFileTable = new AssetsFileTable(file);

                    foreach (AssetsFileDependency dependency in file.dependencies.dependencies)
                    {
                        int dependencyFileId = fileIdByResourcePath[dependency.assetPath];
                        ParseAssetManifest(basePath, dependency.assetPath, dependencyFileId, resourceAssets);
                    }

                    foreach (AssetFileInfoEx assetFileInfo in resourcesFileTable.assetFileInfo)
                    {
                        reader.Position = assetFileInfo.absoluteFilePos;

                        AssetIdentifier identifier = new AssetIdentifier(fileId, assetFileInfo.index);

                        AssetParser assetParser;

                        if (assetParsersByClassId.TryGetValue(assetFileInfo.curFileType, out assetParser))
                        {
                            assetParser.Parse(identifier, reader, resourceAssets);
                        }

                        assetIdentifierToClassId.Add(identifier, assetFileInfo.curFileType);
                    }
                }
        }
コード例 #14
0
        public List <AssetInfo> LoadAllFSMsFromFile(string path)
        {
            curFile = am.LoadAssetsFile(path, true);
            am.UpdateDependencies();

            am.LoadClassDatabaseFromPackage(curFile.file.typeTree.unityVersion);

            AssetsFile      file  = curFile.file;
            AssetsFileTable table = curFile.table;

            //we read manually with binaryreader to speed up reading, but sometimes the dataVersion field won't exist
            //so here we read the template manually to see whether it exists and back up a bit if it doesn't
            string           assemblyPath = Path.Combine(Path.GetDirectoryName(curFile.path), "Managed", "PlayMaker.dll");
            MonoDeserializer deserializer = new MonoDeserializer();

            deserializer.Read("PlayMakerFSM", MonoDeserializer.GetAssemblyWithDependencies(assemblyPath), file.header.format);
            bool hasDataField = deserializer.children[0].children[0].name == "dataVersion";

            return(GetFSMInfos(file, table, hasDataField));
        }
コード例 #15
0
ファイル: AssetHelper.cs プロジェクト: Snobi/AssetsTools.NET
 public static AssetFileInfoEx GetAssetInfo(this AssetsFileTable table, string name, uint typeId, bool caseSensitive = true)
 {
     if (!caseSensitive)
     {
         name = name.ToLower();
     }
     for (int i = 0; i < table.assetFileInfo.Length; i++)
     {
         AssetFileInfoEx info     = table.assetFileInfo[i];
         string          infoName = GetAssetNameFastNaive(table.file, info);
         if (!caseSensitive)
         {
             infoName = infoName.ToLower();
         }
         if (info.curFileType == typeId && infoName == name)
         {
             return(info);
         }
     }
     return(null);
 }
コード例 #16
0
        public static void GenerateLevelFiles(AssetsManager am, AssetsFileInstance inst)
        {
            EditorUtility.DisplayProgressBar("HKEdit", "Reading dependencies...", 0.5f);
            am.UpdateDependencies();

            //quicker asset id lookup
            for (int i = 0; i < am.files.Count; i++)
            {
                AssetsFileInstance afi = am.files[i];
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Generating QLTs...", (float)i / am.files.Count);
                }
                afi.table.GenerateQuickLookupTree();
            }

            ClassDatabaseFile cldb  = am.classFile;
            AssetsFileTable   table = inst.table;

            ReferenceCrawler crawler = new ReferenceCrawler(am);

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

            for (int i = 0; i < initialGameObjects.Count; i++)
            {
                if (i % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Recursing GameObject dependencies... (step 1/3)", (float)i / initialGameObjects.Count);
                }
                AssetFileInfoEx inf = initialGameObjects[i];
                crawler.AddReference(new AssetID(inst.path, (long)inf.index), false);
                crawler.FindReferences(inst, inf);
            }

            Dictionary <AssetID, AssetID> glblToLcl = crawler.references;

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

            Dictionary <string, AssetsFileInstance> fileToInst = am.files.ToDictionary(d => d.path);
            int j = 0;

            foreach (KeyValuePair <AssetID, AssetID> id in glblToLcl)
            {
                if (j % 100 == 0)
                {
                    EditorUtility.DisplayProgressBar("HKEdit", "Rewiring asset pointers... (step 2/3)", (float)j / glblToLcl.Count);
                }
                AssetsFileInstance depInst = fileToInst[id.Key.fileName];
                AssetFileInfoEx    depInf  = depInst.table.getAssetInfo((ulong)id.Key.pathId);

                ClassDatabaseType clType = AssetHelper.FindAssetClassByID(cldb, depInf.curFileType);
                string            clName = clType.name.GetString(cldb);
                if (!typeNames.Contains(clName))
                {
                    Type_0D type0d = C2T5.Cldb2TypeTree(cldb, clName);
                    type0d.classId = (int)depInf.curFileType;
                    types.Add(type0d);
                    typeNames.Add(clName);
                }

                crawler.ReplaceReferences(depInst, depInf, id.Value.pathId);
                j++;
            }

            EditorUtility.DisplayProgressBar("HKEdit", "Saving scene... (step 3/3)", 1f);

            types.Add(CreateEditDifferTypeTree(cldb));

            List <Type_0D> assetTypes = new List <Type_0D>()
            {
                C2T5.Cldb2TypeTree(cldb, 0x1c),
                C2T5.Cldb2TypeTree(cldb, 0x30),
                C2T5.Cldb2TypeTree(cldb, 0x53)
            };

            string origFileName = Path.GetFileNameWithoutExtension(inst.path);

            string sceneGuid = CreateMD5(origFileName);

            string ExportedScenes = Path.Combine("Assets", "ExportedScenes");
            //circumvents "!BeginsWithCaseInsensitive(file.pathName, AssetDatabase::kAssetsPathWithSlash)' assertion
            string ExportedScenesData = "ExportedScenesData";

            CreateMetaFile(sceneGuid, Path.Combine(ExportedScenes, origFileName + ".unity.meta"));

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

            byte[] sceneFileData;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    //unity editor won't load whole assets files by guid, so we have to use hardcoded paths
                    sceneFile.dependencies.pDependencies = new AssetsFileDependency[]
                    {
                        CreateDependency(ExportedScenesData + "/" + origFileName + "-data.assets"),
                        CreateScriptDependency(Constants.editDifferMsEditorScriptHash, Constants.editDifferLsEditorScriptHash)
                    };
                    sceneFile.dependencies.dependencyCount = 2;
                    sceneFile.preloadTable.items           = new AssetPPtr[]
                    {
                        new AssetPPtr(2, 11500000)
                    };
                    sceneFile.preloadTable.len = 1;
                    sceneFile.Write(w, 0, crawler.sceneReplacers.Concat(crawler.sceneMonoReplacers).ToArray(), 0);
                    sceneFileData = ms.ToArray();
                }
            byte[] assetFileData;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter w = new AssetsFileWriter(ms))
                {
                    w.bigEndian = false;
                    assetFile.Write(w, 0, crawler.assetReplacers.ToArray(), 0);
                    assetFileData = ms.ToArray();
                }

            File.WriteAllBytes(Path.Combine(ExportedScenes, origFileName + ".unity"), sceneFileData);
            File.WriteAllBytes(Path.Combine(ExportedScenesData, origFileName + "-data.assets"), assetFileData);
            File.WriteAllText(Path.Combine(ExportedScenesData, origFileName + ".metadata"), CreateHKWEMetaFile(am, inst));

            EditorUtility.ClearProgressBar();
        }
コード例 #17
0
ファイル: HKMenu.cs プロジェクト: xueliuxing28/HKWorldEdit
    public void LoadFSM(AssetsManager am, AssetInfo info, string folderPath)
    {
        //risky but would technically work
        AssetsFileInstance assetsFileInstance = am.files.First();
        AssetsFile         assetsFile         = assetsFileInstance.file;
        AssetsFileTable    assetsTable        = assetsFileInstance.table;

        AssetFileInfoEx afi = assetsTable.getAssetInfo(info.id);

        AssetTypeValueField baseField = Util.GetMonoBaseField(am, assetsFile, afi, folderPath);

        AssetTypeValueField fsm    = baseField.Get("fsm");
        AssetTypeValueField states = fsm.Get("states");

        dataVersion = fsm.Get("dataVersion").GetValue().AsInt();
        for (int i = 0; i < states.GetValue().AsArray().size; i++)
        {
            AssetTypeValueField state = states.Get((uint)i);

            string name = state.Get("name").GetValue().AsString();
            AssetTypeValueField rect = state.Get("position");
            float x      = Mathf.Floor(rect.Get("x").GetValue().AsFloat());
            float y      = Mathf.Floor(rect.Get("y").GetValue().AsFloat());
            float width  = Mathf.Floor(rect.Get("width").GetValue().AsFloat());
            float height = Mathf.Floor(rect.Get("height").GetValue().AsFloat());

            HandleElement rectElem = new HandleElement(HandleType.Rectangle, new Vector2(x, y), new Vector2(x + width, y + height), new Color(0.5f, 0.5f, 0.5f, 0.7f));
            elements.Add(rectElem);
            elements.Add(new HandleElement(HandleType.Label, new Vector2(x + (width / 2), y + 3), (int)width, name));

            AssetTypeValueField transitions   = state.Get("transitions");
            uint            transitionCount   = transitions.GetValue().AsArray().size;
            FsmTransition[] dotNetTransitions = new FsmTransition[transitionCount];
            for (int j = 0; j < transitionCount; j++)
            {
                dotNetTransitions[j] = new FsmTransition(transitions.Get((uint)j));
                string transitionName = dotNetTransitions[j].fsmEvent.name;
                elements.Add(new HandleElement(HandleType.Label, new Vector2(x + (width / 2), y + 3 + ((j + 1) * 16)), (int)width, transitionName));
            }

            Node node = new Node(name, new Rect(x, y, width, height), dotNetTransitions, rectElem);
            nodes.Add(node);

            //AssetTypeValueField transitions = state.Get("transitions");
            //uint transitionCount = transitions.GetValue().AsArray().size;
            //FsmTransition[] dotNetTransitions = new FsmTransition[transitionCount];
            //for (int j = 0; j < transitionCount; j++)
            //{
            //    dotNetTransitions[j] = new FsmTransition(transitions.Get((uint)j));
            //}
            //Node node = new Node(state, name, dotNetRect, dotNetTransitions);
            //nodes.Add(node);

            //node.grid.MouseLeftButtonDown += (object sender, MouseButtonEventArgs e) =>
            //{
            //    foreach (Node node2 in nodes)
            //    {
            //        node2.Selected = false;
            //    }
            //    node.Selected = true;
            //    SidebarData(node);
            //};
            //
            //graphCanvas.Children.Add(node.grid);
        }

        foreach (Node node in nodes)
        {
            if (node.transitions.Length > 0)
            {
                float yPos = 25;
                foreach (FsmTransition trans in node.transitions)
                {
                    Node endNode = nodes.Where(n => n.text == trans.toState).FirstOrDefault();
                    if (endNode != null)
                    {
                        bool    isLeft, dummy;
                        Vector2 start = ComputeLocation(node, endNode, yPos, out isLeft);
                        Vector2 end   = ComputeLocation(endNode, node, 10, out dummy);

                        Vector2 startMiddle, endMiddle;
                        float   dist = 70;
                        if (!isLeft)
                        {
                            startMiddle = new Vector2(start.x - dist, start.y);
                            endMiddle   = new Vector2(end.x + dist, end.y);
                        }
                        else
                        {
                            startMiddle = new Vector2(start.x + dist, start.y);
                            endMiddle   = new Vector2(end.x - dist, end.y);
                        }

                        elements.Insert(0, new HandleElement(HandleType.ArrowLine, start, end, startMiddle, endMiddle));
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine(node.text + " failed to connect to " + trans.toState);
                    }
                    yPos += 16;
                }
            }
        }
    }
コード例 #18
0
ファイル: Loader.cs プロジェクト: crmaxx/HKWorldLoad
        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());
                }
        }
コード例 #19
0
ファイル: HKSave.cs プロジェクト: xueliuxing28/HKWorldEdit
    public HKSave(string path, string diff)
    {
        LoadProgress("Load Scene", "Generating diff...", 0);
        am = new AssetsManager();
        assetsFileInstance = am.LoadAssetsFile(diff, false);
        assetsFile         = assetsFileInstance.file;
        assetsTable        = assetsFileInstance.table;
        am.LoadClassPackage(Path.Combine(Application.dataPath, "cldb.dat"));

        //FileStream stream = File.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
        //BinaryWriter writer = new BinaryWriter(stream);

        GameObject[]            sceneObjs      = GameObject.FindObjectsOfType <GameObject>();
        List <GameObjectAdd>    addList        = new List <GameObjectAdd>();
        List <GameObjectRemove> removeList     = new List <GameObjectRemove>();
        List <GameObjectChange> changeList     = new List <GameObjectChange>();
        List <GameObject>       newGameObjects = new List <GameObject>();
        List <GameObjectInfo>   newGoInfos     = new List <GameObjectInfo>();

        int i = 0;

        foreach (GameObject obj in sceneObjs)
        {
            LoadProgress("Load Scene", "Generating diff...", ((float)i / sceneObjs.Length) * 100f);
            EditDiffer differ = obj.GetComponent <EditDiffer>();
            if (differ != null)
            {
                if (!differ.newAsset)
                {
                    List <ComponentChangeOrAdd> changes = new List <ComponentChangeOrAdd>();
                    List <ComponentRemove>      removes = new List <ComponentRemove>();

                    ulong origPathId = differ.pathId;

                    CompareTransform(obj, origPathId, changes);

                    if (changes.Count > 0 || removes.Count > 0)
                    {
                        changeList.Add(new GameObjectChange()
                        {
                            pathId  = (long)origPathId,
                            changes = changes,
                            removes = removes
                        });
                    }
                }
                else
                {
                    //bool parentIsNew = false;
                    ulong parentPathId = ulong.MaxValue;
                    if (obj.transform.parent == null)
                    {
                        parentPathId = 0;
                    }
                    else
                    {
                        EditDiffer ed = obj.transform.parent.gameObject.GetComponent <EditDiffer>();
                        if (ed != null)
                        {
                            parentPathId = ed.pathId;
                            //if (ed.newAsset)
                            //{
                            //    parentIsNew = true;
                            //}
                        }
                        else
                        {
                            Debug.LogWarning("editdiff missing from " + obj.name + "'s parent");
                        }
                    }
                    bool newAsset = differ.origPathId == 0; //when a new asset was created *not* by cloning
                    addList.Add(new GameObjectAdd()
                    {
                        pathId   = differ.pathId,
                        parentId = parentPathId,
                        goNew    = newAsset
                    });
                    newGameObjects.Add(obj);
                    if (newAsset)
                    {
                        newGoInfos.Add(new GameObjectInfo(obj.name, differ.fileId, differ.origPathId, differ.pathId));
                    }
                }
            }
            i++;
        }
        LoadProgress("Create Diff Bundle", 0);
        CreateBundle(path, addList, removeList, changeList, newGameObjects, newGoInfos);
        EditorUtility.ClearProgressBar();
        EditorUtility.DisplayDialog("HKEdit", "Diff saved. Because of a Unity bug, please clear and reopen the map to continue working. All errors shown after save are normal.", "OK");
        //stream.Close();
    }
コード例 #20
0
ファイル: HKScene.cs プロジェクト: xueliuxing28/HKWorldEdit
    public HKScene(string path, AssetsManager ami = null)
    {
        EditorUtility.DisplayProgressBar("HKEdit", "Wiping scene...", 0);
        GameObject[] sceneRoots = SceneManager.GetActiveScene().GetRootGameObjects();
        foreach (GameObject rootObj in sceneRoots)
        {
            UnityEngine.Object.DestroyImmediate(rootObj);
        }
        EditorUtility.DisplayProgressBar("HKEdit", "Loading level file", 0);
        diffFile = path;
        string folderName = Path.GetDirectoryName(path);

        if (ami != null)
        {
            am = ami;
        }
        else
        {
            am = new AssetsManager();
        }

        if (am.classFile == null)
        {
            am.LoadClassPackage(Path.Combine(Application.dataPath, "cldb.dat"));
        }
        assetsFileInstance = am.LoadAssetsFile(path, false);
        assetsFile         = assetsFileInstance.file;
        assetsTable        = assetsFileInstance.table;

        EditorUtility.DisplayProgressBar("HKEdit", "Loading dependencies", 0);
        //i dunno what this does but it should fix dependency issues
        am.LoadAssetsFile(path, true);
        EditorUtility.DisplayProgressBar("HKEdit", "Loading dependencies refs", 50);
        am.UpdateDependencies();

        spriteLoader = new SpriteLoader();

        byte[] bundleData = Loader.CreateBundleFromLevel(am, assetsFileInstance);
        EditorUtility.DisplayProgressBar("HKEdit", "Loading bundle", 0);
        bundle = AssetBundle.LoadFromMemory(bundleData);
        EditorUtility.DisplayProgressBar("HKEdit", "Loading scene", 50);

        //File.WriteAllBytes("hkwedebug.unity3d", bundleData);

        //assetMap = GetAssetMap(am, bundle);

        string[] names = bundle.GetAllAssetNames();
        bundleAssets = bundle.LoadAllAssets();

        int index = 0;

        foreach (string fileName in names)
        {
            string withoutExt = fileName.Substring(0, fileName.Length - 4);
            string assetName  = withoutExt.Split('/')[0];
            long   pathId     = long.Parse(withoutExt.Split('/')[1]);
            if (assetName == "" && pathId == 0)
            {
                index++;
                continue;
            }
            assetMap.Add(new AssetID(assetName, pathId), index);
            index++;
        }

        EditDiffer.usedIds.Clear();
        int i = 0;

        foreach (AssetFileInfoEx info in assetsTable.pAssetFileInfo)
        {
            EditorUtility.DisplayProgressBar("HKEdit", "Creating GameObjects", i / (float)assetsTable.pAssetFileInfo.Length);
            if (info.curFileType == GAMEOBJECT)
            {
                RecurseGameObjects(info, true);
            }
            EditDiffer.usedIds.Add(info.index);
            i++;
        }

        EditorUtility.ClearProgressBar();
    }
コード例 #21
0
        private bool GetDataFiles(out string lootDistributions, out Dictionary <string, WorldEntityInfo> worldEntityData)
        {
            lootDistributions = "";
            worldEntityData   = new Dictionary <string, WorldEntityInfo>();
            string            resourcesPath     = "";
            Optional <string> steamPath         = SteamFinder.FindSteamGamePath(264710, "Subnautica");
            string            gameResourcesPath = "";

            if (!steamPath.IsEmpty())
            {
                gameResourcesPath = Path.Combine(steamPath.Get(), "Subnautica_Data/resources.assets");
            }
            if (File.Exists(gameResourcesPath))
            {
                resourcesPath = gameResourcesPath;
            }
            else if (File.Exists("../resources.assets"))
            {
                resourcesPath = Path.GetFullPath("../resources.assets");
            }
            else if (File.Exists("resources.assets"))
            {
                resourcesPath = Path.GetFullPath("resources.assets");
            }
            else
            {
                throw new FileNotFoundException("Make sure resources.assets is in current or parent directory and readable.");
            }

            using (FileStream resStream = new FileStream(resourcesPath, FileMode.Open))
                using (AssetsFileReader resReader = new AssetsFileReader(resStream))
                {
                    AssetsFile      resourcesFile      = new AssetsFile(resReader);
                    AssetsFileTable resourcesFileTable = new AssetsFileTable(resourcesFile);
                    foreach (AssetFileInfoEx afi in resourcesFileTable.pAssetFileInfo)
                    {
                        if (afi.curFileType == TEXT_CLASS_ID)
                        {
                            resourcesFile.reader.Position = afi.absoluteFilePos;
                            string assetName = resourcesFile.reader.ReadCountStringInt32();
                            if (assetName == "EntityDistributions")
                            {
                                resourcesFile.reader.Align();
                                lootDistributions = resourcesFile.reader.ReadCountStringInt32().Replace("\\n", "");
                            }
                        }
                        else if (afi.curFileType == MONOBEHAVIOUR_CLASS_ID)
                        {
                            resourcesFile.reader.Position  = afi.absoluteFilePos;
                            resourcesFile.reader.Position += 28;
                            string assetName = resourcesFile.reader.ReadCountStringInt32();
                            if (assetName == "WorldEntityData")
                            {
                                resourcesFile.reader.Align();
                                uint            size = resourcesFile.reader.ReadUInt32();
                                WorldEntityInfo wei;
                                for (int i = 0; i < size; i++)
                                {
                                    wei           = new WorldEntityInfo();
                                    wei.classId   = resourcesFile.reader.ReadCountStringInt32();
                                    wei.techType  = (TechType)resourcesFile.reader.ReadInt32();
                                    wei.slotType  = (EntitySlot.Type)resourcesFile.reader.ReadInt32();
                                    wei.prefabZUp = resourcesFile.reader.ReadBoolean();
                                    resourcesFile.reader.Align();
                                    wei.cellLevel  = (LargeWorldEntity.CellLevel)resourcesFile.reader.ReadInt32();
                                    wei.localScale = new UnityEngine.Vector3(resourcesFile.reader.ReadSingle(), resourcesFile.reader.ReadSingle(), resourcesFile.reader.ReadSingle());
                                    worldEntityData.Add(wei.classId, wei);
                                }
                            }
                        }
                    }
                }
            return(true);
        }
コード例 #22
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);
        }
コード例 #23
0
ファイル: Loader.cs プロジェクト: xueliuxing28/HKWorldEdit
        public static byte[] CreateBundleFromLevel(AssetsManager am, AssetsFileInstance inst)
        {
            AssetsFile      file  = inst.file;
            AssetsFileTable table = inst.table;

            string folderName = Path.GetDirectoryName(inst.path);

            ulong pathId = 2;
            List <AssetsReplacer>       assets   = new List <AssetsReplacer>();
            Dictionary <AssetID, ulong> assetMap = new Dictionary <AssetID, ulong>();

            //get all sprites

            int i = 0;
            List <AssetFileInfoEx> infos     = table.GetAssetsOfType(0xD4);
            List <ulong>           spriteIds = new List <ulong>();

            foreach (AssetFileInfoEx info in infos)
            {
                //honestly this is a really trash way to do this
                //we have a better scene exporter but it would
                //take some work to fix it up and block certain assets

                EditorUtility.DisplayProgressBar("HKEdit", "Creating scene bundle", i / (float)infos.Count);

                AssetTypeValueField baseField = GetBaseField(am, file, info);

                AssetTypeValueField m_Sprite   = baseField.Get("m_Sprite");
                AssetFileInfoEx     spriteInfo = am.GetExtAsset(inst, m_Sprite, true).info;
                AssetsFileInstance  spriteInst;
                if (m_Sprite.Get("m_FileID").GetValue().AsInt() == 0)
                {
                    spriteInst = inst;
                }
                else
                {
                    spriteInst = inst.dependencies[m_Sprite.Get("m_FileID").GetValue().AsInt() - 1];
                }

                int  spriteFileId = m_Sprite.Get("m_FileID").GetValue().AsInt();
                long spritePathId = m_Sprite.Get("m_PathID").GetValue().AsInt64();
                if (assetMap.ContainsKey(new AssetID(Path.GetFileName(spriteInst.path), spritePathId)) || (spriteFileId == 0 && spritePathId == 0))
                {
                    i++;
                    continue;
                }

                AssetTypeValueField spriteBaseField = GetBaseField(am, spriteInst.file, spriteInfo);

                AssetTypeValueField m_RD = spriteBaseField.Get("m_RD");

                AssetTypeValueField texture      = m_RD.Get("texture");
                AssetTypeValueField alphaTexture = m_RD.Get("alphaTexture");

                AssetsFileInstance textureInst, alphaTextureInst;
                if (texture.Get("m_FileID").GetValue().AsInt() == 0)
                {
                    textureInst = spriteInst;
                }
                else
                {
                    textureInst = spriteInst.dependencies[texture.Get("m_FileID").GetValue().AsInt() - 1];
                }

                if (alphaTexture.Get("m_FileID").GetValue().AsInt() == 0)
                {
                    alphaTextureInst = spriteInst;
                }
                else
                {
                    alphaTextureInst = spriteInst.dependencies[alphaTexture.Get("m_FileID").GetValue().AsInt() - 1];
                }

                AssetTypeInstance textureAti      = am.GetExtAsset(spriteInst, texture, false).instance;
                AssetTypeInstance alphaTextureAti = am.GetExtAsset(spriteInst, alphaTexture, false).instance;

                ulong textureId = 0, alphaTextureId = 0;

                if (textureAti != null)
                {
                    AssetID id = new AssetID(Path.GetFileName(textureInst.path), texture.Get("m_PathID").GetValue().AsInt64());
                    if (!assetMap.ContainsKey(id))
                    {
                        textureId = pathId;
                        assetMap.Add(id, pathId);
                        assets.Add(TextureConverter.ConvertTexture(textureAti.GetBaseField(), pathId++, folderName));
                    }
                    else
                    {
                        textureId = assetMap[id];
                    }
                }
                if (alphaTextureAti != null)
                {
                    AssetID id = new AssetID(Path.GetFileName(alphaTextureInst.path), alphaTexture.Get("m_PathID").GetValue().AsInt64());
                    if (!assetMap.ContainsKey(id))
                    {
                        alphaTextureId = pathId;
                        assetMap.Add(id, pathId);
                        assets.Add(TextureConverter.ConvertTexture(alphaTextureAti.GetBaseField(), pathId++, folderName));
                    }
                    else
                    {
                        alphaTextureId = assetMap[id];
                    }
                }
                AssetTypeValueField m_Materials = baseField.Get("m_Materials").Get("Array");
                if (m_Materials.GetValue().AsArray().size > 0)
                {
                    AssetTypeValueField material = baseField.Get("m_Materials").Get("Array")[0];
                    AssetsFileInstance  materialInst;

                    int materialFileId = material.Get("m_FileID").GetValue().AsInt();

                    if (materialFileId == 0)
                    {
                        materialInst = inst;
                    }
                    else
                    {
                        materialInst = inst.dependencies[materialFileId - 1];
                    }

                    AssetID materialId = new AssetID(Path.GetFileName(materialInst.path), material.Get("m_PathID").GetValue().AsInt64());
                    if (!assetMap.ContainsKey(materialId))
                    {
                        AssetTypeValueField materialBaseField = am.GetExtAsset(inst, material).instance.GetBaseField();

                        AssetTypeValueField shader = materialBaseField.Get("m_Shader");

                        ulong shaderPathId = RecurseShaderDependencies(am, materialInst, pathId, shader, assets, assetMap, out pathId);

                        assetMap.Add(materialId, pathId);
                        assets.Add(MaterialConverter.ConvertMaterial(materialBaseField, pathId++, shaderPathId));
                    }
                }

                assetMap.Add(new AssetID(Path.GetFileName(spriteInst.path), spritePathId), pathId);
                spriteIds.Add(pathId);
                assets.Add(SpriteConverter.ConvertSprite(spriteBaseField, pathId++, textureId, alphaTextureId));
                i++;
            }

            assetMap.Add(new AssetID(0), pathId);
            assets.Add(HeaderInformation.CreateHeaderInformation(assetMap, pathId++));

            assets.Insert(0, BundleMeta.CreateBundleInformation(assetMap, spriteIds, 1));
            //assets.Add(BundleMeta.CreateBundleInformation(assetMap, 1));

            //todo: pull from original assets file, cldb is not always update to date
            List <Type_0D> types = new List <Type_0D>
            {
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x8E)), //AssetBundle
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x1C)), //Texture2D
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x31)), //TextAsset
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0xD4)), //SpriteRenderer
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0xD5)), //Sprite
                //FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x31)), //TextAsset
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x15)), //Material
                FixTypeTree(C2T5.Cldb2TypeTree(am.classFile, 0x30))  //Shader
            };

            const string ver = "2017.4.10f1";

            //const string ver = "2018.2.1f1";

            byte[]     blankData = BundleCreator.CreateBlankAssets(ver, types);
            AssetsFile blankFile = new AssetsFile(new AssetsFileReader(new MemoryStream(blankData)));

            byte[] data = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    blankFile.WriteFix(writer, 0, assets.ToArray(), 0);
                    data = ms.ToArray();
                }

            EditorUtility.DisplayProgressBar("HKEdit", "Creating bundle", 1);
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    BundleCreator.CreateBlankBundle(ver, data.Length).Write(writer, data);
                    return(ms.ToArray());
                }
        }
コード例 #24
0
    public static void ShowOpenFileDialog()
    {
        string path = EditorUtility.OpenFilePanel("Open level file", "", "");

        if (path.Length != 0)
        {
            HKSelect window = GetWindow <HKSelect>();
            window.am = new AssetsManager();
            AssetsFileInstance assetsFileInstance = window.am.LoadAssetsFile(path, true); //might work with false
            AssetsFile         assetsFile         = assetsFileInstance.file;
            AssetsFileTable    assetsTable        = assetsFileInstance.table;
            window.am.LoadClassPackage(Path.Combine(Application.dataPath, "cldb.dat"));

            window.folderPath = Path.GetDirectoryName(path);

            Stream assetStream = assetsFileInstance.stream;

            List <AssetInfo> assetInfos = new List <AssetInfo>();
            uint             fsmTypeId  = 0;
            foreach (AssetFileInfoEx info in assetsTable.pAssetFileInfo)
            {
                bool isMono = false;
                if (fsmTypeId == 0)
                {
                    ushort monoType = assetsFile.typeTree.pTypes_Unity5[info.curFileTypeOrIndex].scriptIndex;
                    if (monoType != 0xFFFF)
                    {
                        isMono = true;
                    }
                }
                else if (info.curFileType == fsmTypeId)
                {
                    isMono = true;
                }
                if (isMono)
                {
                    AssetTypeInstance monoAti   = window.am.GetATI(assetsFile, info);
                    AssetTypeInstance scriptAti = window.am.GetExtAsset(assetsFileInstance, monoAti.GetBaseField().Get("m_Script")).instance;
                    AssetTypeInstance goAti     = window.am.GetExtAsset(assetsFileInstance, 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 = new BinaryReader(assetStream);

                        long oldPos = assetStream.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));

            window.assetInfos = assetInfos;
            window.strings    = assetInfos.Select(i => i.name).ToArray();
        }
    }
コード例 #25
0
ファイル: Loader.cs プロジェクト: crmaxx/HKWorldEdit2
        public static byte[] CreateBundleFromLevel(AssetsManager am, AssetsFileInstance inst)
        {
            EditorUtility.DisplayProgressBar("HKEdit", "Reading Files...", 0f);
            am.UpdateDependencies();

            //quicker asset id lookup
            for (int i = 0; i < am.files.Count; i++)
            {
                AssetsFileInstance afi = am.files[i];
                EditorUtility.DisplayProgressBar("HKEdit", "Generating QLTs", (float)i / am.files.Count);
                afi.table.GenerateQuickLookupTree();
            }

            //setup
            AssetsFile      file  = inst.file;
            AssetsFileTable table = inst.table;

            string folderName = Path.GetDirectoryName(inst.path);

            List <AssetFileInfoEx> infos = table.pAssetFileInfo.ToList();

            List <string> fileNames           = new List <string>();
            Dictionary <AssetID, byte[]> deps = new Dictionary <AssetID, byte[]>();

            fileNames.Add(inst.name);

            //add own ids to list so we don't reread them
            foreach (AssetFileInfoEx info in infos)
            {
                if (info.curFileType != 1)
                {
                    continue;
                }
                AssetID id = new AssetID(inst.name, (long)info.index);
                deps.Add(id, null);
            }

            //look through each field in each asset in this file
            for (int i = 0; i < infos.Count; i++)
            {
                AssetFileInfoEx info = infos[i];
                if (info.curFileType != 1)
                {
                    continue;
                }
                EditorUtility.DisplayProgressBar("HKEdit", "Crawling PPtrs", (float)i / infos.Count);
                ReferenceCrawler.CrawlPPtrs(am, inst, info.index, fileNames, deps);
            }

            //add typetree data for dependencies
            long                  curId     = 1;
            List <Type_0D>        types     = new List <Type_0D>();
            List <string>         typeNames = new List <string>();
            List <AssetsReplacer> assets    = new List <AssetsReplacer>();
            Dictionary <string, AssetsFileInstance> insts = new Dictionary <string, AssetsFileInstance>();
            //asset id is our custom id that uses filename/pathid instead of fileid/pathid
            //asset id to path id
            Dictionary <AssetID, long> aidToPid = new Dictionary <AssetID, long>();
            //script id to mono id
            Dictionary <ScriptID, ushort> sidToMid = new Dictionary <ScriptID, ushort>();
            uint   lastId     = 0;
            ushort nextMonoId = 0;
            int    depCount   = 0;

            foreach (KeyValuePair <AssetID, byte[]> dep in deps)
            {
                EditorUtility.DisplayProgressBar("HKEdit", "Fixing Dependencies", (float)depCount / deps.Keys.Count);
                AssetID            id        = dep.Key;
                byte[]             assetData = dep.Value;
                AssetsFileInstance afInst    = null;
                if (insts.ContainsKey(id.fileName))
                {
                    afInst = insts[id.fileName];
                }
                else
                {
                    afInst = am.files.First(f => f.name == id.fileName);
                }
                if (afInst == null)
                {
                    continue;
                }
                AssetFileInfoEx inf = afInst.table.getAssetInfo((ulong)id.pathId);
                if (lastId != inf.curFileType)
                {
                    lastId = inf.curFileType;
                }

                ClassDatabaseType clType    = AssetHelper.FindAssetClassByID(am.classFile, inf.curFileType);
                string            clName    = clType.name.GetString(am.classFile);
                ushort            monoIndex = 0xFFFF;
                if (inf.curFileType != 0x72)
                {
                    if (!typeNames.Contains(clName))
                    {
                        Type_0D type0d = C2T5.Cldb2TypeTree(am.classFile, clName);
                        type0d.classId = (int)inf.curFileType; //?
                        types.Add(type0d);
                        typeNames.Add(clName);
                    }
                }
                else
                {
                    //unused for now
                    AssetTypeValueField baseField       = am.GetATI(afInst.file, inf).GetBaseField();
                    AssetTypeValueField m_Script        = baseField.Get("m_Script");
                    AssetTypeValueField scriptBaseField = am.GetExtAsset(afInst, m_Script).instance.GetBaseField();
                    string   m_ClassName    = scriptBaseField.Get("m_ClassName").GetValue().AsString();
                    string   m_Namespace    = scriptBaseField.Get("m_Namespace").GetValue().AsString();
                    string   m_AssemblyName = scriptBaseField.Get("m_AssemblyName").GetValue().AsString();
                    ScriptID sid            = new ScriptID(m_ClassName, m_Namespace, m_AssemblyName);
                    if (!sidToMid.ContainsKey(sid))
                    {
                        MonoClass mc = new MonoClass();
                        mc.Read(m_ClassName, Path.Combine(Path.Combine(Path.GetDirectoryName(inst.path), "Managed"), m_AssemblyName), afInst.file.header.format);

                        Type_0D type0d = C2T5.Cldb2TypeTree(am.classFile, clName);
                        TemplateFieldToType0D typeConverter = new TemplateFieldToType0D();

                        TypeField_0D[] monoFields = typeConverter.TemplateToTypeField(mc.children, type0d);

                        type0d.pStringTable      = typeConverter.stringTable;
                        type0d.stringTableLen    = (uint)type0d.pStringTable.Length;
                        type0d.scriptIndex       = nextMonoId;
                        type0d.pTypeFieldsEx     = type0d.pTypeFieldsEx.Concat(monoFields).ToArray();
                        type0d.typeFieldsExCount = (uint)type0d.pTypeFieldsEx.Length;

                        types.Add(type0d);
                        sidToMid.Add(sid, nextMonoId);
                        nextMonoId++;
                    }
                    monoIndex = sidToMid[sid];
                }
                aidToPid.Add(id, curId);
                AssetsReplacer rep = new AssetsReplacerFromMemory(0, (ulong)curId, (int)inf.curFileType, monoIndex, assetData);
                assets.Add(rep);
                curId++;
                depCount++;
            }

            byte[]     blankData = BundleCreator.CreateBlankAssets(ver, types);
            AssetsFile blankFile = new AssetsFile(new AssetsFileReader(new MemoryStream(blankData)));

            EditorUtility.DisplayProgressBar("HKEdit", "Writing first file...", 0f);
            byte[] data = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    blankFile.Write(writer, 0, assets.ToArray(), 0);
                    data = ms.ToArray();
                }

            //File.WriteAllBytes("debug.assets", data);

            MemoryStream  msn = new MemoryStream(data);
            AssetsManager amn = new AssetsManager();

            amn.classFile = am.classFile;
            AssetsFileInstance instn = amn.LoadAssetsFile(msn, ((FileStream)inst.file.reader.BaseStream).Name, false);

            instn.table.GenerateQuickLookupTree();

            deps.Clear();

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

            //gameobject id to mono id
            Dictionary <long, long> gidToMid = new Dictionary <long, long>();
            long nextBehaviourId             = (long)instn.table.pAssetFileInfo.Max(i => i.index) + 1;

            CreateEditDifferTypeTree(amn.classFile, instn);
            CreateSceneMetadataTypeTree(amn.classFile, instn);

            Random rand = new Random();

            rand.Next();
            foreach (KeyValuePair <AssetID, long> kvp in aidToPid)
            {
                AssetFileInfoEx inf = instn.table.getAssetInfo((ulong)kvp.Value);
                if (inf.curFileType == 0x01)
                {
                    gidToMid.Add(kvp.Value, nextBehaviourId);
                    assetsn.Add(CreateEditDifferMonoBehaviour(kvp.Value, kvp.Key, nextBehaviourId++, rand));
                }
            }

            for (int i = 0; i < instn.table.pAssetFileInfo.Length; i++)
            {
                AssetFileInfoEx inf = instn.table.pAssetFileInfo[i];
                EditorUtility.DisplayProgressBar("HKEdit", "Crawling PPtrs", (float)i / instn.table.pAssetFileInfo.Length);
                ReferenceCrawler.CrawlReplacePPtrs(amn, instn, inf.index, fileNames, deps, aidToPid, gidToMid);
            }

            //add monoscript assets to preload table to make unity happy
            List <AssetPPtr> preloadPptrs = new List <AssetPPtr>();

            preloadPptrs.Add(new AssetPPtr(1, 11500000));
            preloadPptrs.Add(new AssetPPtr(2, 11500000));
            foreach (KeyValuePair <AssetID, byte[]> dep in deps)
            {
                AssetID id        = dep.Key;
                byte[]  assetData = dep.Value;
                long    pid       = id.pathId;

                if (pid == 1)
                {
                    assetData = AddMetadataMonobehaviour(assetData, nextBehaviourId);
                }

                AssetFileInfoEx inf    = instn.table.getAssetInfo((ulong)pid);
                ushort          monoId = instn.file.typeTree.pTypes_Unity5[inf.curFileTypeOrIndex].scriptIndex;
                assetsn.Add(new AssetsReplacerFromMemory(0, (ulong)pid, (int)inf.curFileType, monoId, assetData));
                if (inf.curFileType == 0x73)
                {
                    preloadPptrs.Add(new AssetPPtr(0, (ulong)pid));
                }
            }

            List <long> usedIds = assetsn.Select(a => (long)a.GetPathID()).ToList();

            //will break if no gameobjects but I don't really care at this point
            assetsn.Add(CreateSceneMetadataMonoBehaviour(1, nextBehaviourId++, inst.name, usedIds));

            instn.file.preloadTable.items = preloadPptrs.ToArray();
            instn.file.preloadTable.len   = (uint)instn.file.preloadTable.items.Length;

            //add dependencies to monobehaviours
            List <AssetsFileDependency> fileDeps = new List <AssetsFileDependency>();

            AddScriptDependency(fileDeps, Constants.editDifferMsEditorScriptHash, Constants.editDifferLsEditorScriptHash);
            AddScriptDependency(fileDeps, Constants.sceneMetadataMsEditorScriptHash, Constants.sceneMetadataLsEditorScriptHash);

            instn.file.dependencies.pDependencies   = fileDeps.ToArray();
            instn.file.dependencies.dependencyCount = (uint)fileDeps.Count;

            EditorUtility.DisplayProgressBar("HKEdit", "Writing second file...", 0f);
            byte[] datan = null;
            using (MemoryStream ms = new MemoryStream())
                using (AssetsFileWriter writer = new AssetsFileWriter(ms))
                {
                    instn.file.Write(writer, 0, assetsn.ToArray(), 0);
                    datan = ms.ToArray();
                }

            EditorUtility.ClearProgressBar();

            return(datan);
        }
コード例 #26
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);
                }
            }
        }
コード例 #27
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));
            }
        }
コード例 #28
0
ファイル: Saver.cs プロジェクト: nesrak1/HKWorldEdit2
        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();
                }
        }