private static MenuObj getMenu(string menuFileName)
        {
            //UnityEngine.Debug.Log("Fetching Menu " + menuFileName);

            MenuObj menu = new MenuObj();

            byte[] cd;
            using (AFileBase afileBase = GameUty.FileOpen(menuFileName, (AFileSystemBase)null))
            {
                if (afileBase != null && afileBase.IsValid())
                {
                    //UnityEngine.Debug.Log("Reading bytes");

                    cd = afileBase.ReadAll();

                    using (BinaryReader binaryReader = new BinaryReader((Stream) new MemoryStream(cd), Encoding.UTF8))
                    {
                        //Useless header info???
                        //UnityEngine.Debug.Log("Reading header");
                        menu.header.CM3D2_MENU = binaryReader.ReadString();
                        menu.header.temp1      = binaryReader.ReadInt32();
                        menu.header.temp2      = binaryReader.ReadString();
                        menu.header.temp3      = binaryReader.ReadString();
                        menu.header.temp4      = binaryReader.ReadString();
                        menu.header.temp5      = binaryReader.ReadString();
                        menu.header.temp6      = binaryReader.ReadInt32();

                        bool end = false;

                        //UnityEngine.Debug.Log("Reading commands");
                        //Blocks
                        do
                        {
                            MenuCommandObj command = new MenuCommandObj();
                            string         str4;
                            do
                            {
                                byte byt = binaryReader.ReadByte();
                                command.byt = byt;
                                int num2 = (int)byt;

                                str4 = string.Empty;
                                if (num2 != 0)
                                {
                                    for (int index = 0; index < num2; ++index)
                                    {
                                        string str = binaryReader.ReadString();
                                        command.nativeStrings.Add(str);
                                        str4 = str4 + "\"" + str + "\" ";
                                    }
                                }
                                else
                                {
                                    end = true;
                                }
                            }while (str4 == string.Empty && !end);

                            if (!end)
                            {
                                string   stringCom  = UTY.GetStringCom(str4);
                                string[] stringList = UTY.GetStringList(str4);

                                command.stringCom  = stringCom;
                                command.stringList = stringList;
                                menu.commands.Add(command);

                                if (stringCom.Equals("category"))
                                {
                                    //Get the category
                                    menu.category = stringList[1];
                                }
                            }
                        }while (!end);
                    }
                }
                else
                {
                    if (afileBase == null)
                    {
                        UnityEngine.Debug.Log("Split Hair Sliders: null AFileBase");
                    }
                    else
                    {
                        if (!afileBase.IsValid())
                        {
                            UnityEngine.Debug.Log("Split Hair Sliders: invalid AFileBase");
                        }
                    }
                }
            }

            return(menu);
        }
        public static IEnumerator createNewHairMenu(string hairMenuFileName, List <HairLengthTargetObj> listTarget, MenuObj menu, bool useExistingLengths)
        {
            //Delete Existing
            if (File.Exists(Path.Combine(newMenuPath, hairMenuFileName)))
            {
                UnityEngine.Debug.Log("Deleting old Menu");
                File.Delete(Path.Combine(newMenuPath, hairMenuFileName));
            }

            //Write new
            using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(Path.Combine(newMenuPath, "Ext_" + hairMenuFileName), FileMode.OpenOrCreate)))
            {
                List <string> sliderNames = new List <string>();

                //Write the header
                binaryWriter.Write(menu.header.CM3D2_MENU);
                binaryWriter.Write(menu.header.temp1);
                binaryWriter.Write(menu.header.temp2);
                binaryWriter.Write(menu.header.temp3);
                binaryWriter.Write(menu.header.temp4);
                binaryWriter.Write(menu.header.temp5);
                binaryWriter.Write(menu.header.temp6);

                //Write the commands
                for (int i = 0; i < menu.commands.Count; i++)
                {
                    MenuCommandObj command = menu.commands[i];

                    //Special case for the length sliders - need to adjust the data
                    if (command.stringCom.Equals("length"))
                    {
                        if (useExistingLengths)
                        {
                            //Write the byte indicating size of params
                            binaryWriter.Write(command.byt);

                            string sliderName = command.stringList[2];
                            while (sliderNames.Contains(sliderName))
                            {
                                sliderName += "_";
                            }
                            sliderNames.Add(sliderName);

                            //Write out commands
                            for (int j = 0; j < command.nativeStrings.Count; j++)
                            {
                                if (j != 2)
                                {
                                    //Normal Param
                                    binaryWriter.Write(command.nativeStrings[j]);
                                }
                                else
                                {
                                    //Slider
                                    binaryWriter.Write(sliderName);
                                }
                            }
                        }
                    }
                    else
                    {
                        //Write the byte indicating size of params
                        binaryWriter.Write(command.byt);

                        //Write out normal commands
                        for (int j = 0; j < command.nativeStrings.Count; j++)
                        {
                            binaryWriter.Write(command.nativeStrings[j]);
                        }
                    }
                }

                //Add the hair length options
                if (listTarget != null)
                {
                    for (int i = 0; i < listTarget.Count; i++)
                    {
                        binaryWriter.Write(Convert.ToByte(11));
                        binaryWriter.Write("length");
                        binaryWriter.Write(menu.category);
                        binaryWriter.Write("髪" + i);
                        binaryWriter.Write("fbrother");
                        binaryWriter.Write(listTarget[i].trTarget);
                        binaryWriter.Write(listTarget[i].vScaleMin.x.ToString("N1"));
                        binaryWriter.Write(listTarget[i].vScaleMin.y.ToString("N1"));
                        binaryWriter.Write(listTarget[i].vScaleMin.z.ToString("N1"));
                        binaryWriter.Write(listTarget[i].vScaleMax.x.ToString("N1"));
                        binaryWriter.Write(listTarget[i].vScaleMax.y.ToString("N1"));
                        binaryWriter.Write(listTarget[i].vScaleMax.z.ToString("N1"));
                    }
                }

                //Write the end
                binaryWriter.Write(Convert.ToByte('\u0000'));
            }

            //Add the new menu to the file system
            UnityEngine.Debug.Log("Adding new Menu to MOD file system: Ext_" + hairMenuFileName);
            GameUty.FileSystemMod.FileOpen(Path.Combine(newMenuPath, "Ext_" + hairMenuFileName));

            yield return(null);
        }
        private static IEnumerator exportAllHairMenus(string[] fileNames, bool isModList, int num)
        {
            run[num] = true;
            UnityEngine.Debug.Log("Exporting Menus Start" + fileNames.Length);
            Maid maid = GameMain.Instance.CharacterMgr.GetMaid(0);

            if (maid != null)
            {
                for (int i = 0; i < fileNames.Length; i++)
                {
                    string fileNameFullPath = fileNames[i];
                    bool   isMod            = isModList || fileNameFullPath.IndexOf("mod_") == 0;
                    if (((isMod && includeMods) || (!isMod && !onlyMods)) &&
                        (fileNameFullPath.Contains("hairf") || fileNameFullPath.Contains("hairr") || fileNameFullPath.Contains("hairs") || fileNameFullPath.Contains("hairt")))
                    {
                        string[] filePathSplit = fileNameFullPath.Split('\\');
                        string   fileName      = filePathSplit[filePathSplit.Length - 1];

                        if (!File.Exists(Path.Combine(newMenuPath, fileName)) || overwriteExisting)
                        {
                            MenuObj menu = getMenu(fileNameFullPath);

                            //Only process the file if it is a hair
                            if (new string[] { "hairf", "hairr", "hairs", "hairt" }.Contains(menu.category.ToLower()))
                            {
                                TBody.SlotID slotID = TBody.SlotID.hairAho;
                                MPN          mpnID  = MPN.hairaho;
                                switch (menu.category.ToLower())
                                {
                                case "hairf":
                                    slotID = TBody.SlotID.hairF;
                                    mpnID  = MPN.hairf;
                                    break;

                                case "hairr":
                                    slotID = TBody.SlotID.hairR;
                                    mpnID  = MPN.hairr;
                                    break;

                                case "hairs":
                                    slotID = TBody.SlotID.hairS;
                                    mpnID  = MPN.hairs;
                                    break;

                                case "hairt":
                                    slotID = TBody.SlotID.hairT;
                                    mpnID  = MPN.hairt;
                                    break;
                                }

                                //Cache the current selection
                                string oldFileName = maid.GetProp(mpnID).strFileName;

                                //Set the hair to the file
                                Menu.ProcScript(maid, fileNameFullPath, false);

                                //Export the hair
                                if (everyBone && maid.body0.goSlot[(int)slotID] != null && maid.body0.goSlot[(int)slotID].morph != null && maid.body0.goSlot[(int)slotID].morph.BoneNames != null && maid.body0.goSlot[(int)slotID].morph.BoneNames.Count > 0)
                                {
                                    UnityEngine.Debug.Log("Creating Menu for all bones");
                                    List <HairLengthTargetObj> listTarget = new List <HairLengthTargetObj>();
                                    for (int j = 0; j < maid.body0.goSlot[(int)slotID].morph.BoneNames.Count; j++)
                                    {
                                        string boneName = maid.body0.goSlot[(int)slotID].morph.BoneNames[j];
                                        if (boneName.Contains("yure"))
                                        {
                                            HairLengthTargetObj target = new HairLengthTargetObj();
                                            target.trTarget  = boneName;
                                            target.vScaleMin = new Vector3(0.3f, 1f, 1f);
                                            target.vScaleMax = new Vector3(2f, 1f, 1f);
                                            listTarget.Add(target);
                                        }
                                    }

                                    this1.StartCoroutine(createNewHairMenu(fileName, listTarget, menu, false));
                                }
                                else
                                {
                                    if (slotID != TBody.SlotID.hairAho &&
                                        maid.body0.goSlot[(int)slotID] != null &&
                                        maid.body0.goSlot[(int)slotID].m_HairLengthCtrl != null && maid.body0.goSlot[(int)slotID].m_HairLengthCtrl.HairLengthGroupList != null &&
                                        maid.body0.goSlot[(int)slotID].m_HairLengthCtrl.HairLengthGroupList.ContainsKey("AutoConv") &&
                                        maid.body0.goSlot[(int)slotID].m_HairLengthCtrl.HairLengthGroupList["AutoConv"].listTarget != null &&
                                        maid.body0.goSlot[(int)slotID].m_HairLengthCtrl.HairLengthGroupList["AutoConv"].listTarget.Count != 0)
                                    {
                                        //CM
                                        UnityEngine.Debug.Log("Createing Menu for AutoConv");
                                        List <HairLengthTargetObj> listTarget = new List <HairLengthTargetObj>();
                                        for (int j = 0; j < maid.body0.goSlot[(int)slotID].m_HairLengthCtrl.HairLengthGroupList["AutoConv"].listTarget.Count; j++)
                                        {
                                            TBodySkin.HairLengthCtrl.HairLengthTarget orig = maid.body0.goSlot[(int)slotID].m_HairLengthCtrl.HairLengthGroupList["AutoConv"].listTarget[j];
                                            HairLengthTargetObj target = new HairLengthTargetObj();
                                            target.trTarget  = orig.trTarget.name;
                                            target.vScaleMin = orig.vScaleMin;
                                            target.vScaleMax = orig.vScaleMax;
                                            listTarget.Add(target);
                                        }
                                        this1.StartCoroutine(createNewHairMenu(fileName, listTarget, menu, true));
                                    }
                                    else
                                    {
                                        //COM
                                        //UnityEngine.Debug.Log("Creating Menu for standard");
                                        this1.StartCoroutine(createNewHairMenu(fileName, null, menu, true));
                                    }
                                }

                                //Revert to the old selection
                                Menu.ProcScript(maid, oldFileName, false);
                            }
                        }
                    }
                }
            }
            UnityEngine.Debug.Log("Exporting Menus End" + fileNames.Length);
            run[num] = false;
            yield return(null);
        }