Browse Source

Fix texture name capture; add versioning

Geoffrey Horsington 4 years ago
parent
commit
19e26f4e20
2 changed files with 80 additions and 42 deletions
  1. 54 37
      COM3D2.CacheEditMenu.Patcher/Patcher.cs
  2. 26 5
      COM3D2.CacheEditMenu/Hooks.cs

+ 54 - 37
COM3D2.CacheEditMenu.Patcher/Patcher.cs

@@ -11,7 +11,46 @@ namespace COM3D2.CacheEditMenu.Patcher
         public static readonly string[] TargetAssemblyNames = { "Assembly-CSharp.dll" };
 
         public static readonly string SybarisPath = Path.GetDirectoryName(typeof(Patcher).Assembly.Location);
-        
+
+        private static void PatchHelper(MethodDefinition target, MethodReference prefix, MethodReference postix, params int[] ldargs)
+        {
+            var il = target.Body.GetILProcessor();
+            var resultVar = target.ReturnType.FullName != "System.Void" ? new VariableDefinition(target.Module.ImportReference(target.ReturnType)) : null;
+            if(resultVar != null)
+                target.Body.Variables.Add(resultVar);
+            
+            var ins = target.Body.Instructions[0];
+
+            if(resultVar != null)
+                il.InsertBefore(ins, il.Create(OpCodes.Ldloca, resultVar));
+            foreach (var ldarg in ldargs)
+                il.InsertBefore(ins, il.Create(OpCodes.Ldarg, ldarg));
+            il.InsertBefore(ins, il.Create(OpCodes.Call, target.Module.ImportReference(prefix)));
+            il.InsertBefore(ins, il.Create(OpCodes.Brtrue, ins));
+            if(resultVar != null)
+                il.InsertBefore(ins, il.Create(OpCodes.Ldloc, resultVar));
+            il.InsertBefore(ins, il.Create(OpCodes.Ret));
+
+            if (postix == null)
+                return;
+
+            ins = il.Create(OpCodes.Nop);
+
+            foreach (var bodyInstruction in target.Body.Instructions.Where(bodyInstruction => bodyInstruction.OpCode == OpCodes.Ret).Skip(1))
+            {
+                bodyInstruction.OpCode = OpCodes.Br;
+                bodyInstruction.Operand = ins;
+            }
+
+            il.Append(ins);
+            ins = il.Create(OpCodes.Ret);
+            il.Append(ins);
+
+            foreach (var ldarg in ldargs)
+                il.InsertBefore(ins, il.Create(OpCodes.Ldarg, ldarg));
+            il.InsertBefore(ins, il.Create(OpCodes.Call, target.Module.ImportReference(postix)));
+        }
+
         public static void Patch(AssemblyDefinition ad)
         {
             var hookAd = AssemblyDefinition.ReadAssembly(
@@ -21,51 +60,29 @@ namespace COM3D2.CacheEditMenu.Patcher
             var sceneEdit = ad.MainModule.GetType("SceneEdit");
             var getMenuItemSetUp = sceneEdit.Methods.FirstOrDefault(m => m.Name == "GetMenuItemSetUP");
 
+            var importCm = ad.MainModule.GetType("ImportCM");
+            var createTexture = importCm.Methods.FirstOrDefault(m => m.Name == "CreateTexture" && m.Parameters.Count == 1);
+
             var hookType = hookAd.MainModule.GetType("COM3D2.CacheEditMenu.Hooks");
             var getMenuItemSetUpPrefix = hookType.Methods.FirstOrDefault(m => m.Name == "Prefix");
             var getMenuItemSetUpPostfix = hookType.Methods.FirstOrDefault(m => m.Name == "Postfix");
 
-            var il = getMenuItemSetUp.Body.GetILProcessor();
-            var resultVar = new VariableDefinition(ad.MainModule.ImportReference(typeof(bool)));
-            getMenuItemSetUp.Body.Variables.Add(resultVar);
-            var ins = getMenuItemSetUp.Body.Instructions[0];
-            
-            il.InsertBefore(ins, il.Create(OpCodes.Ldloca, resultVar));
-            il.InsertBefore(ins, il.Create(OpCodes.Ldarg_0));
-            il.InsertBefore(ins, il.Create(OpCodes.Ldarg_1));
-            il.InsertBefore(ins, il.Create(OpCodes.Call, ad.MainModule.ImportReference(getMenuItemSetUpPrefix)));
-            il.InsertBefore(ins, il.Create(OpCodes.Brtrue, ins));
-            il.InsertBefore(ins, il.Create(OpCodes.Ldloc, resultVar));
-            il.InsertBefore(ins, il.Create(OpCodes.Ret));
-            
-            ins = il.Create(OpCodes.Nop);
-            
-            foreach (var bodyInstruction in getMenuItemSetUp.Body.Instructions.Where(bodyInstruction => bodyInstruction.OpCode == OpCodes.Ret).Skip(1))
-            {
-                bodyInstruction.OpCode = OpCodes.Br;
-                bodyInstruction.Operand = ins;
-            }
-            
-            il.Append(ins);
-            ins = il.Create(OpCodes.Ret);
-            il.Append(ins);
-            
-            il.InsertBefore(ins, il.Create(OpCodes.Ldarg_0));
-            il.InsertBefore(ins, il.Create(OpCodes.Ldarg_1));
-            il.InsertBefore(ins, il.Create(OpCodes.Call, ad.MainModule.ImportReference(getMenuItemSetUpPostfix)));
-            
+            var createTexturePrefix = hookType.Methods.FirstOrDefault(m => m.Name == "CreateTexturePrefix");
+
+            PatchHelper(getMenuItemSetUp, getMenuItemSetUpPrefix, getMenuItemSetUpPostfix, 0, 1);
+            PatchHelper(createTexture, createTexturePrefix, null, 0);
 
             var buffer = new byte[4096];
             using(var s = typeof(Patcher).Assembly.GetManifestResourceStream(
                 "COM3D2.CacheEditMenu.Patcher.COM3D2.CacheEditMenu.dll"))
-            using (var ms = new MemoryStream())
-            {
-                int read;
-                while ((read = s.Read(buffer, 0, buffer.Length)) > 0)
-                    ms.Write(buffer, 0, read);
+                using (var ms = new MemoryStream())
+                {
+                    int read;
+                    while ((read = s.Read(buffer, 0, buffer.Length)) > 0)
+                        ms.Write(buffer, 0, read);
 
-                Assembly.Load(ms.ToArray());
-            }
+                    Assembly.Load(ms.ToArray());
+                }
         }
     }
 }

