Browse Source

First doorstop prototype integration
Code is messy, please do not bully

Bepis 3 years ago
parent
commit
f737a3e53c

+ 0 - 5
BepInEx.Core/Bootstrap/BaseChainloader.cs

@@ -23,11 +23,6 @@ namespace BepInEx.Bootstrap
 
 		public List<string> DependencyErrors { get; } = new List<string>();
 
-		//protected BaseChainloader()
-		//{
-		//	Plugins = new ReadOnlyCollection<TPlugin>(_plugins);
-		//}
-
 		public virtual void Initialize(string gameExePath = null)
 		{
 			if (_initialized)

+ 5 - 2
BepInEx.Core/ConsoleUtil/ConsoleWindow.cs

@@ -47,8 +47,11 @@ namespace UnityInjector.ConsoleUtil
 				throw new Exception("SetStdHandle() failed");
 
 
-			var originalOutStream = new FileStream(new SafeFileHandle(_oOut, false), FileAccess.Write);
-			OriginalOut = new StreamWriter(originalOutStream, new UTF8Encoding(false));
+#warning Fix OriginalOut
+
+			//var originalOutStream = new FileStream(new SafeFileHandle(_oOut, false), FileAccess.Write);
+			//OriginalOut = new StreamWriter(originalOutStream, new UTF8Encoding(false));
+			OriginalOut = TextWriter.Null;
 
 			Init();
 

+ 28 - 0
BepInEx.IL2CPP/BasePlugin.cs

@@ -0,0 +1,28 @@
+using BepInEx.Configuration;
+using BepInEx.Logging;
+
+namespace BepInEx.IL2CPP
+{
+	public abstract class BasePlugin
+	{
+		public ManualLogSource Log { get; }
+
+		public ConfigFile Config { get; }
+
+		protected BasePlugin()
+		{
+			var metadata = MetadataHelper.GetMetadata(this);
+
+			Log = Logger.CreateLogSource(metadata.Name);
+
+			Config = new ConfigFile(Utility.CombinePaths(Paths.ConfigPath, metadata.GUID + ".cfg"), false, metadata);
+		}
+
+		public abstract void Load();
+
+		public virtual bool Unload()
+		{
+			return false;
+		}
+	}
+}

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

@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{429D5F83-7FEC-4D09-AB82-E868EB61AF59}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>BepInEx.IL2CPP</RootNamespace>
+    <AssemblyName>BepInEx.IL2CPP</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Deterministic>true</Deterministic>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\il2cpp\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\il2cpp\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Il2Cppmscorlib">
+      <HintPath>..\lib\Il2Cppmscorlib.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Mono.Cecil, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil.Mdb, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.Mdb.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil.Pdb, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.Pdb.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil.Rocks, Version=0.11.2.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.11.2\lib\net40\Mono.Cecil.Rocks.dll</HintPath>
+    </Reference>
+    <Reference Include="MonoMod.RuntimeDetour, Version=20.5.21.5, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\MonoMod.RuntimeDetour.20.5.21.5\lib\net40\MonoMod.RuntimeDetour.dll</HintPath>
+    </Reference>
+    <Reference Include="MonoMod.Utils, Version=20.5.21.5, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\MonoMod.Utils.20.5.21.5\lib\net40\MonoMod.Utils.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="UnhollowerBaseLib">
+      <HintPath>..\lib\UnhollowerBaseLib.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="UnhollowerRuntimeLib">
+      <HintPath>..\lib\UnhollowerRuntimeLib.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="UnityEngine-IL2CPP">
+      <HintPath>..\lib\UnityEngine-IL2CPP.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="UnityEngine.CoreModule-IL2CPP">
+      <HintPath>..\lib\UnityEngine.CoreModule-IL2CPP.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BasePlugin.cs" />
+    <Compile Include="DoorstopEntrypoint.cs" />
+    <Compile Include="EnvVars.cs" />
+    <Compile Include="IL2CPPChainloader.cs" />
+    <Compile Include="Preloader.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\BepInEx.Core\BepInEx.Core.csproj">
+      <Project>{4ffba620-f5ed-47f9-b90c-dad1316fd9b9}</Project>
+      <Name>BepInEx.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\BepInEx.Preloader.Core\BepInEx.Preloader.Core.csproj">
+      <Project>{15f8bc38-a761-4f93-8903-1b531ac5d9f9}</Project>
+      <Name>BepInEx.Preloader.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\submodules\BepInEx.Harmony\BepInEx.Harmony\BepInEx.Harmony.csproj">
+      <Project>{54161cfe-ff42-4dde-b161-3a49545db5cd}</Project>
+      <Name>BepInEx.Harmony</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 92 - 0
BepInEx.IL2CPP/DoorstopEntrypoint.cs

@@ -0,0 +1,92 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace BepInEx.IL2CPP
+{
+	internal static class UnityPreloaderRunner
+	{
+		public static void PreloaderMain(string[] args)
+		{
+			string bepinPath = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetFullPath(EnvVars.DOORSTOP_INVOKE_DLL_PATH)));
+
+			Paths.SetExecutablePath(EnvVars.DOORSTOP_PROCESS_PATH, bepinPath);
+			Preloader.IL2CPPUnhollowedPath = Path.Combine(Paths.BepInExRootPath, "unhollowed");
+
+			AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
+			AppDomain.CurrentDomain.AssemblyResolve -= DoorstopEntrypoint.ResolveCurrentDirectory;
+
+			Preloader.Run();
+		}
+
+		private static Assembly LocalResolve(object sender, ResolveEventArgs args)
+		{
+			var assemblyName = new AssemblyName(args.Name);
+
+			var foundAssembly = AppDomain.CurrentDomain.GetAssemblies()
+										 .FirstOrDefault(x => x.GetName().Name == assemblyName.Name);
+
+			if (foundAssembly != null)
+				return foundAssembly;
+
+			if (Utility.TryResolveDllAssembly(assemblyName, Paths.BepInExAssemblyDirectory, out foundAssembly)
+				|| Utility.TryResolveDllAssembly(assemblyName, Paths.PatcherPluginPath, out foundAssembly)
+				|| Utility.TryResolveDllAssembly(assemblyName, Paths.PluginPath, out foundAssembly)
+				|| Utility.TryResolveDllAssembly(assemblyName, Preloader.IL2CPPUnhollowedPath, out foundAssembly))
+				return foundAssembly;
+
+			return null;
+		}
+	}
+
+	internal static class DoorstopEntrypoint
+	{
+		private static string preloaderPath;
+
+		/// <summary>
+		///     The main entrypoint of BepInEx, called from Doorstop.
+		/// </summary>
+		/// <param name="args">
+		///     The arguments passed in from Doorstop. First argument is the path of the currently executing
+		///     process.
+		/// </param>
+		public static void Main(string[] args)
+		{
+			// We set it to the current directory first as a fallback, but try to use the same location as the .exe file.
+			string silentExceptionLog = $"preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log";
+
+			try
+			{
+				EnvVars.LoadVars();
+
+				silentExceptionLog = Path.Combine(Path.GetDirectoryName(EnvVars.DOORSTOP_PROCESS_PATH), silentExceptionLog);
+
+				// Get the path of this DLL via Doorstop env var because Assembly.Location mangles non-ASCII characters on some versions of Mono for unknown reasons
+				preloaderPath = Path.GetDirectoryName(Path.GetFullPath(EnvVars.DOORSTOP_INVOKE_DLL_PATH));
+
+				AppDomain.CurrentDomain.AssemblyResolve += ResolveCurrentDirectory;
+
+				UnityPreloaderRunner.PreloaderMain(args);
+			}
+			catch (Exception ex)
+			{
+				File.WriteAllText(silentExceptionLog, ex.ToString());
+			}
+		}
+
+		public static Assembly ResolveCurrentDirectory(object sender, ResolveEventArgs args)
+		{
+			var name = new AssemblyName(args.Name);
+
+			try
+			{
+				return Assembly.LoadFile(Path.Combine(preloaderPath, $"{name.Name}.dll"));
+			}
+			catch (Exception)
+			{
+				return null;
+			}
+		}
+	}
+}

