Browse Source

Fix for translations unloading

Bepis 6 years ago
parent
commit
ed6a43a94b

+ 52 - 3
BepInEx.Patcher/Program.cs

@@ -40,6 +40,15 @@ namespace BepInEx.Patcher
                 File.Copy(unityOutputDLL, unityOriginalDLL);
 
 
+            string tmOutputDLL = Path.GetFullPath("TextMeshPro-1.0.55.56.0b12.dll");
+            if (!File.Exists(tmOutputDLL))
+                Error("\"TextMeshPro-1.0.55.56.0b12.dll\" not found.");
+
+            string tmOriginalDLL = Path.GetFullPath("TextMeshPro-1.0.55.56.0b12.dll.bak");
+            if (!File.Exists(tmOriginalDLL))
+                File.Copy(tmOutputDLL, tmOriginalDLL);
+
+
             string injectedDLL = Path.GetFullPath("BepInEx.dll");
             if (!File.Exists(unityOutputDLL))
                 Error("\"BepInEx.dll\" not found.");
@@ -57,6 +66,10 @@ namespace BepInEx.Patcher
             {
                 AssemblyResolver = defaultResolver
             });
+            AssemblyDefinition tm = AssemblyDefinition.ReadAssembly(tmOriginalDLL, new ReaderParameters
+            {
+                AssemblyResolver = defaultResolver
+            });
             AssemblyDefinition injected = AssemblyDefinition.ReadAssembly(injectedDLL, new ReaderParameters
             {
                 AssemblyResolver = defaultResolver
@@ -74,27 +87,63 @@ namespace BepInEx.Patcher
             //title.Patch(assembly);
 
 
-            InjectAssembly(assembly, unity, injected);
+            InjectAssembly(assembly, unity, tm, injected);
 
 
             assembly.Write(assemblyDLL);
             unity.Write(unityOutputDLL);
+            tm.Write(tmOutputDLL);
         }
 
-        static void InjectAssembly(AssemblyDefinition assembly, AssemblyDefinition unity, AssemblyDefinition injected)
+        static void InjectAssembly(AssemblyDefinition assembly, AssemblyDefinition unity, AssemblyDefinition tm, AssemblyDefinition injected)
         {
+            //Entry point
             var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "Initialize");
 
             var injectMethod = unity.MainModule.Import(originalInjectMethod);
 
             var sceneManager = unity.MainModule.Types.First(x => x.Name == "SceneManager");
 
+            ILProcessor IL;
+
             foreach (var loadScene in sceneManager.Methods.Where(x => x.Name == "LoadScene"))
             {
-                ILProcessor IL = loadScene.Body.GetILProcessor();
+                IL = loadScene.Body.GetILProcessor();
 
                 IL.InsertBefore(loadScene.Body.Instructions[0], IL.Create(OpCodes.Call, injectMethod));
             }
+
+            //Text loading
+            //originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "TextLoadedHook");
+            //injectMethod = assembly.MainModule.Import(originalInjectMethod);
+
+            //TypeDefinition Data = assembly.MainModule.Types.First(x => x.Name == "Data");
+            //var constr = Data.Methods.First(x => x.Name == ".ctor");
+
+            //IL = constr.Body.GetILProcessor();
+
+            //var target = constr.Body.Instructions[0];
+            //IL.InsertBefore(target, IL.Create(OpCodes.Ldarg_1));
+            //IL.InsertBefore(target, IL.Create(OpCodes.Call, injectMethod));
+
+            originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "TextLoadedHook");
+            injectMethod = tm.MainModule.Import(originalInjectMethod);
+
+            TypeDefinition tmpText = tm.MainModule.Types.First(x => x.Name == "TMP_Text"); //TextMeshProUGUI
+            var setText = tmpText.Methods.First(x => x.Name == "set_text");
+
+            IL = setText.Body.GetILProcessor();
+            
+            IL.InsertAfter(setText.Body.Instructions[11], IL.Create(OpCodes.Call, injectMethod));
+            //IL.InsertAfter(setText.Body.Instructions[3], IL.Create(OpCodes.Call, injectMethod));
+
+            //IL.Replace(setText.Body.Instructions[3], IL.Create(OpCodes.Ldloc_2));
+            //IL.Replace(setText.Body.Instructions[11], IL.Create(OpCodes.Ldloc_2));
+
+            //var target = setText.Body.Instructions[0];
+            //IL.InsertBefore(target, IL.Create(OpCodes.Ldarg_1));
+            //IL.InsertBefore(target, IL.Create(OpCodes.Call, injectMethod));
+            //IL.InsertBefore(target, IL.Create(OpCodes.Stloc_2));
         }
     }
 }

