From 59097dbb73c0b7698b11a4dc87625d250d8e0eae Mon Sep 17 00:00:00 2001 From: ghorsington Date: Sun, 29 May 2022 00:36:04 +0300 Subject: [PATCH] Update Il2CppInterop; use new runner API --- BepInEx.IL2CPP/BepInEx.IL2CPP.csproj | 6 +- BepInEx.IL2CPP/Il2CppInteropManager.cs | 43 ++++++++---- .../Logging/BepInExLoggerProvider.cs | 68 +++++++++++++++++++ BepInEx.IL2CPP/Preloader.cs | 4 +- 4 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 BepInEx.IL2CPP/Logging/BepInExLoggerProvider.cs diff --git a/BepInEx.IL2CPP/BepInEx.IL2CPP.csproj b/BepInEx.IL2CPP/BepInEx.IL2CPP.csproj index f1c047b..46aebe2 100644 --- a/BepInEx.IL2CPP/BepInEx.IL2CPP.csproj +++ b/BepInEx.IL2CPP/BepInEx.IL2CPP.csproj @@ -26,9 +26,11 @@ - + - + + + diff --git a/BepInEx.IL2CPP/Il2CppInteropManager.cs b/BepInEx.IL2CPP/Il2CppInteropManager.cs index 04ad888..2947a17 100644 --- a/BepInEx.IL2CPP/Il2CppInteropManager.cs +++ b/BepInEx.IL2CPP/Il2CppInteropManager.cs @@ -8,14 +8,19 @@ using System.Reflection; using System.Security.Cryptography; using System.Text; using BepInEx.Configuration; +using BepInEx.IL2CPP.Logging; using BepInEx.Logging; using Cpp2IL.Core; using HarmonyLib; using Il2CppInterop.Common; using Il2CppInterop.Generator; -using Il2CppInterop.Runtime.XrefScans; +using Il2CppInterop.Generator.Runners; +using Il2CppInterop.Runtime.Startup; using LibCpp2IL; +using Microsoft.Extensions.Logging; using Mono.Cecil; +using LogLevel = Microsoft.Extensions.Logging.LogLevel; +using MSLoggerFactory = Microsoft.Extensions.Logging.LoggerFactory; namespace BepInEx.IL2CPP; @@ -46,6 +51,8 @@ internal static class Il2CppInteropManager private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("InteropManager"); + private static bool initialized; + public static string GameAssemblyPath => Path.Combine(Paths.GameRootPath, "GameAssembly.dll"); private static string HashPath => Path.Combine(IL2CPPInteropAssemblyPath, "assembly-hash.txt"); @@ -54,6 +61,12 @@ internal static class Il2CppInteropManager internal static string IL2CPPInteropAssemblyPath => Path.Combine(Paths.BepInExRootPath, "interop"); + private static ILoggerFactory LoggerFactory { get; } = MSLoggerFactory.Create(b => + { + b.AddProvider(new BepInExLoggerProvider()) + .SetMinimumLevel(LogLevel.Trace); // Each BepInEx log listener has its own filtering + }); + private static string ComputeHash() { using var md5 = MD5.Create(); @@ -130,21 +143,20 @@ internal static class Il2CppInteropManager : null; } - public static void Initialize() + public static void Initialize(Version unityVersion) { - GeneratedDatabasesUtil.DatabasesLocationOverride = IL2CPPInteropAssemblyPath; - - var interopLogger = BepInEx.Logging.Logger.CreateLogSource("Il2CppInterop"); - Il2CppInterop.Runtime.Logger.InfoHandler += s => interopLogger.LogInfo(s.Trim()); - Il2CppInterop.Runtime.Logger.WarningHandler += s => interopLogger.LogWarning(s.Trim()); - Il2CppInterop.Runtime.Logger.TraceHandler += s => interopLogger.LogDebug(s.Trim()); - Il2CppInterop.Runtime.Logger.ErrorHandler += s => interopLogger.LogError(s.Trim()); + if (initialized) + throw new InvalidOperationException("Already initialized"); + initialized = true; + Environment.SetEnvironmentVariable("IL2CPP_INTEROP_DATABASES_LOCATION", IL2CPPInteropAssemblyPath); AppDomain.CurrentDomain.AssemblyResolve += ResolveInteropAssemblies; GenerateInteropAssemblies(); - - XrefRuntimeScanner.Initialize(); + var interopLogger = LoggerFactory.CreateLogger("Il2CppInterop"); + Il2CppInteropRuntime.Create(new() { UnityVersion = unityVersion }) + .AddLogger(interopLogger) + .Start(); } private static void GenerateInteropAssemblies() @@ -205,7 +217,6 @@ internal static class Il2CppInteropManager { Logger.LogMessage("Running Cpp2IL to generate dummy assemblies"); - var metadataPath = Path.Combine(Paths.GameRootPath, $"{Paths.ProcessName}_Data", "il2cpp_data", @@ -253,7 +264,6 @@ internal static class Il2CppInteropManager Source = sourceAssemblies, OutputDir = IL2CPPInteropAssemblyPath, UnityBaseLibsDir = Directory.Exists(UnityBaseLibsDirectory) ? UnityBaseLibsDirectory : null, - NoCopyRuntimeLibs = true }; var renameMapLocation = Path.Combine(Paths.BepInExRootPath, "DeobfuscationMap.csv.gz"); @@ -265,7 +275,12 @@ internal static class Il2CppInteropManager Logger.LogInfo("Generating interop assemblies"); - InteropAssemblyGenerator.GenerateInteropAssemblies(opts); + var logger = LoggerFactory.CreateLogger("Il2CppInteropGen"); + + Il2CppInteropGenerator.Create(opts) + .AddLogger(logger) + .AddInteropAssemblyGenerator() + .Run(); sourceAssemblies.Do(x => x.Dispose()); } diff --git a/BepInEx.IL2CPP/Logging/BepInExLoggerProvider.cs b/BepInEx.IL2CPP/Logging/BepInExLoggerProvider.cs new file mode 100644 index 0000000..dca3e1c --- /dev/null +++ b/BepInEx.IL2CPP/Logging/BepInExLoggerProvider.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using BepInEx.Logging; +using Microsoft.Extensions.Logging; +using BepInExLogLevel = BepInEx.Logging.LogLevel; +using LogLevel = Microsoft.Extensions.Logging.LogLevel; + +namespace BepInEx.IL2CPP.Logging; + +internal class BepInExLoggerProvider : ILoggerProvider +{ + private readonly List loggers = new(); + + public void Dispose() + { + foreach (var bepInExLogger in loggers) + bepInExLogger.Dispose(); + loggers.Clear(); + } + + public ILogger CreateLogger(string categoryName) + { + var logger = new BepInExLogger { SourceName = categoryName }; + Logger.Sources.Add(logger); + loggers.Add(logger); + return logger; + } + + private class EmptyScope : IDisposable + { + public void Dispose() { } + } + + private class BepInExLogger : ILogSource, ILogger + { + public void Log(LogLevel logLevel, + EventId eventId, + TState state, + Exception exception, + Func formatter) => + LogEvent?.Invoke(this, + new LogEventArgs(formatter(state, exception), MSLogLevelToBepInExLogLevel(logLevel), + this)); + + public bool IsEnabled(LogLevel logLevel) => + (MSLogLevelToBepInExLogLevel(logLevel) & Logger.ListenedLogLevels) != BepInExLogLevel.None; + + public IDisposable BeginScope(TState state) => new EmptyScope(); + + public void Dispose() => Logger.Sources.Remove(this); + + public string SourceName { get; init; } + + public event EventHandler LogEvent; + + private static BepInExLogLevel MSLogLevelToBepInExLogLevel(LogLevel logLevel) => logLevel switch + { + LogLevel.Trace => BepInExLogLevel.Debug, + LogLevel.Debug => BepInExLogLevel.Debug, + LogLevel.Information => BepInExLogLevel.Info, + LogLevel.Warning => BepInExLogLevel.Warning, + LogLevel.Error => BepInExLogLevel.Error, + LogLevel.Critical => BepInExLogLevel.Fatal, + LogLevel.None => BepInExLogLevel.None, + var _ => throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null) + }; + } +} diff --git a/BepInEx.IL2CPP/Preloader.cs b/BepInEx.IL2CPP/Preloader.cs index 2f32818..3903bdd 100644 --- a/BepInEx.IL2CPP/Preloader.cs +++ b/BepInEx.IL2CPP/Preloader.cs @@ -8,7 +8,6 @@ using BepInEx.Preloader.Core; using BepInEx.Preloader.Core.Logging; using BepInEx.Preloader.Core.Patching; using BepInEx.Preloader.RuntimeFixes; -using Il2CppInterop.Runtime.Runtime; namespace BepInEx.IL2CPP; @@ -58,8 +57,7 @@ public static class Preloader Log.Log(LogLevel.Debug, $"BepInEx root path: {Paths.BepInExRootPath}"); InitializeUnityVersion(); - Il2CppInteropManager.Initialize(); - UnityVersionHandler.Initialize(UnityVersion.Major, UnityVersion.Minor, UnityVersion.Build); + Il2CppInteropManager.Initialize(UnityVersion); using (var assemblyPatcher = new AssemblyPatcher()) {