Jelajahi Sumber

Add parsing regular menu files

Thought it wasn't needed but remembered that COM3D2 does not add meu
files in the Mod folder to the MenuDataBase

Also changed ModItem.Priority to a float since menu file priority is not
stored as an int
habeebweeb 4 tahun lalu
induk
melakukan
b232ae61b3
1 mengubah file dengan 129 tambahan dan 39 penghapusan
  1. 129 39
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MenuFileUtility.cs

+ 129 - 39
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MenuFileUtility.cs

@@ -3,6 +3,7 @@ using System.Text;
 using System.IO;
 using System.IO;
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Linq;
 using UnityEngine;
 using UnityEngine;
 using UnityEngine.Rendering;
 using UnityEngine.Rendering;
 
 
@@ -10,12 +11,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
 {
     internal static class MenuFileUtility
     internal static class MenuFileUtility
     {
     {
-        private static readonly HashSet<string> accMpn = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
-        {
-            "accashi", "acchana", "acchat", "acchead", "accheso", "acckami", "acckamisub", "acckubi", "acckubiwa",
-            "accmimi", "accnip", "accsenaka", "accshippo", "accude", "accxxx", "bra", "glove", "headset", "megane",
-            "mizugi", "onepiece", "panz", "shoes", "skirt", "stkg", "wear",
+        public const string noCategory = "noCategory";
+        public static string[] MenuCategories = new[] {
+            noCategory, "acchat", "headset", "wear", "skirt", "onepiece", "mizugi", "bra", "panz", "stkg", "shoes",
+            "acckami", "megane", "acchead", "acchana", "accmimi", "glove", "acckubi", "acckubiwa", "acckamisub",
+            "accnip", "accude", "accheso", "accashi", "accsenaka", "accshippo", "accxxx"
         };
         };
+        private static readonly HashSet<string> accMpn = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
         private enum IMode
         private enum IMode
         {
         {
             None, ItemChange, TexChange
             None, ItemChange, TexChange
@@ -25,6 +27,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
 
         static MenuFileUtility()
         static MenuFileUtility()
         {
         {
+            accMpn.UnionWith(MenuCategories.Skip(1));
             GameMain.Instance.StartCoroutine(CheckMenuDataBaseJob());
             GameMain.Instance.StartCoroutine(CheckMenuDataBaseJob());
         }
         }
 
 
@@ -55,7 +58,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 string menuPropString = String.Empty;
                 string menuPropString = String.Empty;
                 string menuPropStringTemp = String.Empty;
                 string menuPropStringTemp = String.Empty;
                 // string tempString3 = String.Empty;
                 // string tempString3 = String.Empty;
-                string slotName = String.Empty;
+                // string slotName = String.Empty;
 
 
                 try
                 try
                 {
                 {
@@ -453,17 +456,17 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
 
         public static GameObject LoadModel(string menuFile)
         public static GameObject LoadModel(string menuFile)
         {
         {
-            return LoadModel(new ItemData { MenuFile = menuFile });
+            return LoadModel(new ModItem { MenuFile = menuFile });
         }
         }
 
 
-        public static GameObject LoadModel(ItemData menuItem)
+        public static GameObject LoadModel(ModItem modItem)
         {
         {
             byte[] menuBuffer = null;
             byte[] menuBuffer = null;
             byte[] modMenuBuffer = null;
             byte[] modMenuBuffer = null;
 
 
-            if (menuItem.IsOfficialMod)
+            if (modItem.IsOfficialMod)
             {
             {
-                using (FileStream fileStream = new FileStream(menuItem.MenuFile, FileMode.Open))
+                using (FileStream fileStream = new FileStream(modItem.MenuFile, FileMode.Open))
                 {
                 {
                     if (fileStream == null || fileStream.Length == 0)
                     if (fileStream == null || fileStream.Length == 0)
                     {
                     {
@@ -478,7 +481,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
                 }
             }
             }
 
 
-            string menu = menuItem.IsOfficialMod ? menuItem.BaseMenuFile : menuItem.MenuFile;
+            string menu = modItem.IsOfficialMod ? modItem.BaseMenuFile : modItem.MenuFile;
 
 
             using (AFileBase afileBase = GameUty.FileOpen(menu))
             using (AFileBase afileBase = GameUty.FileOpen(menu))
             {
             {
@@ -510,27 +513,28 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
                 }
                 catch
                 catch
                 {
                 {
-                    Debug.LogError($"Could not load mesh for '{menuItem.MenuFile}'");
+                    Debug.LogError($"Could not load mesh for '{modItem.MenuFile}'");
                 }
                 }
 
 
                 if (gameObject != null)
                 if (gameObject != null)
                 {
                 {
                     foreach (MaterialChange matChange in modelInfo.MaterialChanges)
                     foreach (MaterialChange matChange in modelInfo.MaterialChanges)
                     {
                     {
-                        foreach (Transform transform in gameObject.transform.GetComponentInChildren<Transform>(true))
+                        foreach (Transform transform in gameObject.transform.GetComponentsInChildren<Transform>(true))
                         {
                         {
                             Renderer renderer = transform.GetComponent<Renderer>();
                             Renderer renderer = transform.GetComponent<Renderer>();
                             if (renderer != null && renderer.material != null
                             if (renderer != null && renderer.material != null
                                 && matChange.MaterialIndex < renderer.materials.Length
                                 && matChange.MaterialIndex < renderer.materials.Length
                             )
                             )
                             {
                             {
-                                renderer.materials[matChange.MaterialIndex] =
-                                    ImportCM.LoadMaterial(matChange.MaterialFile, null);
+                                renderer.materials[matChange.MaterialIndex] = ImportCM.LoadMaterial(
+                                        matChange.MaterialFile, null, renderer.materials[matChange.MaterialIndex]
+                                    );
                             }
                             }
                         }
                         }
                     }
                     }
 
 
-                    if (menuItem.IsOfficialMod)
+                    if (modItem.IsOfficialMod)
                     {
                     {
                         ProcModScriptBin(modMenuBuffer, gameObject);
                         ProcModScriptBin(modMenuBuffer, gameObject);
                     }
                     }
@@ -540,27 +544,113 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
             }
             else
             else
             {
             {
-                Debug.LogWarning($"Could not parse menu file '{menuItem.MenuFile}'");
+                Debug.LogWarning($"Could not parse menu file '{modItem.MenuFile}'");
                 return null;
                 return null;
             }
             }
         }
         }
 
 
-        public static bool ParseNativeMenuFile(int menuIndex, ItemData menuItem)
+        public static bool ParseNativeMenuFile(int menuIndex, ModItem modItem)
         {
         {
             MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;
             MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;
             menuDataBase.SetIndex(menuIndex);
             menuDataBase.SetIndex(menuIndex);
             if (menuDataBase.GetBoDelOnly()) return false;
             if (menuDataBase.GetBoDelOnly()) return false;
-            menuItem.Category = menuDataBase.GetCategoryMpnText();
-            if (!accMpn.Contains(menuItem.Category)) return false;
-            menuItem.MenuFile = menuDataBase.GetMenuFileName().ToLower();
-            if (!validBG2MenuFile(menuItem.MenuFile)) return false;
-            menuItem.Name = menuDataBase.GetMenuName();
-            menuItem.IconFile = menuDataBase.GetIconS();
-            menuItem.Priority = (int)menuDataBase.GetPriority();
+            modItem.Category = menuDataBase.GetCategoryMpnText();
+            if (!accMpn.Contains(modItem.Category)) return false;
+            modItem.MenuFile = menuDataBase.GetMenuFileName().ToLower();
+            if (!validBG2MenuFile(modItem.MenuFile)) return false;
+            modItem.Name = menuDataBase.GetMenuName();
+            modItem.IconFile = menuDataBase.GetIconS();
+            modItem.Priority = menuDataBase.GetPriority();
             return true;
             return true;
         }
         }
 
 
-        public static bool ParseModMenuFile(string modMenuFile, ItemData menuItem)
+        public static bool ParseMenuFile(string menuFile, ModItem modItem)
+        {
+            if (!validBG2MenuFile(menuFile)) return false;
+
+            byte[] buf = null;
+            try
+            {
+                using (AFileBase afileBase = GameUty.FileOpen(menuFile))
+                {
+                    if (afileBase == null || !afileBase.IsValid() || afileBase.GetSize() == 0) return false;
+                    buf = afileBase.ReadAll();
+                }
+            }
+            catch
+            {
+                Debug.LogError($"Could not read menu file '{menuFile}'");
+                return false;
+            }
+
+            using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(buf), Encoding.UTF8))
+            {
+                string menuHeader = binaryReader.ReadString();
+                NDebug.Assert(
+                    menuHeader == "CM3D2_MENU", "ProcScriptBin 例外 : ヘッダーファイルが不正です。" + menuHeader
+                );
+                binaryReader.ReadInt32(); // file version
+                binaryReader.ReadString(); // txt path
+                modItem.Name = binaryReader.ReadString(); // name
+                modItem.Category = binaryReader.ReadString(); // category
+                if (!accMpn.Contains(modItem.Category)) return false;
+                binaryReader.ReadString(); // description
+                binaryReader.ReadInt32(); // idk (as long)
+
+                string menuPropString = String.Empty;
+                string menuPropStringTemp = String.Empty;
+
+                try
+                {
+                    while (true)
+                    {
+                        int numberOfProps = (int)binaryReader.ReadByte();
+                        menuPropStringTemp = menuPropString;
+                        menuPropString = String.Empty;
+
+                        if (numberOfProps != 0)
+                        {
+                            for (int i = 0; i < numberOfProps; i++)
+                            {
+                                menuPropString = $"{menuPropString}\"{binaryReader.ReadString()}\"";
+                            }
+
+                            if (menuPropString != string.Empty)
+                            {
+                                string header = UTY.GetStringCom(menuPropString);
+                                string[] menuProps = UTY.GetStringList(menuPropString);
+
+                                if (header == "end")
+                                {
+                                    break;
+                                }
+                                else if (header == "icons" || header == "icon")
+                                {
+                                    modItem.IconFile = menuProps[1];
+                                    break;
+                                }
+                                else if (header == "priority")
+                                {
+                                    modItem.Priority = float.Parse(menuProps[1]);
+                                }
+                            }
+                        }
+                        else
+                        {
+                            break;
+                        }
+                    }
+                }
+                catch (Exception e)
+                {
+                    Debug.LogWarning($"Could not parse menu file '{menuFile}' because {e.Message}");
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public static bool ParseModMenuFile(string modMenuFile, ModItem modItem)
         {
         {
             if (!validBG2MenuFile(modMenuFile)) return false;
             if (!validBG2MenuFile(modMenuFile)) return false;
 
 
@@ -579,9 +669,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     fileStream.Read(buf, 0, (int)fileStream.Length);
                     fileStream.Read(buf, 0, (int)fileStream.Length);
                 }
                 }
             }
             }
-            catch
+            catch (Exception e)
             {
             {
-                Debug.LogError($"Could not read mod menu file '{modMenuFile}'");
+                Debug.LogError($"Could not read mod menu file '{modMenuFile} because {e.Message}'");
                 return false;
                 return false;
             }
             }
 
 
@@ -597,10 +687,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                         binaryReader.ReadInt32();
                         binaryReader.ReadInt32();
                         string iconName = binaryReader.ReadString();
                         string iconName = binaryReader.ReadString();
                         string baseItemPath = binaryReader.ReadString().Replace(":", " ");
                         string baseItemPath = binaryReader.ReadString().Replace(":", " ");
-                        menuItem.BaseMenuFile = Path.GetFileName(baseItemPath);
-                        menuItem.Name = binaryReader.ReadString();
-                        menuItem.Category = binaryReader.ReadString();
-                        if (!accMpn.Contains(menuItem.Category)) return false;
+                        modItem.BaseMenuFile = Path.GetFileName(baseItemPath);
+                        modItem.Name = binaryReader.ReadString();
+                        modItem.Category = binaryReader.ReadString();
+                        if (!accMpn.Contains(modItem.Category)) return false;
                         binaryReader.ReadString();
                         binaryReader.ReadString();
                         string mpnValue = binaryReader.ReadString();
                         string mpnValue = binaryReader.ReadString();
                         MPN mpn = MPN.null_mpn;
                         MPN mpn = MPN.null_mpn;
@@ -627,15 +717,15 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                             {
                             {
                                 Texture2D tex = new Texture2D(1, 1, TextureFormat.RGBA32, false);
                                 Texture2D tex = new Texture2D(1, 1, TextureFormat.RGBA32, false);
                                 tex.LoadImage(data);
                                 tex.LoadImage(data);
-                                menuItem.Icon = tex;
+                                modItem.Icon = tex;
                                 break;
                                 break;
                             }
                             }
                         }
                         }
                     }
                     }
                 }
                 }
-                catch
+                catch (Exception e)
                 {
                 {
-                    Debug.LogWarning($"Could not parse mod menu file '{modMenuFile}'");
+                    Debug.LogWarning($"Could not parse mod menu file '{modMenuFile}' because {e}");
                     return false;
                     return false;
                 }
                 }
             }
             }
@@ -646,7 +736,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         {
         {
             menu = Path.GetFileNameWithoutExtension(menu).ToLower();
             menu = Path.GetFileNameWithoutExtension(menu).ToLower();
             return !(menu.EndsWith("_del") || menu.Contains("zurashi") || menu.Contains("mekure")
             return !(menu.EndsWith("_del") || menu.Contains("zurashi") || menu.Contains("mekure")
-                || menu.Contains("porori") || menu.Contains("moza"));
+                || menu.Contains("porori") || menu.Contains("moza") || menu.Contains("folder"));
         }
         }
 
 
         public abstract class MenuItem
         public abstract class MenuItem
@@ -655,19 +745,19 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             public Texture2D Icon { get; set; }
             public Texture2D Icon { get; set; }
         }
         }
 
 
-        public class ItemData : MenuItem
+        public class ModItem : MenuItem
         {
         {
             public string MenuFile { get; set; }
             public string MenuFile { get; set; }
             public string BaseMenuFile { get; set; }
             public string BaseMenuFile { get; set; }
             public string Name { get; set; }
             public string Name { get; set; }
             public string Category { get; set; }
             public string Category { get; set; }
-            public int Priority { get; set; }
+            public float Priority { get; set; }
             public bool IsMod { get; set; }
             public bool IsMod { get; set; }
             public bool IsOfficialMod { get; set; }
             public bool IsOfficialMod { get; set; }
             public string ModelFile { get; set; }
             public string ModelFile { get; set; }
         }
         }
 
 
-        public class CreativeItem : MenuItem
+        public class MyRoomItem : MenuItem
         {
         {
             public int ID { get; set; }
             public int ID { get; set; }
             public string PrefabName { get; set; }
             public string PrefabName { get; set; }