+ 1 - 0
BepInEx/BepInEx.csproj

@@ -73,6 +73,7 @@
     <Compile Include="Internal\DumpScenePlugin.cs" />
     <Compile Include="Internal\TranslationPlugin.cs" />
     <Compile Include="Internal\UnlockedInputPlugin.cs" />
+    <Compile Include="ITranslationPlugin.cs" />
     <Compile Include="IUnityPlugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Utility.cs" />

+ 24 - 6
BepInEx/Chainloader.cs

@@ -11,6 +11,7 @@ namespace BepInEx
     {
         static bool loaded = false;
         public static IEnumerable<IUnityPlugin> Plugins;
+        public static IEnumerable<ITranslationPlugin> TLPlugins;
 
         public static void Initialize()
         {
@@ -20,20 +21,37 @@ namespace BepInEx
             UnityInjector.ConsoleUtil.ConsoleWindow.Attach();
             Console.WriteLine("Chainloader started");
 
-            List<IUnityPlugin> plugins = new List<IUnityPlugin>();
-            plugins.Add(new DumpScenePlugin());
-            plugins.Add(new TranslationPlugin());
-            plugins.Add(new UnlockedInputPlugin());
+            TranslationPlugin translationPlugin = new TranslationPlugin();
 
-            Plugins = plugins;
+            Plugins = new List<IUnityPlugin>
+            {
+                new DumpScenePlugin(),
+                new UnlockedInputPlugin(),
+                translationPlugin
+            };
+
+            TLPlugins = new List<ITranslationPlugin>
+            {
+                translationPlugin
+            };
 
             UnityInjector.ConsoleUtil.ConsoleWindow.Attach();
-            Console.WriteLine($"{plugins.Count} plugins loaded");
+            UnityInjector.ConsoleUtil.ConsoleEncoding.ConsoleCodePage = 932;
+            Console.WriteLine($"{Plugins.Count()} plugins loaded");
 
             
             BepInComponent.Create();
 
             loaded = true;
         }
+
+        public static string TextLoadedHook(string text)
+        {
+            foreach (var plugin in TLPlugins)
+                if (plugin.TryTranslate(text, out string output))
+                    return output;
+
+            return text;
+        }
     }
 }

+ 12 - 0
BepInEx/ITranslationPlugin.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BepInEx
+{
+    public interface ITranslationPlugin
+    {
+        bool TryTranslate(string input, out string output);
+    }
+}

+ 12 - 1
BepInEx/Internal/TranslationPlugin.cs

@@ -9,7 +9,7 @@ using UnityEngine.SceneManagement;
 
 namespace BepInEx.Internal
 {
-    public class TranslationPlugin : IUnityPlugin
+    public class TranslationPlugin : ITranslationPlugin, IUnityPlugin
     {
         Dictionary<string, string> translations = new Dictionary<string, string>();
 
@@ -60,5 +60,16 @@ namespace BepInEx.Internal
                     gameObject.text = translations[gameObject.text];
             }
         }
+
+        public bool TryTranslate(string input, out string output)
+        {
+            if (translations.ContainsKey(input))
+            {
+                output = translations[input];
+                return true;
+            }
+            output = null;
+            return false;
+        }
     }
 }