Quellcode durchsuchen

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 vor 4 Jahren
Ursprung
Commit
b232ae61b3
1 geänderte Dateien mit 129 neuen und 39 gelöschten Zeilen
  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.Collections;
 using System.Collections.Generic;
+using System.Linq;
 using UnityEngine;
 using UnityEngine.Rendering;
 
@@ -10,12 +11,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     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
         {
             None, ItemChange, TexChange
@@ -25,6 +27,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         static MenuFileUtility()
         {
+            accMpn.UnionWith(MenuCategories.Skip(1));
             GameMain.Instance.StartCoroutine(CheckMenuDataBaseJob());
         }
 
@@ -55,7 +58,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 string menuPropString = String.Empty;
                 string menuPropStringTemp = String.Empty;
                 // string tempString3 = String.Empty;
-                string slotName = String.Empty;
+                // string slotName = String.Empty;
 
                 try
                 {
@@ -453,17 +456,17 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         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[] 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)
                     {
@@ -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))
             {
@@ -510,27 +513,28 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
                 catch
                 {
-                    Debug.LogError($"Could not load mesh for '{menuItem.MenuFile}'");
+                    Debug.LogError($"Could not load mesh for '{modItem.MenuFile}'");
                 }
 
                 if (gameObject != null)
                 {
                     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>();
                             if (renderer != null && renderer.material != null
                                 && 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);
                     }
@@ -540,27 +544,113 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
             else
             {
-                Debug.LogWarning($"Could not parse menu file '{menuItem.MenuFile}'");
+                Debug.LogWarning($"Could not parse menu file '{modItem.MenuFile}'");
                 return null;
             }
         }
 
-        public static bool ParseNativeMenuFile(int menuIndex, ItemData menuItem)
+        public static bool ParseNativeMenuFile(int menuIndex, ModItem modItem)
         {
             MenuDataBase menuDataBase = GameMain.Instance.MenuDataBase;
             menuDataBase.SetIndex(menuIndex);
             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;
         }
 
-        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;
 
@@ -579,9 +669,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     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;
             }
 
@@ -597,10 +687,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                         binaryReader.ReadInt32();
                         string iconName = binaryReader.ReadString();
                         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();
                         string mpnValue = binaryReader.ReadString();
                         MPN mpn = MPN.null_mpn;
@@ -627,15 +717,15 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                             {
                                 Texture2D tex = new Texture2D(1, 1, TextureFormat.RGBA32, false);
                                 tex.LoadImage(data);
-                                menuItem.Icon = tex;
+                                modItem.Icon = tex;
                                 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;
                 }
             }
@@ -646,7 +736,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         {
             menu = Path.GetFileNameWithoutExtension(menu).ToLower();
             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
@@ -655,19 +745,19 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             public Texture2D Icon { get; set; }
         }
 
-        public class ItemData : MenuItem
+        public class ModItem : MenuItem
         {
             public string MenuFile { get; set; }
             public string BaseMenuFile { get; set; }
             public string Name { get; set; }
             public string Category { get; set; }
-            public int Priority { get; set; }
+            public float Priority { get; set; }
             public bool IsMod { get; set; }
             public bool IsOfficialMod { get; set; }
             public string ModelFile { get; set; }
         }
 
-        public class CreativeItem : MenuItem
+        public class MyRoomItem : MenuItem
         {
             public int ID { get; set; }
             public string PrefabName { get; set; }