Program.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using Mono.Cecil;
  2. using Mono.Cecil.Cil;
  3. using System;
  4. using System.IO;
  5. using System.Linq;
  6. namespace BepInEx.Patcher
  7. {
  8. class Program
  9. {
  10. static void Error(string message)
  11. {
  12. Console.WriteLine($"Error: {message}");
  13. Console.WriteLine("Press any key to continue...");
  14. Console.ReadKey();
  15. Environment.Exit(1);
  16. }
  17. static void Main(string[] args)
  18. {
  19. foreach (string exePath in Directory.GetFiles(Directory.GetCurrentDirectory()))
  20. {
  21. string managedDir = Environment.CurrentDirectory + $@"\{Path.GetFileNameWithoutExtension(exePath)}_Data\Managed";
  22. string unityOutputDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.dll");
  23. if (!Directory.Exists(managedDir) || !File.Exists(unityOutputDLL))
  24. continue;
  25. string unityOriginalDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.dll.bak");
  26. if (!File.Exists(unityOriginalDLL))
  27. File.Copy(unityOutputDLL, unityOriginalDLL);
  28. string harmony = Path.GetFullPath($"{managedDir}\\0Harmony.dll");
  29. File.WriteAllBytes(harmony, Resources._0Harmony);
  30. string injectedDLL = Path.GetFullPath($"{managedDir}\\BepInEx.dll");
  31. File.WriteAllBytes(injectedDLL, Resources.BepInEx);
  32. var defaultResolver = new DefaultAssemblyResolver();
  33. defaultResolver.AddSearchDirectory(managedDir);
  34. var rp = new ReaderParameters
  35. {
  36. AssemblyResolver = defaultResolver
  37. };
  38. AssemblyDefinition unity = AssemblyDefinition.ReadAssembly(unityOriginalDLL, rp);
  39. AssemblyDefinition injected = AssemblyDefinition.ReadAssembly(injectedDLL, rp);
  40. InjectAssembly(unity, injected);
  41. unity.Write(unityOutputDLL);
  42. }
  43. }
  44. static void InjectAssembly(AssemblyDefinition unity, AssemblyDefinition injected)
  45. {
  46. //Entry point
  47. var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader")
  48. .Methods.First(x => x.Name == "Initialize");
  49. var injectMethod = unity.MainModule.ImportReference(originalInjectMethod);
  50. var sceneManager = unity.MainModule.Types.First(x => x.Name == "Application");
  51. var voidType = unity.MainModule.ImportReference(typeof(void));
  52. var cctor = new MethodDefinition(".cctor",
  53. MethodAttributes.Static
  54. | MethodAttributes.Private
  55. | MethodAttributes.HideBySig
  56. | MethodAttributes.SpecialName
  57. | MethodAttributes.RTSpecialName,
  58. voidType);
  59. var ilp = cctor.Body.GetILProcessor();
  60. ilp.Append(ilp.Create(OpCodes.Call, injectMethod));
  61. ilp.Append(ilp.Create(OpCodes.Ret));
  62. sceneManager.Methods.Add(cctor);
  63. }
  64. }
  65. }