diff --git a/Runtimes/Unity/BepInEx.Unity.IL2CPP/BepInEx.Unity.IL2CPP.csproj b/Runtimes/Unity/BepInEx.Unity.IL2CPP/BepInEx.Unity.IL2CPP.csproj
index 9dca287..333ab54 100644
--- a/Runtimes/Unity/BepInEx.Unity.IL2CPP/BepInEx.Unity.IL2CPP.csproj
+++ b/Runtimes/Unity/BepInEx.Unity.IL2CPP/BepInEx.Unity.IL2CPP.csproj
@@ -14,7 +14,7 @@
-
+
@@ -22,7 +22,7 @@
-
+
diff --git a/Runtimes/Unity/BepInEx.Unity.IL2CPP/Il2CppInteropManager.AsmToCecilConverter.cs b/Runtimes/Unity/BepInEx.Unity.IL2CPP/Il2CppInteropManager.AsmToCecilConverter.cs
new file mode 100644
index 0000000..05855bb
--- /dev/null
+++ b/Runtimes/Unity/BepInEx.Unity.IL2CPP/Il2CppInteropManager.AsmToCecilConverter.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Mono.Cecil;
+
+namespace BepInEx.Unity.IL2CPP;
+
+internal static partial class Il2CppInteropManager
+{
+ private sealed class AsmToCecilConverter : IAssemblyResolver
+ {
+ private readonly Dictionary asmResolverDictionary;
+ private readonly Dictionary cecilDictionary = new();
+ private readonly Dictionary asmToCecil = new();
+ public AsmToCecilConverter(List list)
+ {
+ asmResolverDictionary = list.ToDictionary(a => a.Name?.ToString(), a => a);
+ }
+
+ public void Dispose() { }
+ public AssemblyDefinition Resolve(AssemblyNameReference name) => Resolve(name, new() { AssemblyResolver = this });
+ public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
+ {
+ var assemblyName = name.Name;
+ if (!cecilDictionary.TryGetValue(assemblyName, out var cecilAssembly) && asmResolverDictionary.TryGetValue(assemblyName, out var asmAssembly))
+ {
+ cecilAssembly = Convert(asmAssembly, parameters);
+ }
+ return cecilAssembly;
+ }
+
+ public List ConvertAll()
+ {
+ List cecilAssemblies = new(asmResolverDictionary.Count);
+ foreach (var asmResolverAssembly in asmResolverDictionary.Values)
+ {
+ var cecilAssembly = Convert(asmResolverAssembly);
+ cecilAssemblies.Add(cecilAssembly);
+ }
+ return cecilAssemblies;
+ }
+
+ private AssemblyDefinition Convert(AsmResolver.DotNet.AssemblyDefinition asmResolverAssembly)
+ {
+ return Convert(asmResolverAssembly, new ReaderParameters() { AssemblyResolver = this });
+ }
+
+ private AssemblyDefinition Convert(AsmResolver.DotNet.AssemblyDefinition asmResolverAssembly, ReaderParameters readerParameters)
+ {
+ if (asmToCecil.TryGetValue(asmResolverAssembly, out var cecilAssembly))
+ {
+ return cecilAssembly;
+ }
+ MemoryStream stream = new();
+ asmResolverAssembly.WriteManifest(stream);
+ stream.Position = 0;
+ cecilAssembly = AssemblyDefinition.ReadAssembly(stream, readerParameters);
+ cecilDictionary.Add(cecilAssembly.Name.Name, cecilAssembly);
+ asmToCecil.Add(asmResolverAssembly, cecilAssembly);
+ return cecilAssembly;
+ }
+ }
+}
diff --git a/Runtimes/Unity/BepInEx.Unity.IL2CPP/Il2CppInteropManager.cs b/Runtimes/Unity/BepInEx.Unity.IL2CPP/Il2CppInteropManager.cs
index 4c900f4..d6f41b6 100644
--- a/Runtimes/Unity/BepInEx.Unity.IL2CPP/Il2CppInteropManager.cs
+++ b/Runtimes/Unity/BepInEx.Unity.IL2CPP/Il2CppInteropManager.cs
@@ -14,6 +14,10 @@ using BepInEx.Unity.Common;
using BepInEx.Unity.IL2CPP.Hook;
using BepInEx.Unity.IL2CPP.Logging;
using Cpp2IL.Core;
+using Cpp2IL.Core.Api;
+using Cpp2IL.Core.InstructionSets;
+using Cpp2IL.Core.OutputFormats;
+using Cpp2IL.Core.ProcessingLayers;
using HarmonyLib;
using Il2CppInterop.Common;
using Il2CppInterop.Generator;
@@ -29,8 +33,15 @@ using MSLoggerFactory = Microsoft.Extensions.Logging.LoggerFactory;
namespace BepInEx.Unity.IL2CPP;
-internal static class Il2CppInteropManager
+internal static partial class Il2CppInteropManager
{
+ static Il2CppInteropManager()
+ {
+ InstructionSetRegistry.RegisterInstructionSet(DefaultInstructionSets.X86_32);
+ InstructionSetRegistry.RegisterInstructionSet(DefaultInstructionSets.X86_64);
+ LibCpp2IlBinaryRegistry.RegisterBuiltInBinarySupport();
+ }
+
private static readonly ConfigEntry UpdateInteropAssemblies =
ConfigFile.CoreConfig.Bind("IL2CPP",
"UpdateInteropAssemblies",
@@ -199,17 +210,18 @@ internal static class Il2CppInteropManager
AppDomain.CurrentDomain.AddCecilPlatformAssemblies(UnityBaseLibsDirectory);
DownloadUnityAssemblies();
- var dummyAssemblies = RunCpp2Il();
+ var asmResolverAssemblies = RunCpp2Il();
+ var cecilAssemblies = new AsmToCecilConverter(asmResolverAssemblies).ConvertAll();
if (DumpDummyAssemblies.Value)
{
var dummyPath = Path.Combine(Paths.BepInExRootPath, "dummy");
Directory.CreateDirectory(dummyPath);
- foreach (var assemblyDefinition in dummyAssemblies)
+ foreach (var assemblyDefinition in cecilAssemblies)
assemblyDefinition.Write(Path.Combine(dummyPath, $"{assemblyDefinition.Name.Name}.dll"));
}
- RunIl2CppInteropGenerator(dummyAssemblies);
+ RunIl2CppInteropGenerator(cecilAssemblies);
File.WriteAllText(HashPath, ComputeHash());
}
@@ -242,7 +254,7 @@ internal static class Il2CppInteropManager
}
}
- private static List RunCpp2Il()
+ private static List RunCpp2Il()
{
Logger.LogMessage("Running Cpp2IL to generate dummy assemblies");
@@ -252,40 +264,44 @@ internal static class Il2CppInteropManager
"Metadata",
"global-metadata.dat");
- List sourceAssemblies;
-
var stopwatch = new Stopwatch();
stopwatch.Start();
var cpp2IlLogger = BepInEx.Logging.Logger.CreateLogSource("Cpp2IL");
- Cpp2IL.Core.Logger.VerboseLog += (message, s) =>
+ Cpp2IL.Core.Logging.Logger.VerboseLog += (message, s) =>
cpp2IlLogger.LogDebug($"[{s}] {message.Trim()}");
- Cpp2IL.Core.Logger.InfoLog += (message, s) =>
+ Cpp2IL.Core.Logging.Logger.InfoLog += (message, s) =>
cpp2IlLogger.LogInfo($"[{s}] {message.Trim()}");
- Cpp2IL.Core.Logger.WarningLog += (message, s) =>
+ Cpp2IL.Core.Logging.Logger.WarningLog += (message, s) =>
cpp2IlLogger.LogWarning($"[{s}] {message.Trim()}");
- Cpp2IL.Core.Logger.ErrorLog += (message, s) =>
+ Cpp2IL.Core.Logging.Logger.ErrorLog += (message, s) =>
cpp2IlLogger.LogError($"[{s}] {message.Trim()}");
var unityVersion = UnityInfo.Version;
- Cpp2IlApi.InitializeLibCpp2Il(GameAssemblyPath, metadataPath, new int[]
+ Cpp2IlApi.InitializeLibCpp2Il(GameAssemblyPath, metadataPath, unityVersion, false);
+
+ List processingLayers = new() { new AttributeInjectorProcessingLayer(), };
+
+ foreach (var cpp2IlProcessingLayer in processingLayers)
{
- unityVersion.Major,
- unityVersion.Minor,
- unityVersion.Build,
- }, false);
- sourceAssemblies = Cpp2IlApi.MakeDummyDLLs();
- Cpp2IlApi.RunAttributeRestorationForAllAssemblies(null,
- LibCpp2IlMain.MetadataVersion >= 29 ||
- LibCpp2IlMain.Binary!.InstructionSet is InstructionSet.X86_32
- or InstructionSet.X86_64);
- Cpp2IlApi.DisposeAndCleanupAll();
+ cpp2IlProcessingLayer.PreProcess(Cpp2IlApi.CurrentAppContext, processingLayers);
+ }
+
+ foreach (var cpp2IlProcessingLayer in processingLayers)
+ {
+ cpp2IlProcessingLayer.Process(Cpp2IlApi.CurrentAppContext);
+ }
+
+ var assemblies = new AsmResolverDummyDllOutputFormat().BuildAssemblies(Cpp2IlApi.CurrentAppContext);
+
+ LibCpp2IlMain.Reset();
+ Cpp2IlApi.CurrentAppContext = null;
stopwatch.Stop();
Logger.LogInfo($"Cpp2IL finished in {stopwatch.Elapsed}");
- return sourceAssemblies;
+ return assemblies;
}
private static void RunIl2CppInteropGenerator(List sourceAssemblies)
diff --git a/nuget.config b/nuget.config
index 1864ded..5e67f2a 100644
--- a/nuget.config
+++ b/nuget.config
@@ -2,5 +2,6 @@
+
-
\ No newline at end of file
+