Esempio n. 1
0
        private void Awake()
        {
            Debug.Log("Starting awake now...");

            @this2 = this;

            //We set our patcher so we can call it back and patch dynamically as needed.
            harmony = Harmony.CreateAndPatchAll(typeof(Main));

            MethodBase menuItemSetConstructor = typeof(SceneEdit)
                                                .GetNestedType("MenuItemSet", BindingFlags.NonPublic)
                                                .GetConstructor(
                new Type[]
                { typeof(GameObject),
                  typeof(SceneEdit.SMenuItem),
                  typeof(string),
                  typeof(bool) });

            MethodBase colorItemSetConstructor = typeof(SceneEdit).GetNestedType("ColorItemSet", BindingFlags.NonPublic).GetConstructor(new Type[] { typeof(GameObject), typeof(SceneEdit.SMenuItem) });

            harmony.PatchAll(typeof(QuickEdit));

            harmony.Patch(menuItemSetConstructor, new HarmonyMethod(typeof(QuickEdit), "MenuItemSet"));
            harmony.Patch(colorItemSetConstructor, new HarmonyMethod(typeof(QuickEdit), "MenuItemSet"));

            @this2.StartCoroutine(GSModMenuLoad.LoadCache());

            UseVanillaCache = Config.Bind("General", "Use Vanilla Cache", false, "This decides whether a vanilla cache is created, maintained and used on load. Kiss has it's own questionable implementation of a cache, but this cache is questionable in it's own right too.");

            ChangeModPriority = Config.Bind("General", "Add 10,000 to Mod Item Priority", false, "This option simply adds 10,000 priority to all mod items loaded. Handy if you don't want mod items mix and matching with vanilla stuff or appearing before the remove button.");

            @this2.StartCoroutine(VanillaMenuLoad.LoadCache());
        }
        private void Awake()
        {
            logger = this.Logger;

            Main.logger.LogDebug("Starting awake now...");

            @this2 = this;

            //We set our patcher so we can call it back and patch dynamically as needed.
            harmony = Harmony.CreateAndPatchAll(typeof(Main));

            MethodBase menuItemSetConstructor = typeof(SceneEdit)
                                                .GetNestedType("MenuItemSet", BindingFlags.NonPublic)
                                                .GetConstructor(
                new Type[]
                { typeof(GameObject),
                  typeof(SceneEdit.SMenuItem),
                  typeof(string),
                  typeof(bool) });

            MethodBase colorItemSetConstructor = typeof(SceneEdit).GetNestedType("ColorItemSet", BindingFlags.NonPublic).GetConstructor(new Type[] { typeof(GameObject), typeof(SceneEdit.SMenuItem) });

            harmony.PatchAll(typeof(QuickEdit));

            harmony.Patch(menuItemSetConstructor, new HarmonyMethod(typeof(QuickEdit), "MenuItemSet"));
            harmony.Patch(colorItemSetConstructor, new HarmonyMethod(typeof(QuickEdit), "MenuItemSet"));

            @this2.StartCoroutine(GSModMenuLoad.LoadCache());

            BreakInterval = Config.Bind("General", "Time Between Breaks in Seconds", 0.5f, "The break interval is the time between each break that the co-routine takes where it returns processing back to the main thread. After one frame, processing is given back to the co-routine. Higher values can help with low-end processing times but can cause instability if set too high. If after all of this you're still confused, leave it alone.");

            UseVanillaCache = Config.Bind("General", "Use Vanilla Cache", false, "This decides whether a vanilla cache is created, maintained and used on load. Kiss has it's own questionable implementation of a cache, but this cache is questionable in it's own right too.");

            ChangeModPriority = Config.Bind("General", "Add 10,000 to Mod Item Priority", false, "This option simply adds 10,000 priority to all mod items loaded. Handy if you don't want mod items mix and matching with vanilla stuff or appearing before the remove button.");

            @this2.StartCoroutine(VanillaMenuLoad.LoadCache());
        }
        private static IEnumerator InitMenuNative()
        {
            List <SceneEdit.SMenuItem>    menuList           = new List <SceneEdit.SMenuItem>();
            Dictionary <int, List <int> > menuGroupMemberDic = new Dictionary <int, List <int> >();

            @this.m_menuRidDic = new Dictionary <int, SceneEdit.SMenuItem>();

            //We set time so the coroutines to be called can coordinate themselves.
            time = Time.realtimeSinceStartup;

            AccessTools.Method(typeof(SceneEdit), "InitCategoryList").Invoke(Main.@this, null);

            Main.logger.LogInfo($"Files began loading at: {WatchOverall.Elapsed}");

            //These coroutines hold the loading code for each type of item related file.
            this2.StartCoroutine(GSModMenuLoad.GSMenuLoadStart(menuList, menuGroupMemberDic));
            this2.StartCoroutine(ModMenuLoad.ModMenuLoadStart(menuList, menuGroupMemberDic));
            this2.StartCoroutine(VanillaMenuLoad.VanillaMenuLoadStart(menuList, menuGroupMemberDic));

            //In a sorta async fashion, while the threads are no complete, the coroutine will pass on processing to someone else.
            while (ThreadsDone != 3)
            {
                yield return(null);
            }

            Main.logger.LogInfo($"All loaders finished at: {WatchOverall.Elapsed}.");
            //Setting threads back to 0 for next loads.
            ThreadsDone = 0;

            //Calls the final function to complete setting up menu items.
            yield return(@this.StartCoroutine(Main.FixedInitMenu(menuList, @this.m_menuRidDic, menuGroupMemberDic)));

            //Does something...
            yield return(@this.StartCoroutine(AccessTools.Method(typeof(SceneEdit), "CoLoadWait").Invoke(@this, null) as IEnumerator));

            Main.logger.LogInfo($"Loading completely done at: {WatchOverall.Elapsed}.");
        }
        public static IEnumerator VanillaMenuLoadStart(List <SceneEdit.SMenuItem> menuList, Dictionary <int, List <int> > menuGroupMemberDic)
        {
            Dictionary <SceneEdit.SMenuItem, int>    filesToLoadFromDatabase = new Dictionary <SceneEdit.SMenuItem, int>();
            Dictionary <SceneEdit.SMenuItem, string> filesToLoad             = new Dictionary <SceneEdit.SMenuItem, string>();

            //We wait until the manager is not busy because starting work while the manager is busy causes egregious bugs.
            while (GameMain.Instance.CharacterMgr.IsBusy())
            {
                yield return(null);
            }

            MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;

            Stopwatch waitOnKiss = new Stopwatch();

            waitOnKiss.Start();

            while (!menuDataBase.JobFinished())
            {
                yield return(null);
            }

            waitOnKiss.Stop();

            int fileCount = menuDataBase.GetDataSize();

            //This entire for loop is what loads in normal game menus. It's been left relatively untouched.
            for (int i = 0; i < fileCount; i++)
            {
                menuDataBase.SetIndex(i);
                string fileName = menuDataBase.GetMenuFileName();

                if (GameMain.Instance.CharacterMgr.status.IsHavePartsItem(fileName))
                {
                    SceneEdit.SMenuItem mi = new SceneEdit.SMenuItem
                    {
                        m_strMenuFileName = fileName,
                        m_nMenuFileRID    = fileName.GetHashCode()
                    };

                    filesToLoadFromDatabase[mi] = i;
                }
            }

            while (CacheLoadDone != true && Main.UseVanillaCache.Value)
            {
                yield return(null);
            }

            foreach (SceneEdit.SMenuItem mi in filesToLoadFromDatabase.Keys)
            {
                try
                {
                    string iconFileName = null;

                    if (MenuCache.ContainsKey(mi.m_strMenuFileName) && Main.UseVanillaCache.Value)
                    {
                        MenuStub tempStub = MenuCache[mi.m_strMenuFileName];

                        if (tempStub.DateModified == File.GetLastWriteTimeUtc(BepInEx.Paths.GameRootPath + "\\GameData\\paths.dat"))
                        {
                            mi.m_strMenuName           = tempStub.Name;
                            mi.m_strInfo               = tempStub.Description;
                            mi.m_mpn                   = (MPN)Enum.Parse(typeof(MPN), tempStub.Category);
                            mi.m_strCateName           = tempStub.Category;
                            mi.m_eColorSetMPN          = (MPN)Enum.Parse(typeof(MPN), tempStub.ColorSetMPN);
                            mi.m_strMenuNameInColorSet = tempStub.ColorSetMenu;
                            mi.m_pcMultiColorID        = (MaidParts.PARTS_COLOR)Enum.Parse(typeof(MaidParts.PARTS_COLOR), tempStub.MultiColorID);
                            mi.m_boDelOnly             = tempStub.DelMenu;
                            mi.m_fPriority             = tempStub.Priority;
                            mi.m_bMan                  = tempStub.ManMenu;
                            mi.m_bOld                  = tempStub.LegacyMenu;

                            iconFileName = tempStub.Icon;
                        }
                        else
                        {
                            Debug.LogWarning("GameData folder was changed! We'll be wiping the vanilla cache clean and rebuilding it now.");
                            MenuCache = new Dictionary <string, MenuStub>();
                        }
                    }

                    if (string.IsNullOrEmpty(mi.m_strMenuName))
                    {
                        //Debug.Log($"Loading {mi.m_strMenuFileName} from the database as it wasn't in cache...");
                        VanillaMenuLoad.ReadMenuItemDataFromNative(mi, filesToLoadFromDatabase[mi], out iconFileName);
                    }

                    filesToLoad[mi] = null;

                    if (!string.IsNullOrEmpty(iconFileName) && GameUty.FileSystem.IsExistentFile(iconFileName))
                    {
                        if (SceneEdit.Instance != null)
                        {
                            SceneEdit.Instance.editItemTextureCache.PreLoadRegister(mi.m_nMenuFileRID, iconFileName);
                        }
                        else
                        {
                            mi.m_texIcon = ImportCM.CreateTexture(iconFileName);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogError(string.Concat(new string[]
                    {
                        "ReadMenuItemDataFromNative 例外/",
                        mi.m_strMenuFileName,
                        "/",
                        ex.Message,
                        " StackTrace/",
                        ex.StackTrace
                    }));
                }
            }

            while (GSModMenuLoad.DictionaryBuilt == false)
            {
                yield return(null);
            }

            foreach (SceneEdit.SMenuItem mi in filesToLoad.Keys)
            {
                if (!mi.m_bMan && !GSModMenuLoad.FilesDictionary.ContainsKey(mi.m_strMenuFileName) && [email protected](mi.m_nMenuFileRID))
                {
                    AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(Main.@this, new object[] { mi });

                    menuList.Add(mi);

                    [email protected]_menuRidDic[mi.m_nMenuFileRID] = mi;
                    string parentMenuName = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(Main.@this, new object[] { mi }) as string;

                    if (!string.IsNullOrEmpty(parentMenuName))
                    {
                        int hashCode = parentMenuName.GetHashCode();
                        if (!menuGroupMemberDic.ContainsKey(hashCode))
                        {
                            menuGroupMemberDic.Add(hashCode, new List <int>());
                        }
                        menuGroupMemberDic[hashCode].Add(mi.m_strMenuFileName.ToLower().GetHashCode());
                    }
                    else if (mi.m_strCateName.IndexOf("set_") != -1 && mi.m_strMenuFileName.IndexOf("_del") == -1)
                    {
                        mi.m_bGroupLeader = true;
                        mi.m_listMember   = new List <SceneEdit.SMenuItem>
                        {
                            mi
                        };
                    }

                    if (0.5f < Time.realtimeSinceStartup - Main.time)
                    {
                        yield return(null);

                        Main.time = Time.realtimeSinceStartup;
                    }
                }
            }

            Main.ThreadsDone++;
            Debug.Log($"Vanilla menus finished loading at: {Main.WatchOverall.Elapsed}. We also spent {waitOnKiss.Elapsed} waiting for an unmodified database to finish loading...");

            [email protected](SaveCache(filesToLoad));
        }