+ 33 - 0
BepInEx.IL2CPP/EnvVars.cs

@@ -0,0 +1,33 @@
+using System;
+
+namespace BepInEx.IL2CPP
+{
+	/// <summary>
+	/// Doorstop environment variables, passed into the BepInEx preloader.
+	/// <para>https://github.com/NeighTools/UnityDoorstop/wiki#environment-variables</para>
+	/// </summary>
+	internal static class EnvVars
+	{
+		/// <summary>
+		/// Path to the assembly that was invoked via Doorstop. Contains the same value as in "targetAssembly" configuration option in the config file.
+		/// </summary>
+		public static string DOORSTOP_INVOKE_DLL_PATH { get; private set; }
+
+		/// <summary>
+		/// Full path to the game's "Managed" folder that contains all the game's managed assemblies
+		/// </summary>
+		public static string DOORSTOP_MANAGED_FOLDER_DIR { get; private set; }
+
+		/// <summary>
+		/// Full path to the game's executable.
+		/// </summary>
+		public static string DOORSTOP_PROCESS_PATH { get; private set; }
+
+		internal static void LoadVars()
+		{
+			DOORSTOP_INVOKE_DLL_PATH = Environment.GetEnvironmentVariable("DOORSTOP_INVOKE_DLL_PATH");
+			DOORSTOP_MANAGED_FOLDER_DIR = Environment.GetEnvironmentVariable("DOORSTOP_MANAGED_FOLDER_DIR");
+			DOORSTOP_PROCESS_PATH = Environment.GetEnvironmentVariable("DOORSTOP_PROCESS_PATH");
+		}
+	}
+}

+ 109 - 0
BepInEx.IL2CPP/IL2CPPChainloader.cs

@@ -0,0 +1,109 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using BepInEx.Bootstrap;
+using BepInEx.Logging;
+using BepInEx.Preloader.Core;
+using BepInEx.Preloader.Core.Logging;
+using MonoMod.RuntimeDetour;
+using MonoMod.Utils;
+using UnhollowerBaseLib.Runtime;
+using UnhollowerRuntimeLib;
+using UnityEngine;
+using Logger = BepInEx.Logging.Logger;
+
+namespace BepInEx.IL2CPP
+{
+	public class IL2CPPChainloader : BaseChainloader<BasePlugin>
+	{
+		private static ManualLogSource UnityLogSource = new ManualLogSource("Unity");
+
+		[UnmanagedFunctionPointer(CallingConvention.StdCall)]
+		private delegate void UnityLogCallbackDelegate([In] [MarshalAs(UnmanagedType.LPStr)] string log);
+		private static void UnityLogCallback([In] [MarshalAs(UnmanagedType.LPStr)] string log)
+		{
+			UnityLogSource.LogInfo(log.Trim());
+		}
+
+		[UnmanagedFunctionPointer(CallingConvention.StdCall)]
+		private delegate IntPtr RuntimeInvokeDetour(IntPtr method, IntPtr obj, IntPtr parameters, IntPtr exc);
+
+		public unsafe IL2CPPChainloader()
+		{
+			ClassInjector.DoHook = (ptr, intPtr) =>
+			{
+				var detour = new NativeDetour(new IntPtr(*((int**)ptr)), intPtr);
+				detour.Apply();
+			};
+
+			var gameAssemblyModule = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().First(x => x.FileName.Contains("GameAssembly"));
+			var functionPtr = DynDll.GetFunction(gameAssemblyModule.BaseAddress, "il2cpp_runtime_invoke");
+
+			RuntimeInvokeDetour originalInvoke = null;
+			RuntimeInvokeDetour invokeHook = (method, obj, parameters, exc) =>
+			{
+				UnityLogSource.LogInfo(Marshal.PtrToStringAnsi(UnhollowerBaseLib.IL2CPP.il2cpp_method_get_name(method)));
+				return originalInvoke(method, obj, parameters, exc);
+			};
+
+			var invokeDetour = new NativeDetour(functionPtr, Marshal.GetFunctionPointerForDelegate(invokeHook), new NativeDetourConfig {ManualApply = true});
+
+			originalInvoke = invokeDetour.GenerateTrampoline<RuntimeInvokeDetour>();
+
+			invokeDetour.Apply();
+
+
+			//UnityVersionHandler.Initialize(2019, 3, 15);
+		}
+
+		protected override void InitializeLoggers()
+		{
+			//Logger.Listeners.Add(new UnityLogListener());
+
+			//if (ConfigUnityLogging.Value)
+			//	Logger.Sources.Add(new UnityLogSource());
+
+			Logger.Sources.Add(UnityLogSource);
+
+
+			ManualLogSource unhollowerLogSource = Logger.CreateLogSource("Unhollower");
+
+			UnhollowerBaseLib.LogSupport.InfoHandler += s => unhollowerLogSource.LogInfo(s);
+			UnhollowerBaseLib.LogSupport.WarningHandler += s => unhollowerLogSource.LogWarning(s);
+			UnhollowerBaseLib.LogSupport.TraceHandler += s => unhollowerLogSource.LogDebug(s);
+			UnhollowerBaseLib.LogSupport.ErrorHandler += s => unhollowerLogSource.LogError(s);
+
+			base.InitializeLoggers();
+
+
+			//if (!ConfigDiskWriteUnityLog.Value)
+			//{
+			//	DiskLogListener.BlacklistedSources.Add("Unity Log");
+			//}
+
+
+			foreach (var preloaderLogEvent in PreloaderConsoleListener.LogEvents)
+			{
+				PreloaderLogger.Log.Log(preloaderLogEvent.Level, preloaderLogEvent.Data);
+			}
+
+			//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);
+		}
+
+		public override BasePlugin LoadPlugin(PluginInfo pluginInfo, Assembly pluginAssembly)
+		{
+			var type = pluginAssembly.GetType(pluginInfo.TypeName);
+
+			var pluginInstance = (BasePlugin)Activator.CreateInstance(type);
+
+			pluginInstance.Load();
+
+			return pluginInstance;
+		}
+	}
+}

+ 46 - 0
BepInEx.IL2CPP/Preloader.cs

@@ -0,0 +1,46 @@
+using System.Diagnostics;
+using BepInEx.Logging;
+using BepInEx.Preloader.Core;
+using BepInEx.Preloader.Core.Logging;
+
+namespace BepInEx.IL2CPP
+{
+	public static class Preloader
+	{
+		public static string IL2CPPUnhollowedPath { get; internal set; }
+
+		private static PreloaderConsoleListener PreloaderLog { get; set; }
+
+		private static ManualLogSource Log => PreloaderLogger.Log;
+
+		public static IL2CPPChainloader Chainloader { get; private set; }
+
+		public static void Run()
+		{
+			PreloaderLog = new PreloaderConsoleListener(false);
+			Logger.Listeners.Add(PreloaderLog);
+
+
+			BasicLogInfo.PrintLogInfo(Log);
+
+
+
+			Log.LogInfo($"Running under Unity v{FileVersionInfo.GetVersionInfo(Paths.ExecutablePath).FileVersion}");
+			//Log.LogInfo($"CLR runtime version: {Environment.Version}");
+			//Log.LogInfo($"Supports SRE: {Utility.CLRSupportsDynamicAssemblies}");
+
+			Log.LogDebug($"Game executable path: {Paths.ExecutablePath}");
+			Log.LogDebug($"Unhollowed assembly directory: {IL2CPPUnhollowedPath}");
+			Log.LogDebug($"BepInEx root path: {Paths.BepInExRootPath}");
+
+			Logger.Listeners.Remove(PreloaderLog);
+
+
+			Chainloader = new IL2CPPChainloader();
+
+			Chainloader.Initialize();
+
+			Chainloader.Execute();
+		}
+	}
+}

+ 36 - 0
BepInEx.IL2CPP/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("BepInEx.IL2CPP")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BepInEx.IL2CPP")]
+[assembly: AssemblyCopyright("Copyright ©  2020")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("429d5f83-7fec-4d09-ab82-e868eb61af59")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 11 - 0
BepInEx.IL2CPP/app.config

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Mono.Cecil" publicKeyToken="50cebf1cceb9d05e" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-0.11.2.0" newVersion="0.11.2.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>

+ 6 - 0
BepInEx.IL2CPP/packages.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Mono.Cecil" version="0.11.2" targetFramework="net472" />
+  <package id="MonoMod.RuntimeDetour" version="20.5.21.5" targetFramework="net472" />
+  <package id="MonoMod.Utils" version="20.5.21.5" targetFramework="net472" />
+</packages>

+ 2 - 7
BepInEx.NetLauncher/RuntimeFixes/AssemblyFix.cs

@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
+using System.Reflection;
 using BepInEx.Harmony;
 using HarmonyLib;
 
@@ -26,4 +21,4 @@ namespace BepInEx.NetLauncher.RuntimeFixes
 			return false;
 		}
 	}
-}
+}

+ 3 - 2
BepInEx.Preloader.Core/BepInEx.Preloader.Core.csproj

@@ -36,6 +36,7 @@
     <Reference Include="System.Core" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Logging\BasicLogInfo.cs" />
     <Compile Include="Logging\PreloaderLogWriter.cs" />
     <Compile Include="Patching\AssemblyPatcher.cs" />
     <Compile Include="Patching\PatcherPlugin.cs" />
@@ -61,10 +62,10 @@
       <Version>0.10.4</Version>
     </PackageReference>
     <PackageReference Include="MonoMod.RuntimeDetour">
-      <Version>20.4.3.1</Version>
+      <Version>20.5.21.5</Version>
     </PackageReference>
     <PackageReference Include="MonoMod.Utils">
-      <Version>20.4.3.1</Version>
+      <Version>20.5.21.5</Version>
     </PackageReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

+ 26 - 0
BepInEx.Preloader.Core/Logging/BasicLogInfo.cs

@@ -0,0 +1,26 @@
+using System.Diagnostics;
+using BepInEx.Logging;
+
+namespace BepInEx.Preloader.Core.Logging
+{
+	public static class BasicLogInfo
+	{
+		public static void PrintLogInfo(ManualLogSource log)
+		{
+			string consoleTile = $"BepInEx {typeof(Paths).Assembly.GetName().Version} - {Process.GetCurrentProcess().ProcessName}";
+			log.LogMessage(consoleTile);
+
+			if (ConsoleManager.ConsoleActive)
+				ConsoleManager.SetConsoleTitle(consoleTile);
+
+			//See BuildInfoAttribute for more information about this section.
+			object[] attributes = typeof(BuildInfoAttribute).Assembly.GetCustomAttributes(typeof(BuildInfoAttribute), false);
+
+			if (attributes.Length > 0)
+			{
+				var attribute = (BuildInfoAttribute)attributes[0];
+				log.LogMessage(attribute.Info);
+			}
+		}
+	}
+}

+ 0 - 1
BepInEx.Preloader.Core/Logging/PreloaderLogWriter.cs

@@ -2,7 +2,6 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
-using BepInEx.ConsoleUtil;
 using BepInEx.Logging;
 
 namespace BepInEx.Preloader.Core.Logging

+ 1 - 14
BepInEx.Preloader.Unity/UnityPreloader.cs

@@ -65,20 +65,7 @@ namespace BepInEx.Preloader.Unity
 				PreloaderLog = new PreloaderConsoleListener(ConfigPreloaderCOutLogging.Value);
 				Logger.Listeners.Add(PreloaderLog);
 
-				string consoleTile = $"BepInEx {typeof(Paths).Assembly.GetName().Version} - {Process.GetCurrentProcess().ProcessName}";
-				Log.LogMessage(consoleTile);
-
-				if (ConsoleManager.ConsoleActive)
-					ConsoleManager.SetConsoleTitle(consoleTile);
-				
-				//See BuildInfoAttribute for more information about this section.
-				object[] attributes = typeof(BuildInfoAttribute).Assembly.GetCustomAttributes(typeof(BuildInfoAttribute), false);
-
-				if (attributes.Length > 0)
-				{
-					var attribute = (BuildInfoAttribute)attributes[0];
-					Log.LogMessage(attribute.Info);
-				}
+				BasicLogInfo.PrintLogInfo(Log);
 
 				Log.LogInfo($"Running under Unity v{FileVersionInfo.GetVersionInfo(Paths.ExecutablePath).FileVersion}");
 				Log.LogInfo($"CLR runtime version: {Environment.Version}");

+ 13 - 0
BepInEx.sln

@@ -36,6 +36,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.NetLauncher", "BepI
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NetFramework", "NetFramework", "{6EC98884-A3DC-4828-85EF-5F10F7519429}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IL2CPP", "IL2CPP", "{D5F47CFC-E4F3-46EE-B4F3-2474CF7D9E2C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.IL2CPP", "BepInEx.IL2CPP\BepInEx.IL2CPP.csproj", "{429D5F83-7FEC-4D09-AB82-E868EB61AF59}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -106,6 +110,14 @@ Global
 		{490B052B-7F23-4052-AD04-613856618901}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
 		{490B052B-7F23-4052-AD04-613856618901}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{490B052B-7F23-4052-AD04-613856618901}.Release|Any CPU.Build.0 = Release|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release_NetFramework|Any CPU.ActiveCfg = Release|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release_NetFramework|Any CPU.Build.0 = Release|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release_Unity|Any CPU.ActiveCfg = Release|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release_Unity|Any CPU.Build.0 = Release|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -117,6 +129,7 @@ Global
 		{EAE9FAE6-8011-45A3-8B6E-0C7F14210533} = {6E2DD21E-0854-4F4A-B925-D90E0016D03D}
 		{D404C973-441D-48ED-B266-C21320BA0D87} = {6E2DD21E-0854-4F4A-B925-D90E0016D03D}
 		{490B052B-7F23-4052-AD04-613856618901} = {6EC98884-A3DC-4828-85EF-5F10F7519429}
+		{429D5F83-7FEC-4D09-AB82-E868EB61AF59} = {D5F47CFC-E4F3-46EE-B4F3-2474CF7D9E2C}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {55AC11EF-F568-4C79-A356-7ED9510145B1}

BIN
lib/Il2Cppmscorlib.dll


BIN
lib/UnhollowerBaseLib.dll


BIN
lib/UnhollowerRuntimeLib.dll


BIN
lib/UnityEngine-IL2CPP.dll


BIN
lib/UnityEngine.CoreModule-IL2CPP.dll