You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.3 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. using Harmony;
  2. using IPA.Loader;
  3. using IPA.Logging;
  4. using System;
  5. using System.IO;
  6. using System.Reflection;
  7. using System.Runtime.InteropServices;
  8. using UnityEngine;
  9. using static IPA.Logging.Logger;
  10. namespace IPA.Injector
  11. {
  12. public static class Injector
  13. {
  14. public static void Main(string[] args)
  15. { // entry point for doorstop
  16. // At this point, literally nothing but mscorlib is loaded,
  17. // and since this class doesn't have any static fields that
  18. // aren't defined in mscorlib, we can control exactly what
  19. // gets loaded.
  20. try
  21. {
  22. // This loads System.Runtime.InteropServices, and Microsoft.Win32.SafeHandles.
  23. Windows.WinConsole.Initialize();
  24. // This loads AppDomain, System.IO, System.Collections.Generic, and System.Reflection.
  25. // If kernel32.dll is not already loaded, this will also load it.
  26. // This call also loads IPA.Loader and initializes the logging system. In the process
  27. // it loads Ionic.Zip.
  28. SetupLibraryLoading();
  29. // This will load Harmony and UnityEngine.CoreModule
  30. InstallBootstrapPatch();
  31. }
  32. catch (Exception e)
  33. {
  34. Console.WriteLine(e);
  35. }
  36. }
  37. private static void InstallBootstrapPatch()
  38. {
  39. var harmony = HarmonyInstance.Create("IPA_NonDestructive_Bootstrapper");
  40. // patch the Application static constructor to create the bootstrapper after being called
  41. harmony.Patch(typeof(Application).TypeInitializer, null, new HarmonyMethod(typeof(Injector).GetMethod(nameof(CreateBootstrapper), BindingFlags.NonPublic | BindingFlags.Static)));
  42. }
  43. private static void CreateBootstrapper()
  44. {
  45. var bootstrapper = new GameObject("NonDestructiveBootstrapper").AddComponent<Bootstrapper>();
  46. bootstrapper.Destroyed += Bootstrapper_Destroyed;
  47. }
  48. private static bool injected = false;
  49. public static void Inject()
  50. {
  51. if (!injected)
  52. {
  53. injected = true;
  54. Windows.WinConsole.Initialize();
  55. SetupLibraryLoading();
  56. var bootstrapper = new GameObject("Bootstrapper").AddComponent<Bootstrapper>();
  57. bootstrapper.Destroyed += Bootstrapper_Destroyed;
  58. }
  59. }
  60. private static bool loadingDone = false;
  61. public static void SetupLibraryLoading()
  62. {
  63. if (loadingDone) return;
  64. loadingDone = true;
  65. #region Add Library load locations
  66. AppDomain.CurrentDomain.AssemblyResolve += LibLoader.AssemblyLibLoader;
  67. try
  68. {
  69. if (!SetDllDirectory(LibLoader.NativeDir))
  70. {
  71. libLoader.Warn("Unable to add native library path to load path");
  72. }
  73. }
  74. catch (Exception) { }
  75. #endregion
  76. }
  77. [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  78. [return: MarshalAs(UnmanagedType.Bool)]
  79. static extern bool SetDllDirectory(string lpPathName);
  80. private static void Bootstrapper_Destroyed()
  81. {
  82. PluginComponent.Create();
  83. }
  84. }
  85. }