public static void ReadMenuItemDataFromNative(SceneEdit.SMenuItem mi, int menuDataBaseIndex, out string iconStr)
        {
            MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;

            menuDataBase.SetIndex(menuDataBaseIndex);
            mi.m_strMenuName           = menuDataBase.GetMenuName();
            mi.m_strInfo               = menuDataBase.GetItemInfoText();
            mi.m_mpn                   = (MPN)menuDataBase.GetCategoryMpn();
            mi.m_strCateName           = menuDataBase.GetCategoryMpnText();
            mi.m_eColorSetMPN          = (MPN)menuDataBase.GetColorSetMpn();
            mi.m_strMenuNameInColorSet = menuDataBase.GetMenuNameInColorSet();
            mi.m_pcMultiColorID        = (MaidParts.PARTS_COLOR)menuDataBase.GetMultiColorId();
            mi.m_boDelOnly             = menuDataBase.GetBoDelOnly();
            mi.m_fPriority             = menuDataBase.GetPriority();
            mi.m_bMan                  = menuDataBase.GetIsMan();
            mi.m_bOld                  = (menuDataBase.GetVersion() < 2000);
            iconStr = menuDataBase.GetIconS();

            if (Main.UseVanillaCache.Value)
            {
                MenuStub newStub = new MenuStub()
                {
                    Name         = mi.m_strMenuName,
                    Description  = mi.m_strInfo,
                    Category     = mi.m_mpn.ToString(),
                    ColorSetMPN  = mi.m_eColorSetMPN.ToString(),
                    ColorSetMenu = mi.m_strMenuNameInColorSet,
                    MultiColorID = mi.m_pcMultiColorID.ToString(),
                    DelMenu      = mi.m_boDelOnly,
                    Priority     = mi.m_fPriority,
                    ManMenu      = mi.m_bMan,
                    LegacyMenu   = mi.m_bOld,
                    Icon         = iconStr,
                    DateModified = File.GetLastWriteTimeUtc(BepInEx.Paths.GameRootPath + "\\GameData\\paths.dat")
                };

                MenuCache[mi.m_strMenuFileName] = newStub;
            }
        }
        public static void test2()
        {
            Main.logger.LogError("Coroutine was successfully engaged!");

            while (GameMain.Instance.CharacterMgr.IsBusy())
            {
                Thread.Sleep(20);
                //yield return null;
            }
            MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;

            while (!menuDataBase.JobFinished())
            {
                Thread.Sleep(20);
                //yield return null;
            }

            test.Start();

            Main.logger.LogError("Reaching first access method.");

            AccessTools.Method(typeof(SceneEdit), "InitCategoryList").Invoke(@this, null);
            //@this.InitCategoryList();
            int fileCount = menuDataBase.GetDataSize();
            List <SceneEdit.SMenuItem> menuList = new List <SceneEdit.SMenuItem>();

            @this.m_menuRidDic = new Dictionary <int, SceneEdit.SMenuItem>(fileCount);
            Dictionary <int, List <int> > menuGroupMemberDic = new Dictionary <int, List <int> >();
            float time = Time.realtimeSinceStartup;

            for (int i = 0; i < fileCount; i++)
            {
                menuDataBase.SetIndex(i);
                string fileName        = menuDataBase.GetMenuFileName();
                string parent_filename = menuDataBase.GetParentMenuFileName();
                if (GameMain.Instance.CharacterMgr.status.IsHavePartsItem(fileName))
                {
                    SceneEdit.SMenuItem mi = new SceneEdit.SMenuItem();
                    mi.m_strMenuFileName = fileName;
                    mi.m_nMenuFileRID    = fileName.GetHashCode();
                    try
                    {
                        SceneEdit.ReadMenuItemDataFromNative(mi, i);
                    }
                    catch (Exception ex)
                    {
                        Main.logger.LogError(string.Concat(new string[]
                        {
                            "ReadMenuItemDataFromNative 例外/",
                            fileName,
                            "/",
                            ex.Message,
                            " StackTrace/",
                            ex.StackTrace
                        }));
                    }
                    if (!mi.m_bMan && @this.editItemTextureCache.IsRegister(mi.m_nMenuFileRID))
                    {
                        AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi });
                        //@this.AddMenuItemToList(mi);
                        menuList.Add(mi);
                        if ([email protected]_menuRidDic.ContainsKey(mi.m_nMenuFileRID))
                        {
                            @this.m_menuRidDic.Add(mi.m_nMenuFileRID, mi);
                        }
                        string parentMenuName = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi }) as string;
                        //string parentMenuName = SceneEdit.GetParentMenuFileName(mi);
                        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.m_listMember.Add(mi);
                        }
                        if (0.5f < Time.realtimeSinceStartup - time)
                        {
                            //yield return null;
                            time = Time.realtimeSinceStartup;
                        }
                    }
                }
            }

            //Parallel.ForEach(GameUty.ModOnlysMenuFiles, (strFileName) =>
            foreach (string strFileName in GameUty.ModOnlysMenuFiles)
            {
                Stopwatch test2 = new Stopwatch();

                test2.Start();
                Main.logger.LogError("Invoking GetMenuItemSetUP");

                SceneEdit.SMenuItem mi2 = new SceneEdit.SMenuItem();
                if (Main.GetMenuItemSetUP(mi2, strFileName, out string IconTex, false))
                {
                    Main.logger.LogError("Managed to setup menu item correctly. Adding to list to continue processing...");
                    ListOfContinues[mi2] = IconTex;
                }

                //Thread.Sleep(100);

                Main.logger.LogError("Finished GetMenuItemSetUP: " + test2.Elapsed);
            }            //);



            //@this2.StartCoroutine(SetupTexturesCoRoutine(menuList, menuGroupMemberDic));

            SavedmenuList           = menuList;
            SavedmenuGroupMemberDic = menuGroupMemberDic;
            Test2Done = true;
        }
