Program.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using BepInEx.Common;
  2. using Mono.Cecil;
  3. using Mono.Cecil.Cil;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Text;
  10. namespace BepInEx.Patcher
  11. {
  12. class Program
  13. {
  14. static void Error(string message)
  15. {
  16. Console.WriteLine($"Error: {message}");
  17. Console.WriteLine("Press any key to continue...");
  18. Console.ReadKey();
  19. Environment.Exit(1);
  20. }
  21. static void Main(string[] args)
  22. {
  23. string assemblyDLL = Path.GetFullPath("Assembly-CSharp.dll");
  24. if (!File.Exists(assemblyDLL))
  25. Error("\"Assembly-CSharp.dll\" not found.");
  26. string assemblyOriginalDLL = Path.GetFullPath("Assembly-CSharp.dll.bak");
  27. if (!File.Exists(assemblyOriginalDLL))
  28. File.Copy(assemblyDLL, assemblyOriginalDLL);
  29. string unityOutputDLL = Path.GetFullPath("UnityEngine.dll");
  30. if (!File.Exists(unityOutputDLL))
  31. Error("\"UnityEngine.dll\" not found.");
  32. string unityOriginalDLL = Path.GetFullPath("UnityEngine.dll.bak");
  33. if (!File.Exists(unityOriginalDLL))
  34. File.Copy(unityOutputDLL, unityOriginalDLL);
  35. Assembly.LoadFile(unityOriginalDLL);
  36. string tmOutputDLL = Path.GetFullPath("TextMeshPro-1.0.55.56.0b12.dll");
  37. if (!File.Exists(tmOutputDLL))
  38. Error("\"TextMeshPro-1.0.55.56.0b12.dll\" not found.");
  39. string tmOriginalDLL = Path.GetFullPath("TextMeshPro-1.0.55.56.0b12.dll.bak");
  40. if (!File.Exists(tmOriginalDLL))
  41. File.Copy(tmOutputDLL, tmOriginalDLL);
  42. string injectedDLL = Path.GetFullPath("BepInEx.dll");
  43. if (!File.Exists(unityOutputDLL))
  44. Error("\"BepInEx.dll\" not found.");
  45. string referenceDir = Directory.GetCurrentDirectory();
  46. var defaultResolver = new DefaultAssemblyResolver();
  47. defaultResolver.AddSearchDirectory(referenceDir);
  48. AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyOriginalDLL, new ReaderParameters {
  49. AssemblyResolver = defaultResolver
  50. });
  51. AssemblyDefinition unity = AssemblyDefinition.ReadAssembly(unityOriginalDLL, new ReaderParameters
  52. {
  53. AssemblyResolver = defaultResolver
  54. });
  55. AssemblyDefinition tm = AssemblyDefinition.ReadAssembly(tmOriginalDLL, new ReaderParameters
  56. {
  57. AssemblyResolver = defaultResolver
  58. });
  59. AssemblyDefinition injected = AssemblyDefinition.ReadAssembly(injectedDLL, new ReaderParameters
  60. {
  61. AssemblyResolver = defaultResolver
  62. });
  63. InjectAssembly(assembly, unity, tm, injected);
  64. assembly.Write(assemblyDLL);
  65. unity.Write(unityOutputDLL);
  66. tm.Write(tmOutputDLL);
  67. }
  68. static void InjectAssembly(AssemblyDefinition assembly, AssemblyDefinition unity, AssemblyDefinition tm, AssemblyDefinition injected)
  69. {
  70. //Entry point
  71. var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "Initialize");
  72. var injectMethod = unity.MainModule.Import(originalInjectMethod);
  73. var sceneManager = unity.MainModule.Types.First(x => x.Name == "SceneManager");
  74. ILProcessor IL;
  75. foreach (var loadScene in sceneManager.Methods.Where(x => x.Name == "LoadScene"))
  76. {
  77. IL = loadScene.Body.GetILProcessor();
  78. IL.InsertBefore(loadScene.Body.Instructions[0], IL.Create(OpCodes.Call, injectMethod));
  79. }
  80. //Text loading
  81. originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "TextLoadedHook");
  82. injectMethod = tm.MainModule.Import(originalInjectMethod);
  83. TypeDefinition tmpText = tm.MainModule.Types.First(x => x.Name == "TMP_Text");
  84. var setText = tmpText.Methods.First(x => x.Name == "set_text");
  85. IL = setText.Body.GetILProcessor();
  86. IL.InsertAfter(setText.Body.Instructions[11], IL.Create(OpCodes.Call, injectMethod));
  87. //IL.InsertAfter(setText.Body.Instructions[3], IL.Create(OpCodes.Call, injectMethod));
  88. }
  89. }
  90. }