diff --git a/IPA.Injector/Bootstrapper.cs b/IPA.Injector/Bootstrapper.cs index 0f8e6cd2..1bdc0ae6 100644 --- a/IPA.Injector/Bootstrapper.cs +++ b/IPA.Injector/Bootstrapper.cs @@ -12,10 +12,6 @@ namespace IPA.Injector void Awake() { - //if (Environment.CommandLine.Contains("--verbose")) - //{ - Windows.WinConsole.Initialize(); - //} } void Start() diff --git a/IPA.Injector/IPA.Injector.csproj b/IPA.Injector/IPA.Injector.csproj index 11ad1325..2bd2e7a5 100644 --- a/IPA.Injector/IPA.Injector.csproj +++ b/IPA.Injector/IPA.Injector.csproj @@ -31,6 +31,11 @@ 4 + + False + ..\Libs\0Harmony.dll + False + diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs index 02bb9211..d1fcd727 100644 --- a/IPA.Injector/Injector.cs +++ b/IPA.Injector/Injector.cs @@ -1,4 +1,5 @@ -using IPA.Loader; +using Harmony; +using IPA.Loader; using IPA.Logging; using System; using System.IO; @@ -11,28 +12,68 @@ namespace IPA.Injector { public static class Injector { + public static void Main(string[] args) + { // entry point for doorstop + // At this point, literally nothing but mscorlib is loaded, + // and since this class doesn't have any static fields that + // aren't defined in mscorlib, we can control exactly what + // gets loaded. + + // This loads AppDomain, System.IO, System.Collections.Generic, and System.Reflection. + // If kernel32.dll is not already loaded, this will also load it. + // This call also loads IPA.Loader and initializes the logging system. In the process + // it loads Ionic.Zip. + SetupLibraryLoading(); + + // This loads System.Runtime.InteropServices, and Microsoft.Win32.SafeHandles. + Windows.WinConsole.Initialize(); + + // This will load Harmony and UnityEngine.CoreModule + InstallBootstrapPatch(); + } + + private static void InstallBootstrapPatch() + { + var harmony = HarmonyInstance.Create("IPA_NonDestructive_Bootstrapper"); + // patch the Application static constructor to create the bootstrapper after being called + harmony.Patch(typeof(Application).TypeInitializer, null, new HarmonyMethod(typeof(Injector).GetMethod(nameof(CreateBootstrapper), BindingFlags.NonPublic | BindingFlags.Static))); + } + + private static void CreateBootstrapper() + { + var bootstrapper = new GameObject("NonDestructiveBootstrapper").AddComponent(); + bootstrapper.Destroyed += Bootstrapper_Destroyed; + } + private static bool injected = false; public static void Inject() { if (!injected) { injected = true; + Windows.WinConsole.Initialize(); + SetupLibraryLoading(); + var bootstrapper = new GameObject("Bootstrapper").AddComponent(); + bootstrapper.Destroyed += Bootstrapper_Destroyed; + } + } - #region Add Library load locations - AppDomain.CurrentDomain.AssemblyResolve += LibLoader.AssemblyLibLoader; - try + private static bool loadingDone = false; + public static void SetupLibraryLoading() + { + if (loadingDone) return; + loadingDone = true; + #region Add Library load locations + AppDomain.CurrentDomain.AssemblyResolve += LibLoader.AssemblyLibLoader; + try + { + if (!SetDllDirectory(LibLoader.NativeDir)) { - if (!SetDllDirectory(LibLoader.NativeDir)) - { - libLoader.Warn("Unable to add native library path to load path"); - } + libLoader.Warn("Unable to add native library path to load path"); } - catch (Exception) { } - #endregion - - var bootstrapper = new GameObject("Bootstrapper").AddComponent(); - bootstrapper.Destroyed += Bootstrapper_Destroyed; } + catch (Exception) { } + #endregion } [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] diff --git a/IPA.Injector/Properties/AssemblyInfo.cs b/IPA.Injector/Properties/AssemblyInfo.cs index 9b4a786f..841a8059 100644 --- a/IPA.Injector/Properties/AssemblyInfo.cs +++ b/IPA.Injector/Properties/AssemblyInfo.cs @@ -35,5 +35,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.10.1")] -[assembly: AssemblyFileVersion("3.10.1")] +[assembly: AssemblyVersion("3.10.2")] +[assembly: AssemblyFileVersion("3.10.2")] diff --git a/IPA.Loader/Updating/SelfPlugin.cs b/IPA.Loader/Updating/SelfPlugin.cs index 0293b832..30a51e97 100644 --- a/IPA.Loader/Updating/SelfPlugin.cs +++ b/IPA.Loader/Updating/SelfPlugin.cs @@ -11,7 +11,7 @@ namespace IPA.Updating internal class SelfPlugin : IBeatSaberPlugin { internal const string IPA_Name = "Beat Saber IPA"; - internal const string IPA_Version = "3.10.1"; + internal const string IPA_Version = "3.10.2"; public static SelfPlugin Instance { get; set; } = new SelfPlugin(); diff --git a/IPA/Properties/AssemblyInfo.cs b/IPA/Properties/AssemblyInfo.cs index eacd52a8..62d234b8 100644 --- a/IPA/Properties/AssemblyInfo.cs +++ b/IPA/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.10.1")] -[assembly: AssemblyFileVersion("3.10.1")] +[assembly: AssemblyVersion("3.10.2")] +[assembly: AssemblyFileVersion("3.10.2")]