mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
Automatically load all interop assemblies before loading plugins (#777)
Assemblies are often loaded on the il2cpp side but not on the mono side, causing confusion when using reflection. This will load all interop assemblies right before plugins are loaded, which should mostly avoid these issues at a low time cost of around 40ms.
This commit is contained in:
1 parent
2a61b61497
commit
cbd70eb2f0
2 files changed
+40
No files matched your search
@@ -97,6 +97,8 @@ public class IL2CPPChainloader : BaseChainloader<BasePlugin>
|
||||
|
||||
unhook = true;
|
||||
|
||||
Il2CppInteropManager.PreloadInteropAssemblies();
|
||||
|
||||
Instance.Execute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -8,6 +8,8 @@ using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BepInEx.Configuration;
|
||||
using BepInEx.Logging;
|
||||
using BepInEx.Unity.Common;
|
||||
@@ -88,6 +90,14 @@ internal static partial class Il2CppInteropManager
|
||||
.AppendLine("{BepInEx} - Path to the BepInEx folder.")
|
||||
.AppendLine("{ProcessName} - Name of the current process")
|
||||
.ToString());
|
||||
|
||||
private static readonly ConfigEntry<bool> PreloadIL2CPPInteropAssemblies = ConfigFile.CoreConfig.Bind(
|
||||
"IL2CPP", "PreloadIL2CPPInteropAssemblies",
|
||||
true,
|
||||
new StringBuilder()
|
||||
.AppendLine("Automatically load all interop assemblies right before loading plugins.")
|
||||
.AppendLine("Some plugins may not work properly without this, but it may cause issues in some games.")
|
||||
.ToString());
|
||||
|
||||
private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("InteropManager");
|
||||
|
||||
@@ -357,4 +367,32 @@ internal static partial class Il2CppInteropManager
|
||||
|
||||
sourceAssemblies.Do(x => x.Dispose());
|
||||
}
|
||||
|
||||
internal static void PreloadInteropAssemblies()
|
||||
{
|
||||
if (!PreloadIL2CPPInteropAssemblies.Value)
|
||||
return;
|
||||
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
var files = Directory.EnumerateFiles(IL2CPPInteropAssemblyPath);
|
||||
var loaded = 0;
|
||||
Parallel.ForEach(files, file =>
|
||||
{
|
||||
if (!file.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) return;
|
||||
if (file.Equals("netstandard.dll", StringComparison.OrdinalIgnoreCase)) return;
|
||||
if (file.Equals("Il2Cppnetstandard.dll", StringComparison.OrdinalIgnoreCase)) return;
|
||||
try
|
||||
{
|
||||
Assembly.LoadFrom(file);
|
||||
Interlocked.Increment(ref loaded);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogWarning($"Failed to preload {file} - {e}");
|
||||
}
|
||||
});
|
||||
|
||||
Logger.LogDebug($"Preloaded {loaded} interop assemblies in {sw.ElapsedMilliseconds}ms");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user