Esempio n. 3
0
        private static IEnumerator InitMenuNative()
        {
            while (GameMain.Instance.CharacterMgr.IsBusy())
            {
                yield return(null);
            }
            MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;

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

            Stopwatch watch1 = new Stopwatch();

            Debug.Log("Vanilla menu file load has now begun.");

            watch1.Start();

            AccessTools.Method(typeof(SceneEdit), "InitCategoryList").Invoke(@this, null);
            int fileCount = menuDataBase.GetDataSize();
            List <SceneEdit.SMenuItem> menuList = new List <SceneEdit.SMenuItem>(fileCount);

            @this.m_menuRidDic = new Dictionary <int, SceneEdit.SMenuItem>(fileCount);
            Dictionary <int, List <int> > menuGroupMemberDic = new Dictionary <int, List <int> >();
            float time = Time.realtimeSinceStartup;

            for (int i = 0; i < fileCount; i++)
            {
                menuDataBase.SetIndex(i);
                string fileName        = menuDataBase.GetMenuFileName();
                string parent_filename = menuDataBase.GetParentMenuFileName();
                if (GameMain.Instance.CharacterMgr.status.IsHavePartsItem(fileName))
                {
                    SceneEdit.SMenuItem mi = new SceneEdit.SMenuItem();
                    mi.m_strMenuFileName = fileName;
                    mi.m_nMenuFileRID    = fileName.GetHashCode();
                    try
                    {
                        SceneEdit.ReadMenuItemDataFromNative(mi, i);
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError(string.Concat(new string[]
                        {
                            "ReadMenuItemDataFromNative 例外/",
                            fileName,
                            "/",
                            ex.Message,
                            " StackTrace/",
                            ex.StackTrace
                        }));
                    }
                    if (!mi.m_bMan && @this.editItemTextureCache.IsRegister(mi.m_nMenuFileRID))
                    {
                        AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi });
                        menuList.Add(mi);
                        if ([email protected]_menuRidDic.ContainsKey(mi.m_nMenuFileRID))
                        {
                            @this.m_menuRidDic.Add(mi.m_nMenuFileRID, mi);
                        }
                        string parentMenuName = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@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.m_listMember.Add(mi);
                        }
                        if (0.5f < Time.realtimeSinceStartup - time)
                        {
                            yield return(null);

                            time = Time.realtimeSinceStartup;
                        }
                    }
                }
            }
            foreach (string strFileName in GameUty.ModOnlysMenuFiles)
            {
                SceneEdit.SMenuItem mi2 = new SceneEdit.SMenuItem();
                if (SceneEdit.GetMenuItemSetUP(mi2, strFileName, false))
                {
                    if (!mi2.m_bMan && !(mi2.m_texIconRef == null))
                    {
                        AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi2 });
                        menuList.Add(mi2);
                        if ([email protected]_menuRidDic.ContainsKey(mi2.m_nMenuFileRID))
                        {
                            @this.m_menuRidDic.Add(mi2.m_nMenuFileRID, mi2);
                        }
                        string parentMenuName2 = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi2 }) as string;
                        if (!string.IsNullOrEmpty(parentMenuName2))
                        {
                            int hashCode2 = parentMenuName2.GetHashCode();
                            if (!menuGroupMemberDic.ContainsKey(hashCode2))
                            {
                                menuGroupMemberDic.Add(hashCode2, new List <int>());
                            }
                            menuGroupMemberDic[hashCode2].Add(mi2.m_strMenuFileName.ToLower().GetHashCode());
                        }
                        else if (mi2.m_strCateName.IndexOf("set_") != -1 && mi2.m_strMenuFileName.IndexOf("_del") == -1)
                        {
                            mi2.m_bGroupLeader = true;
                            mi2.m_listMember   = new List <SceneEdit.SMenuItem>();
                            mi2.m_listMember.Add(mi2);
                        }
                        if (0.5f < Time.realtimeSinceStartup - time)
                        {
                            yield return(null);

                            time = Time.realtimeSinceStartup;
                        }
                    }
                }
            }

            yield return(@this.StartCoroutine(AccessTools.Method(typeof(SceneEdit), "FixedInitMenu").Invoke(@this, new object[] { menuList, @this.m_menuRidDic, menuGroupMemberDic }) as IEnumerator));

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

            watch1.Stop();

            Debug.LogError($"Vanilla menu file load finished in: {watch1.Elapsed}");

            yield break;
        }
