diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs
index 70b8ec3f..fe614f55 100644
--- a/IPA.Injector/Injector.cs
+++ b/IPA.Injector/Injector.cs
@@ -142,7 +142,7 @@ namespace IPA.Injector
loader.Debug("Ensuring patch on UnityEngine.CoreModule exists");
-#region Insert patch into UnityEngine.CoreModule.dll
+ #region Insert patch into UnityEngine.CoreModule.dll
{
var unityPath = Path.Combine(managedPath,
@@ -234,65 +234,63 @@ namespace IPA.Injector
CriticalSection.ExitExecuteSection();
}
-#endregion Insert patch into UnityEngine.CoreModule.dll
+ #endregion Insert patch into UnityEngine.CoreModule.dll
- loader.Debug("Ensuring Assembly-CSharp is virtualized");
-
+ loader.Debug("Ensuring game assemblies are virtualized");
+
+ #region Virtualize game assemblies
+ bool isFirst = true;
+ foreach(var name in SelfConfig.GameAssemblies_)
{
- var ascPath = Path.Combine(managedPath,
- "MainAssembly.dll"); // TODO: change to config option for other games
+ var ascPath = Path.Combine(managedPath, name);
-#region Virtualize Assembly-CSharp.dll
+ CriticalSection.EnterExecuteSection();
+ try
{
- CriticalSection.EnterExecuteSection();
+ loader.Debug($"Virtualizing {name}");
+ using var ascModule = VirtualizedModule.Load(ascPath);
+ ascModule.Virtualize(cAsmName, () => bkp?.Add(ascPath));
+ }
+ catch (Exception e)
+ {
+ loader.Error($"Could not virtualize {ascPath}");
+ if (SelfConfig.Debug_.ShowHandledErrorStackTraces_)
+ loader.Error(e);
+ }
+ if (isFirst)
+ {
try
{
- var ascModule = VirtualizedModule.Load(ascPath);
- ascModule.Virtualize(cAsmName, () => bkp?.Add(ascPath));
- }
- catch (Exception e)
- {
- loader.Error($"Could not virtualize {ascPath}");
- loader.Error(e);
- }
-
- CriticalSection.ExitExecuteSection();
- }
+ loader.Debug("Applying anti-yeet patch");
-#endregion Virtualize Assembly-CSharp.dll
+ var ascAsmDef = AssemblyDefinition.ReadAssembly(ascPath, new ReaderParameters
+ {
+ ReadWrite = false,
+ InMemory = true,
+ ReadingMode = ReadingMode.Immediate
+ });
+ var ascModDef = ascAsmDef.MainModule;
-#region Anti-Yeet
+ var deleter = ascModDef.GetType("IPAPluginsDirDeleter");
+ deleter.Methods.Clear(); // delete all methods
- CriticalSection.EnterExecuteSection();
+ ascAsmDef.Write(ascPath);
- try
- {
- loader.Debug("Applying anti-yeet patch");
-
- var ascAsmDef = AssemblyDefinition.ReadAssembly(ascPath, new ReaderParameters
+ isFirst = false;
+ }
+ catch (Exception e)
{
- ReadWrite = false,
- InMemory = true,
- ReadingMode = ReadingMode.Immediate
- });
- var ascModDef = ascAsmDef.MainModule;
-
- var deleter = ascModDef.GetType("IPAPluginsDirDeleter");
- deleter.Methods.Clear(); // delete all methods
-
- ascAsmDef.Write(ascPath);
- }
- catch (Exception)
- {
- // ignore
+ loader.Warn($"Could not apply anti-yeet patch to {ascPath}");
+ if (SelfConfig.Debug_.ShowHandledErrorStackTraces_)
+ loader.Warn(e);
+ }
}
CriticalSection.ExitExecuteSection();
-
-#endregion
}
+ #endregion
}
private static bool bootstrapped;
diff --git a/IPA.Injector/Virtualizer.cs b/IPA.Injector/Virtualizer.cs
index 9afa0686..61e9aeac 100644
--- a/IPA.Injector/Virtualizer.cs
+++ b/IPA.Injector/Virtualizer.cs
@@ -5,7 +5,7 @@ using System.Reflection;
namespace IPA.Injector
{
- internal class VirtualizedModule
+ internal class VirtualizedModule : IDisposable
{
private readonly FileInfo file;
private ModuleDefinition module;
@@ -31,15 +31,7 @@ namespace IPA.Injector
ReadingMode = ReadingMode.Immediate
});
}
-
- ~VirtualizedModule()
- {
- module?.Dispose();
- }
- ///
- ///
- ///
public void Virtualize(AssemblyName selfName, Action beforeChangeCallback = null)
{
var changed = false;
@@ -121,5 +113,36 @@ namespace IPA.Injector
if (field.IsPrivate) field.IsFamily = true;
}
}
+
+ #region IDisposable Support
+ private bool disposedValue = false; // To detect redundant calls
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ module.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ ~VirtualizedModule()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose(false);
+ }
+
+ // This code added to correctly implement the disposable pattern.
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
}
}
diff --git a/IPA.Loader/Config/SelfConfig.cs b/IPA.Loader/Config/SelfConfig.cs
index dc27155b..8dbf320b 100644
--- a/IPA.Loader/Config/SelfConfig.cs
+++ b/IPA.Loader/Config/SelfConfig.cs
@@ -3,8 +3,10 @@ using IPA.Logging;
using IPA.Utilities;
using IPA.Config.Stores;
using IPA.Config.Stores.Attributes;
+using IPA.Config.Stores.Converters;
// END: section ignore
using Newtonsoft.Json;
+using System.Collections.Generic;
namespace IPA.Config
{
@@ -136,6 +138,21 @@ namespace IPA.Config
public static bool YeetMods_ => (Instance?.YeetMods ?? true)
&& CommandLineValues.YeetMods;
+ // LINE: ignore
+ [NonNullable, UseConverter(typeof(CollectionConverter>))]
+ [JsonProperty(Required = Required.DisallowNull)]
+ public virtual HashSet GameAssemblies { get; set; } = new HashSet
+ {
+ // LINE: ignore 5
+#if BeatSaber // provide these defaults only for Beat Saber builds
+ "MainAssembly.dll", "HMLib.dll", "HMUI.dll", "VRUI.dll"
+#else // otherwise specify Assembly-CSharp.dll
+ "Assembly-CSharp.dll"
+#endif
+ };
+ // LINE: ignore
+ public static HashSet GameAssemblies_ => Instance?.GameAssemblies ?? new HashSet { "Assembly-CSharp.dll" };
+
public virtual string LastGameVersion { get; set; } = null;
// LINE: ignore
public static string LastGameVersion_ => Instance?.LastGameVersion;
diff --git a/IPA.Loader/IPA.Loader.csproj b/IPA.Loader/IPA.Loader.csproj
index a4dec5e0..49179841 100644
--- a/IPA.Loader/IPA.Loader.csproj
+++ b/IPA.Loader/IPA.Loader.csproj
@@ -4,6 +4,7 @@
Debug
Net4
+ true
{5AD344F0-01A0-4CA8-92E5-9D095737744D}
Library
Properties
@@ -44,6 +45,9 @@
v3.5
$(DefineConstants);NET3
+
+ $(DefineConstants);BeatSaber
+
$(OutputPath)IPA.Loader.xml
diff --git a/appveyor.yml b/appveyor.yml
index dcab5753..dd65b620 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -6,6 +6,7 @@ environment:
secure: E42gl/yepETuoLSwbJZ1GmEIPK6cCJu6zkd59NA21XiICtEV6COOLW7aehi1tcVU
do_deploy: true
+ BuildForBeatSaber: 'false'
matrix:
- BUILD_DOC: 'no'
- BUILD_DOC: 'yes'
@@ -53,6 +54,12 @@ before_build:
echo $env:Configuration $env:Platform $env:BuildingInsideVisualStudio
for:
+-
+ matrix:
+ only:
+ - platform: x64-Net4
+ environment:
+ BuildForBeatSaber: 'true'
-
matrix:
except: