Browse Source

Reimplement Unity engine logging for IL2CPP

Bepis 3 years ago
parent
commit
54ed9fa42b

+ 1 - 0
BepInEx.Core/Properties/AssemblyInfo.cs

@@ -27,6 +27,7 @@ using BepInEx;
 [assembly: InternalsVisibleTo("BepInEx.Preloader.Core")]
 [assembly: InternalsVisibleTo("BepInEx.Unity")]
 [assembly: InternalsVisibleTo("BepInEx.NetLauncher")]
+[assembly: InternalsVisibleTo("BepInEx.IL2CPP")]
 [assembly: InternalsVisibleTo("BepInExTests")]
 
 // Version information for an assembly consists of the following four values:

+ 4 - 0
BepInEx.IL2CPP/BepInEx.IL2CPP.csproj

@@ -57,10 +57,12 @@
     <Reference Include="UnityEngine-IL2CPP">
       <HintPath>..\lib\UnityEngine-IL2CPP.dll</HintPath>
       <Private>False</Private>
+      <Aliases>il2cpp</Aliases>
     </Reference>
     <Reference Include="UnityEngine.CoreModule-IL2CPP">
       <HintPath>..\lib\UnityEngine.CoreModule-IL2CPP.dll</HintPath>
       <Private>False</Private>
+      <Aliases>il2cpp</Aliases>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -70,6 +72,8 @@
     <Compile Include="Hook\FastNativeDetour.cs" />
     <Compile Include="Hook\IL2CPPDetourMethodPatcher.cs" />
     <Compile Include="IL2CPPChainloader.cs" />
+    <Compile Include="Logging\IL2CPPUnityLogSource.cs" />
+    <Compile Include="Logging\IL2CPPLogSource.cs" />
     <Compile Include="MonoExtensions.cs" />
     <Compile Include="Preloader.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 28 - 33
BepInEx.IL2CPP/IL2CPPChainloader.cs

@@ -1,31 +1,26 @@
-using System;
+extern alias il2cpp;
+
+using System;
 using System.Diagnostics;
 using System.Linq;
 using System.Reflection;
 using System.Runtime.InteropServices;
 using BepInEx.Bootstrap;
+using BepInEx.Configuration;
 using BepInEx.IL2CPP.Hook;
+using BepInEx.IL2CPP.Logging;
 using BepInEx.Logging;
 using BepInEx.Preloader.Core;
 using BepInEx.Preloader.Core.Logging;
 using HarmonyLib.Public.Patching;
 using UnhollowerBaseLib.Runtime;
 using UnhollowerRuntimeLib;
-using UnityEngine;
-using Logger = BepInEx.Logging.Logger;
-using BaseUnityEngine = UnityEngine;
+using IL2CPPUnityEngine = il2cpp::UnityEngine;
 
 namespace BepInEx.IL2CPP
 {
 	public class IL2CPPChainloader : BaseChainloader<BasePlugin>
 	{
-		private static ManualLogSource UnityLogSource = new ManualLogSource("Unity");
-
-		public static void UnityLogCallback(string logLine, string exception, LogType type)
-		{
-			UnityLogSource.LogInfo(logLine.Trim());
-		}
-
 		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 		private delegate IntPtr RuntimeInvokeDetourDelegate(IntPtr method, IntPtr obj, IntPtr parameters, IntPtr exc);
 
@@ -95,9 +90,12 @@ namespace BepInEx.IL2CPP
 			{
 				try
 				{
-					//Application.s_LogCallbackHandler = new Action<string, string, LogType>(UnityLogCallback);
+					if (ConfigUnityLogging.Value)
+					{
+						Logger.Sources.Add(new IL2CPPUnityLogSource());
 
-					//Application.CallLogCallback("test from OnInvokeMethod", "", LogType.Log, true);
+						IL2CPPUnityEngine.Application.CallLogCallback("Test call after applying unity logging hook", "", IL2CPPUnityEngine.LogType.Assert, true);
+					}
 
 					unhook = true;
 
@@ -105,7 +103,8 @@ namespace BepInEx.IL2CPP
 				}
 				catch (Exception ex)
 				{
-					UnityLogSource.LogError(ex);
+					Logger.LogFatal("Unable to execute IL2CPP chainloader");
+					Logger.LogError(ex);
 				}
 			}
 
@@ -123,30 +122,16 @@ namespace BepInEx.IL2CPP
 
 		protected override void InitializeLoggers()
 		{
-			//Logger.Listeners.Add(new UnityLogListener());
-
-			//if (ConfigUnityLogging.Value)
-			//	Logger.Sources.Add(new UnityLogSource());
-
-			Logger.Sources.Add(UnityLogSource);
-
 			base.InitializeLoggers();
 
-
-			//if (!ConfigDiskWriteUnityLog.Value)
-			//{
-			//	DiskLogListener.BlacklistedSources.Add("Unity Log");
-			//}
-
+			if (!ConfigDiskWriteUnityLog.Value)
+			{
+				DiskLogListener.BlacklistedSources.Add("Unity");
+			}
 
 			ChainloaderLogHelper.RewritePreloaderLogs();
 
-
-			//UnityEngine.Application.s_LogCallbackHandler = DelegateSupport.ConvertDelegate<Application.LogCallback>(new Action<string>(UnityLogCallback));
-			//UnityEngine.Application.s_LogCallbackHandler = (Application.LogCallback)new Action<string>(UnityLogCallback);
-
-			//var loggerPointer = Marshal.GetFunctionPointerForDelegate(new UnityLogCallbackDelegate(UnityLogCallback));
-			//UnhollowerBaseLib.IL2CPP.il2cpp_register_log_callback(loggerPointer);
+			Logger.Sources.Add(new IL2CPPLogSource());
 		}
 
 		public override BasePlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAssembly)
@@ -159,5 +144,15 @@ namespace BepInEx.IL2CPP
 
 			return pluginInstance;
 		}
+
+		private static readonly ConfigEntry<bool> ConfigUnityLogging = ConfigFile.CoreConfig.Bind(
+			"Logging", "UnityLogListening",
+			true,
+			"Enables showing unity log messages in the BepInEx logging system.");
+
+		private static readonly ConfigEntry<bool> ConfigDiskWriteUnityLog = ConfigFile.CoreConfig.Bind(
+			"Logging.Disk", "WriteUnityLog",
+			false,
+			"Include unity log messages in log file output.");
 	}
 }

+ 28 - 0
BepInEx.IL2CPP/Logging/IL2CPPLogSource.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Runtime.InteropServices;
+using BepInEx.Logging;
+
+namespace BepInEx.IL2CPP.Logging
+{
+	public class IL2CPPLogSource : ILogSource
+	{
+		public string SourceName { get; } = "IL2CPP";
+		public event EventHandler<LogEventArgs> LogEvent;
+
+		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+		private delegate void IL2CPPLogCallbackDelegate([In][MarshalAs(UnmanagedType.LPStr)] string message);
+
+		private void IL2CPPLogCallback(string message)
+		{
+			LogEvent?.Invoke(this, new LogEventArgs(message.Trim(), LogLevel.Message, this));
+		}
+
+		public IL2CPPLogSource()
+		{
+			var loggerPointer = Marshal.GetFunctionPointerForDelegate(new IL2CPPLogCallbackDelegate(IL2CPPLogCallback));
+			UnhollowerBaseLib.IL2CPP.il2cpp_register_log_callback(loggerPointer);
+		}
+
+		public void Dispose() { }
+	}
+}

+ 47 - 0
BepInEx.IL2CPP/Logging/IL2CPPUnityLogSource.cs

@@ -0,0 +1,47 @@
+extern alias il2cpp;
+using System;
+using BepInEx.Logging;
+using il2cpp::UnityEngine;
+
+namespace BepInEx.IL2CPP.Logging
+{
+	public class IL2CPPUnityLogSource : ILogSource
+	{
+		public string SourceName { get; } = "Unity";
+
+		public event EventHandler<LogEventArgs> LogEvent;
+
+		public void UnityLogCallback(string logLine, string exception, LogType type)
+		{
+			LogLevel level = LogLevel.Message;
+
+			switch (type)
+			{
+				case LogType.Error:
+					level = LogLevel.Error;
+					break;
+				case LogType.Assert:
+					level = LogLevel.Debug;
+					break;
+				case LogType.Warning:
+					level = LogLevel.Warning;
+					break;
+				case LogType.Log:
+					level = LogLevel.Message;
+					break;
+				case LogType.Exception:
+					level = LogLevel.Error;
+					break;
+			}
+
+			LogEvent?.Invoke(this, new LogEventArgs(logLine, level, this));
+		}
+
+		public IL2CPPUnityLogSource()
+		{
+			Application.s_LogCallbackHandler = new Action<string, string, LogType>(UnityLogCallback);
+		}
+
+		public void Dispose() { }
+	}
+}