Esempio n. 4
0
        public static IEnumerator InitialBackgroundWorker()
        {
            Debug.LogError("Coroutine was successfully engaged!");

            while (GameMain.Instance.CharacterMgr.IsBusy())
            {
                yield return(null);
                //Thread.Sleep(20);
            }
            MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;

            while (!menuDataBase.JobFinished())
            {
                //Thread.Sleep(20);
                yield return(null);
            }

            test.Start();

            Debug.LogError("Reaching first access method.");

            AccessTools.Method(typeof(SceneEdit), "InitCategoryList").Invoke(@this, null);
            //@this.InitCategoryList();
            int fileCount = menuDataBase.GetDataSize();
            var menuList  = new HashSet <SceneEdit.SMenuItem>();

            @this.m_menuRidDic = new Dictionary <int, SceneEdit.SMenuItem>(fileCount);
            var   menuRidDicThreadSafe = @this.m_menuRidDic;
            var   menuGroupMemberDic   = new Dictionary <int, HashSet <int> >();
            float time = Time.realtimeSinceStartup;

            for (int i = 0; i < fileCount; i++)
            {
                menuDataBase.SetIndex(i);
                string fileName        = menuDataBase.GetMenuFileName();
                string parent_filename = menuDataBase.GetParentMenuFileName();
                if (GameMain.Instance.CharacterMgr.status.IsHavePartsItem(fileName))
                {
                    SceneEdit.SMenuItem mi = new SceneEdit.SMenuItem();
                    mi.m_strMenuFileName = fileName;
                    mi.m_nMenuFileRID    = fileName.GetHashCode();
                    try
                    {
                        SceneEdit.ReadMenuItemDataFromNative(mi, i);
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError(string.Concat(new string[]
                        {
                            "ReadMenuItemDataFromNative 例外/",
                            fileName,
                            "/",
                            ex.Message,
                            " StackTrace/",
                            ex.StackTrace
                        }));
                    }
                    if (!mi.m_bMan && @this.editItemTextureCache.IsRegister(mi.m_nMenuFileRID))
                    {
                        AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi });
                        //@this.AddMenuItemToList(mi);
                        menuList.Add(mi);
                        menuRidDicThreadSafe[mi.m_nMenuFileRID] = mi;
                        string parentMenuName = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi }) as string;
                        //string parentMenuName = SceneEdit.GetParentMenuFileName(mi);
                        if (!string.IsNullOrEmpty(parentMenuName))
                        {
                            int hashCode = parentMenuName.GetHashCode();
                            if (!menuGroupMemberDic.ContainsKey(hashCode))
                            {
                                menuGroupMemberDic[hashCode] = new HashSet <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.m_listMember.Add(mi);
                        }
                        if (0.5f < Time.realtimeSinceStartup - time)
                        {
                            //Thread.Sleep(20);
                            yield return(null);

                            time = Time.realtimeSinceStartup;
                        }
                    }
                }
            }

            Debug.LogError($"Reaching the load ForEach at {test.Elapsed}.");

            Stopwatch test2 = new Stopwatch();

            foreach (string strFileName in GameUty.ModOnlysMenuFiles)
            {
                test2.Reset();
                test2.Start();

                SceneEdit.SMenuItem mi2 = new SceneEdit.SMenuItem();
                if (Main.GetMenuItemSetUP(mi2, strFileName, out string iconTex, false))
                {
                    ListOfIconLoads[mi2] = iconTex;
                }

                Debug.LogError("Finished One GetMenuItemSetUP in " + test2.Elapsed);
            }

            Debug.LogError($"We've finished SceneEdit.SMenuItem {test.Elapsed}");

            /*
             * SetupDone = true;
             *
             * while (IconLoadDone == false)
             * {
             *      yield return null;
             * }*/

            //foreach (KeyValuePair<SceneEdit.SMenuItem, string> keyPair in ListOfIconLoads)
            while (ListOfIconLoads.Count > 0)
            {
                var keyPair = ListOfIconLoads.FirstOrDefault();

                if (keyPair.Key == null || keyPair.Value == null)
                {
                    ListOfIconLoads.Remove(keyPair.Key);
                    continue;
                }

                //Debug.LogError("Icon Coroutine is loading an icon...");

                try
                {
                    keyPair.Key.m_texIcon = ImportCM.CreateTexture(keyPair.Value);
                }
                catch
                {
                    //ListOfIconLoads.Remove(keyPair.Key);
                    continue;
                }

                if (!(keyPair.Key.m_texIconRef == null))
                {
                    ListOfContinues.Add(keyPair.Key);
                }
                ListOfIconLoads.Remove(keyPair.Key);
            }

            Debug.LogError($"Now we've finished loading icons into each menu at {test.Elapsed}.");

            //Parallel.ForEach(ListOfContinues, (mi2) =>
            //foreach (SceneEdit.SMenuItem mi2 in ListOfContinues)
            while (ListOfContinues.Count > 0)
            {
                var mi2 = ListOfContinues.FirstOrDefault();

                if (mi2 == null)
                {
                    continue;
                }

                test2.Reset();

                if (!mi2.m_bMan)
                {
                    test2.Start();
                    //Debug.LogError("Invoking addmenuitemtolist");
                    AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi2 });
                    //@this.AddMenuItemToList(mi2);
                    //Debug.LogError($"Done invoking AddMenuItemToList at: {test2.Elapsed}");
                    menuRidDicThreadSafe[mi2.m_nMenuFileRID] = mi2;
                    //Debug.LogError("Invoking GetParentMenuFileName");
                    string parentMenuName2 = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi2 }) as string;
                    //string parentMenuName2 = SceneEdit.GetParentMenuFileName(mi2);
                    //Debug.LogError($"Done Invoking GetParentMenuFileName at: {test2.Elapsed}");
                    if (!string.IsNullOrEmpty(parentMenuName2))
                    {
                        int hashCode2 = parentMenuName2.GetHashCode();
                        if (!menuGroupMemberDic.ContainsKey(hashCode2))
                        {
                            menuGroupMemberDic[hashCode2] = new HashSet <int>();
                        }
                        menuGroupMemberDic[hashCode2].Add(mi2.m_strMenuFileName.ToLower().GetHashCode());
                    }
                    else if (mi2.m_strCateName.IndexOf("set_") != -1 && mi2.m_strMenuFileName.IndexOf("_del") == -1)
                    {
                        mi2.m_bGroupLeader = true;
                        mi2.m_listMember   = new List <SceneEdit.SMenuItem>();
                        mi2.m_listMember.Add(mi2);
                    }
                    if (0.5f < Time.realtimeSinceStartup - time)
                    {
                        yield return(null);

                        Debug.LogError($"Sleeping thread, 100ms...");
                        time = Time.realtimeSinceStartup;
                    }
                    Debug.LogError($"Finished processing one menu file in {test2.Elapsed}");
                }

                ListOfContinues.Remove(mi2);
            }            //);

            Debug.LogError($"Finished previous foreach at {test.Elapsed}\nInvoking coroutines...");

            @this.m_menuRidDic = menuRidDicThreadSafe;

            //var localmenuRidDic = @this.m_menuRidDic;

            //var tempMenuList = menuList.ToList();
            var tempGroupMemberDic = menuGroupMemberDic.ToDictionary(t => t.Key, t => t.Value.ToList());

            Debug.LogError($"Converted Dictionary back...");

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

            Debug.LogError($"Starting problematic coroutine.");

            //yield return @this.StartCoroutine(@this.FixedInitMenu(menuList, @this.m_menuRidDic, menuGroupMemberDic));
            yield return(@this.StartCoroutine(AccessTools.Method(typeof(SceneEdit), "FixedInitMenu").Invoke(@this, new object[] { menuList.ToList(), @this.m_menuRidDic, tempGroupMemberDic }) as IEnumerator));

            test.Stop();

            Debug.LogError($"Done, loaded {ListOfContinues.Count} menus in {test.Elapsed}");

            ListOfContinues.Clear();

            test.Reset();

            yield break;
        }        /*
        public static IEnumerator test2()
        {
            Stopwatch test = new Stopwatch();

            Debug.LogError("Coroutine was successfully engaged!");

            while (GameMain.Instance.CharacterMgr.IsBusy())
            {
                yield return(null);
            }
            MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;

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

            test.Start();

            Debug.LogError("Reaching first access method.");

            AccessTools.Method(typeof(SceneEdit), "InitCategoryList").Invoke(@this, null);
            //@this.InitCategoryList();
            int fileCount = menuDataBase.GetDataSize();
            ConcurrentQueue <SceneEdit.SMenuItem> menuList = new ConcurrentQueue <SceneEdit.SMenuItem>();

            @this.m_menuRidDic = new Dictionary <int, SceneEdit.SMenuItem>(fileCount);
            var menuRidDicThreadSafe = new ConcurrentDictionary <int, SceneEdit.SMenuItem>(@this.m_menuRidDic);
            ConcurrentDictionary <int, ConcurrentQueue <int> > menuGroupMemberDic = new ConcurrentDictionary <int, ConcurrentQueue <int> >();
            float time = Time.realtimeSinceStartup;

            for (int i = 0; i < fileCount; i++)
            {
                menuDataBase.SetIndex(i);
                string fileName        = menuDataBase.GetMenuFileName();
                string parent_filename = menuDataBase.GetParentMenuFileName();
                if (GameMain.Instance.CharacterMgr.status.IsHavePartsItem(fileName))
                {
                    SceneEdit.SMenuItem mi = new SceneEdit.SMenuItem();
                    mi.m_strMenuFileName = fileName;
                    mi.m_nMenuFileRID    = fileName.GetHashCode();
                    try
                    {
                        SceneEdit.ReadMenuItemDataFromNative(mi, i);
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError(string.Concat(new string[]
                        {
                            "ReadMenuItemDataFromNative 例外/",
                            fileName,
                            "/",
                            ex.Message,
                            " StackTrace/",
                            ex.StackTrace
                        }));
                    }
                    if (!mi.m_bMan && @this.editItemTextureCache.IsRegister(mi.m_nMenuFileRID))
                    {
                        AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi });
                        //@this.AddMenuItemToList(mi);
                        menuList.Enqueue(mi);
                        if (!menuRidDicThreadSafe.ContainsKey(mi.m_nMenuFileRID))
                        {
                            menuRidDicThreadSafe[mi.m_nMenuFileRID] = mi;
                        }
                        string parentMenuName = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi }) as string;
                        //string parentMenuName = SceneEdit.GetParentMenuFileName(mi);
                        if (!string.IsNullOrEmpty(parentMenuName))
                        {
                            int hashCode = parentMenuName.GetHashCode();
                            if (!menuGroupMemberDic.ContainsKey(hashCode))
                            {
                                menuGroupMemberDic[hashCode] = new ConcurrentQueue <int>();
                            }
                            menuGroupMemberDic[hashCode].Enqueue(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.m_listMember.Add(mi);
                        }
                        if (0.5f < Time.realtimeSinceStartup - time)
                        {
                            yield return(null);

                            time = Time.realtimeSinceStartup;
                        }
                    }
                }
            }

            Debug.LogError($"Reaching the load ForEach at {test.Elapsed}.");

            //Parallel.ForEach(GameUty.ModOnlysMenuFiles, (strFileName) =>

            Task.Factory.StartNew(new Action(() =>
            {
                foreach (string strFileName in GameUty.ModOnlysMenuFiles)
                {
                    Stopwatch test2 = new Stopwatch();

                    test2.Start();
                    //Debug.LogError("Invoking GetMenuItemSetUP");

                    SceneEdit.SMenuItem mi2 = new SceneEdit.SMenuItem();
                    if (Main.GetMenuItemSetUP(mi2, strFileName, out string IconTex, false))
                    {
                        //Debug.LogError("Managed to setup menu item correctly. Adding to list to continue processing...");
                        ListOfIconLoads[mi2] = IconTex;
                    }

                    //Thread.Sleep(100);

                    Debug.LogError("Finished One GetMenuItemSetUP in " + test2.Elapsed);
                }
            }            //);
                                             )).Wait();

            Debug.LogError($"We've finished SceneEdit.SMenuItem {test.Elapsed}");

            SetupDone = true;

            while (IconLoadDone != true)
            {
                yield return(null);
            }

            Debug.LogError($"Now we've finished loading icons into each menu at {test.Elapsed}.");

            //Parallel.ForEach(ListOfContinues, (mi2) =>
            foreach (SceneEdit.SMenuItem mi2 in ListOfContinues)
            {
                Stopwatch test2 = new Stopwatch();

                if (!mi2.m_bMan && !(mi2.m_texIconRef == null))
                {
                    test2.Start();
                    //Debug.LogError("Invoking addmenuitemtolist");
                    AccessTools.Method(typeof(SceneEdit), "AddMenuItemToList").Invoke(@this, new object[] { mi2 });
                    //@this.AddMenuItemToList(mi2);
                    //Debug.LogError($"Done invoking AddMenuItemToList at: {test2.Elapsed}");
                    if (!menuRidDicThreadSafe.ContainsKey(mi2.m_nMenuFileRID))
                    {
                        menuRidDicThreadSafe[mi2.m_nMenuFileRID] = mi2;
                    }
                    //Debug.LogError("Invoking GetParentMenuFileName");
                    string parentMenuName2 = AccessTools.Method(typeof(SceneEdit), "GetParentMenuFileName").Invoke(@this, new object[] { mi2 }) as string;
                    //string parentMenuName2 = SceneEdit.GetParentMenuFileName(mi2);
                    //Debug.LogError($"Done Invoking GetParentMenuFileName at: {test2.Elapsed}");
                    if (!string.IsNullOrEmpty(parentMenuName2))
                    {
                        int hashCode2 = parentMenuName2.GetHashCode();
                        if (!menuGroupMemberDic.ContainsKey(hashCode2))
                        {
                            menuGroupMemberDic[hashCode2] = new ConcurrentQueue <int>();
                        }
                        menuGroupMemberDic[hashCode2].Enqueue(mi2.m_strMenuFileName.ToLower().GetHashCode());
                    }
                    else if (mi2.m_strCateName.IndexOf("set_") != -1 && mi2.m_strMenuFileName.IndexOf("_del") == -1)
                    {
                        mi2.m_bGroupLeader = true;
                        mi2.m_listMember   = new List <SceneEdit.SMenuItem>();
                        mi2.m_listMember.Add(mi2);
                    }

                    /*
                     * if (true || 0.5f < Time.realtimeSinceStartup - time)
                     * {
                     *      //yield return null;
                     *      Debug.LogError($"Sleeping thread, 100ms...");
                     *      //Thread.Sleep(20);
                     *      time = Time.realtimeSinceStartup;
                     * }*/
                    Debug.LogError($"Finished processing one menu file in {test2.Elapsed}");
                }
            }            //);

            Debug.LogError($"Finished previous foreach at {test.Elapsed}\nInvoking coroutines...");

            SetupDone = true;

            //@this.m_menuRidDic = menuRidDicThreadSafe
            //.ToDictionary(t => t.Key, t => t.Value);

            Debug.LogError($"Converted Dictionary back...");

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

            Debug.LogError($"Starting problematic coroutine.");

            //yield return @this.StartCoroutine(@this.FixedInitMenu(menuList, @this.m_menuRidDic, menuGroupMemberDic));
            yield return(@this.StartCoroutine(AccessTools.Method(typeof(SceneEdit), "FixedInitMenu").Invoke(@this, new object[] { menuList, menuRidDicThreadSafe, menuGroupMemberDic }) as IEnumerator));

            test.Stop();

            Debug.LogError($"Done {test.Elapsed}");

            yield break;
        }
        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));
        }