diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs
index 88fd3524..8214b81f 100644
--- a/IPA.Injector/Injector.cs
+++ b/IPA.Injector/Injector.cs
@@ -83,6 +83,8 @@ namespace IPA.Injector
return;
}
+ CriticalSection.Configure();
+
loader.Debug("Prepping bootstrapper");
// updates backup
@@ -141,6 +143,9 @@ namespace IPA.Injector
var unityPath = Path.Combine(managedPath,
"UnityEngine.CoreModule.dll");
+ // this is a critical section because if you exit in here, CoreModule can die
+ CriticalSection.EnterExecuteSection();
+
var unityAsmDef = AssemblyDefinition.ReadAssembly(unityPath, new ReaderParameters
{
ReadWrite = false,
@@ -220,8 +225,8 @@ namespace IPA.Injector
bkp?.Add(unityPath);
unityAsmDef.Write(unityPath);
}
- /*else
- return; // shortcut*/
+
+ CriticalSection.ExitExecuteSection();
}
#endregion Insert patch into UnityEngine.CoreModule.dll
@@ -235,15 +240,20 @@ namespace IPA.Injector
#region Virtualize Assembly-CSharp.dll
{
+ CriticalSection.EnterExecuteSection();
+
var ascModule = VirtualizedModule.Load(ascPath);
ascModule.Virtualize(cAsmName, () => bkp?.Add(ascPath));
+
+ CriticalSection.ExitExecuteSection();
}
#endregion Virtualize Assembly-CSharp.dll
#region Anti-Yeet
- //if (SelfConfig.SelfConfigRef.Value.ApplyAntiYeet)
+ CriticalSection.EnterExecuteSection();
+
try
{
loader.Debug("Applying anti-yeet patch");
@@ -266,6 +276,8 @@ namespace IPA.Injector
// ignore
}
+ CriticalSection.ExitExecuteSection();
+
#endregion
}
}
diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj
index 3170c485..3ead06af 100644
--- a/IPA.Loader/IPA.Loader.csproj
+++ b/IPA.Loader/IPA.Loader.csproj
@@ -13,7 +13,6 @@
true
$(SolutionDir)=C:\
portable
-
false
true
net461;net35
@@ -79,7 +78,7 @@
-
+
{642F52DA-90F9-40E3-8784-6964F36752FB}
Net3-Proxy
@@ -122,6 +121,7 @@
+
diff --git a/IPA.Loader/Utilities/BeatSaber.cs b/IPA.Loader/Utilities/BeatSaber.cs
index 15fd15c8..f6d57c2a 100644
--- a/IPA.Loader/Utilities/BeatSaber.cs
+++ b/IPA.Loader/Utilities/BeatSaber.cs
@@ -1,4 +1,5 @@
-using System;
+using IPA.Config;
+using System;
using System.IO;
using System.Reflection;
using UnityEngine;
@@ -18,20 +19,30 @@ namespace IPA.Utilities
/// Provides the current game version.
///
/// the SemVer version of the game
- public static AlmostVersion GameVersion => _gameVersion ?? (_gameVersion = new AlmostVersion(Application.version));
+ public static AlmostVersion GameVersion => _gameVersion ?? (_gameVersion = new AlmostVersion(ApplicationVersionProxy));
internal static void SetEarlyGameVersion(AlmostVersion ver)
{
_gameVersion = ver;
Logging.Logger.log.Debug($"GameVersion set early to {ver}");
}
+ private static string ApplicationVersionProxy => Application.version;
internal static void EnsureRuntimeGameVersion()
{
- var rtVer = new AlmostVersion(Application.version);
- if (!rtVer.Equals(_gameVersion)) // this actually uses stricter equality than == for AlmostVersion
+ try
{
- Logging.Logger.log.Warn($"Early version {_gameVersion} parsed from game files doesn't match runtime version {rtVer}!");
- _gameVersion = rtVer;
+ var rtVer = new AlmostVersion(ApplicationVersionProxy);
+ if (!rtVer.Equals(_gameVersion)) // this actually uses stricter equality than == for AlmostVersion
+ {
+ Logging.Logger.log.Warn($"Early version {_gameVersion} parsed from game files doesn't match runtime version {rtVer}!");
+ _gameVersion = rtVer;
+ }
+ }
+ catch (MissingMethodException e)
+ {
+ Logging.Logger.log.Error("Application.version was not found! Cannot check early parsed version");
+ if (SelfConfig.Debug_.ShowHandledErrorStackTraces_)
+ Logging.Logger.log.Error(e);
}
}
diff --git a/IPA.Loader/Utilities/CriticalSection.cs b/IPA.Loader/Utilities/CriticalSection.cs
new file mode 100644
index 00000000..cdbb982e
--- /dev/null
+++ b/IPA.Loader/Utilities/CriticalSection.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using IPA.Logging;
+
+namespace IPA.Utilities
+{
+ public static class CriticalSection
+ {
+
+ internal static void Configure()
+ {
+ Logger.log.Debug("Configuring exit handlers");
+
+ ResetExitHandlers();
+ }
+
+ #region Execute section
+
+ private static readonly EventHandler registeredHandler = HandleExit;
+ internal static void ResetExitHandlers()
+ {
+ SetConsoleCtrlHandler(registeredHandler, false);
+ SetConsoleCtrlHandler(registeredHandler, true);
+ }
+
+ [DllImport("Kernel32")]
+ private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
+
+ private delegate bool EventHandler(CtrlType sig);
+ private static EventHandler _handler = null;
+
+ private static bool HandleExit(CtrlType type)
+ {
+ if (_handler != null)
+ return _handler(type);
+
+ return false;
+ }
+
+ enum CtrlType
+ {
+ CTRL_C_EVENT = 0,
+ CTRL_BREAK_EVENT = 1,
+ CTRL_CLOSE_EVENT = 2,
+ CTRL_LOGOFF_EVENT = 5,
+ CTRL_SHUTDOWN_EVENT = 6
+ }
+
+ private static volatile bool exitRecieved = false;
+
+ public static void EnterExecuteSection()
+ {
+ ResetExitHandlers();
+
+ exitRecieved = false;
+ _handler = sig => exitRecieved = true;
+ }
+
+ public static void ExitExecuteSection()
+ {
+ _handler = null;
+
+ if (exitRecieved)
+ Environment.Exit(1);
+ }
+
+ #endregion
+
+ }
+}
diff --git a/Refs/Assembly-CSharp.dll b/Refs/Assembly-CSharp.dll
index b4acc11b..89553eba 100644
Binary files a/Refs/Assembly-CSharp.dll and b/Refs/Assembly-CSharp.dll differ
diff --git a/Refs/UnityEngine.CoreModule.Net4.dll b/Refs/UnityEngine.CoreModule.Net4.dll
index d54be652..f6478af7 100644
Binary files a/Refs/UnityEngine.CoreModule.Net4.dll and b/Refs/UnityEngine.CoreModule.Net4.dll differ