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")]