Program.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. string managedDir = Environment.CurrentDirectory + @"\KoikatuTrial_Data\Managed";
  20. if (!Directory.Exists(managedDir))
  21. Error($"\"{managedDir}\" not found.");
  22. string unityOutputDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.dll");
  23. if (!File.Exists(unityOutputDLL))
  24. Error("\"UnityEngine.dll\" not found.");
  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. static void InjectAssembly(AssemblyDefinition unity, AssemblyDefinition injected)
  44. {
  45. //Entry point
  46. var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader")
  47. .Methods.First(x => x.Name == "Initialize");
  48. var injectMethod = unity.MainModule.ImportReference(originalInjectMethod);
  49. var sceneManager = unity.MainModule.Types.First(x => x.Name == "Application");
  50. var voidType = unity.MainModule.ImportReference(typeof(void));
  51. var cctor = new MethodDefinition(".cctor",
  52. MethodAttributes.Static
  53. | MethodAttributes.Private
  54. | MethodAttributes.HideBySig
  55. | MethodAttributes.SpecialName
  56. | MethodAttributes.RTSpecialName,
  57. voidType);
  58. var ilp = cctor.Body.GetILProcessor();
  59. ilp.Append(ilp.Create(OpCodes.Call, injectMethod));
  60. ilp.Append(ilp.Create(OpCodes.Ret));
  61. sceneManager.Methods.Add(cctor);
  62. }
  63. }
  64. }