+ 26 - 5
COM3D2.CacheEditMenu/Hooks.cs

@@ -24,6 +24,8 @@ namespace COM3D2.CacheEditMenu
 
     public static class Hooks
     {
+        private const int CACHE_VERSION = 1000;
+
         private static readonly Dictionary<string, MenuInfo> infoCache = new Dictionary<string, MenuInfo>();
         private static BinaryWriter cacheWriter;
 
@@ -129,6 +131,13 @@ namespace COM3D2.CacheEditMenu
             return true;
         }
 
+        public static string texFileName = null;
+
+        public static bool CreateTexturePrefix(ref Texture2D result, string fileName)
+        {
+            texFileName = fileName;
+            return true;
+        }
 
         public static bool Postfix(bool result, SceneEdit.SMenuItem mi, string menuFileName)
         {
@@ -140,7 +149,8 @@ namespace COM3D2.CacheEditMenu
                 mi = mi,
                 key = menuFileName
             };
-            getTexFileIDDic().TryGetValue(mi.m_nMenuFileRID, out menuInfo.texName);
+            if (!getTexFileIDDic().TryGetValue(mi.m_nMenuFileRID, out menuInfo.texName) && texFileName != null)
+                menuInfo.texName = texFileName;
             infoCache[menuFileName] = menuInfo;
 
             try
@@ -155,6 +165,8 @@ namespace COM3D2.CacheEditMenu
 
             cacheWriter.Flush();
 
+            texFileName = null;
+
             return true;
         }
 
@@ -174,11 +186,19 @@ namespace COM3D2.CacheEditMenu
                 {
                     try
                     {
-                        while (true)
+                        if (br.ReadInt32() == CACHE_VERSION)
+                        {
+                            while (true)
+                            {
+                                var menuInfo = new MenuInfo();
+                                menuInfo.Deserialize(br);
+                                infoCache[menuInfo.key] = menuInfo;
+                            }
+                        }
+                        else
                         {
-                            var menuInfo = new MenuInfo();
-                            menuInfo.Deserialize(br);
-                            infoCache[menuInfo.key] = menuInfo;
+                            Debug.LogWarning("Outdated cache, rebuilding...");
+                            rebuildCache = true;
                         }
                     }
                     catch (FormatException e)
@@ -197,6 +217,7 @@ namespace COM3D2.CacheEditMenu
 
             if (rebuildCache)
             {
+                cacheWriter.Write(CACHE_VERSION);
                 foreach (var keyValuePair in infoCache)
                     keyValuePair.Value.Serialize(cacheWriter);
                 cacheWriter.Flush();