public static void Run() { try { HarmonyBackendFix.Initialize(); ConsoleManager.Initialize(false, false); PreloaderLog = new PreloaderConsoleListener(); Logger.Listeners.Add(PreloaderLog); if (ConsoleManager.ConsoleEnabled) { ConsoleManager.CreateConsole(); Logger.Listeners.Add(new ConsoleLogListener()); } ChainloaderLogHelper.PrintLogInfo(Log); Log.Log(LogLevel.Debug, $"Game executable path: {Paths.ExecutablePath}"); Log.Log(LogLevel.Debug, $"Unhollowed assembly directory: {IL2CPPUnhollowedPath}"); Log.Log(LogLevel.Debug, $"BepInEx root path: {Paths.BepInExRootPath}"); UnhollowerLog = Logger.CreateLogSource("Unhollower"); LogSupport.InfoHandler += UnhollowerLog.LogInfo; LogSupport.WarningHandler += UnhollowerLog.LogWarning; LogSupport.TraceHandler += UnhollowerLog.LogDebug; LogSupport.ErrorHandler += UnhollowerLog.LogError; InitializeUnityVersion(); if (ProxyAssemblyGenerator.CheckIfGenerationRequired()) { ProxyAssemblyGenerator.GenerateAssemblies(); } UnityVersionHandler.Initialize(UnityVersion.Major, UnityVersion.Minor, UnityVersion.Build); using (var assemblyPatcher = new AssemblyPatcher()) { assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath); Log.LogInfo($"{assemblyPatcher.PatcherContext.PatcherPlugins.Count} patcher plugin{(assemblyPatcher.PatcherContext.PatcherPlugins.Count == 1 ? "" : "s")} loaded"); assemblyPatcher.LoadAssemblyDirectories(IL2CPPUnhollowedPath); Log.LogInfo($"{assemblyPatcher.PatcherContext.PatcherPlugins.Count} assemblies discovered"); assemblyPatcher.PatchAndLoad(); } Logger.Listeners.Remove(PreloaderLog); Chainloader = new IL2CPPChainloader(); Chainloader.Initialize(); } catch (Exception ex) { Log.Log(LogLevel.Fatal, ex); throw; } }
public static void Run() { try { HarmonyBackendFix.Initialize(); ConsoleManager.Initialize(false, true); AllocateConsole(); Utility.TryDo(() => { if (ConfigApplyRuntimePatches.Value) { UnityPatches.Apply(); } }, out var runtimePatchException); Logger.Sources.Add(new HarmonyLogSource()); Logger.Sources.Add(TraceLogSource.CreateSource()); PreloaderLog = new PreloaderConsoleListener(); Logger.Listeners.Add(PreloaderLog); ChainloaderLogHelper.PrintLogInfo(Log); Log.Log(LogLevel.Info, $"Running under Unity v{GetUnityVersion()}"); Log.Log(LogLevel.Info, $"CLR runtime version: {Environment.Version}"); Log.Log(LogLevel.Info, $"Supports SRE: {Utility.CLRSupportsDynamicAssemblies}"); Log.Log(LogLevel.Debug, $"Game executable path: {Paths.ExecutablePath}"); Log.Log(LogLevel.Debug, $"Unity Managed directory: {Paths.ManagedPath}"); Log.Log(LogLevel.Debug, $"BepInEx root path: {Paths.BepInExRootPath}"); if (runtimePatchException != null) { Log.Log(LogLevel.Warning, $"Failed to apply runtime patches for Mono. See more info in the output log. Error message: {runtimePatchException.Message}"); } Log.Log(LogLevel.Message, "Preloader started"); TypeLoader.SearchDirectories.UnionWith(Paths.DllSearchPaths); using (var assemblyPatcher = new AssemblyPatcher()) { assemblyPatcher.AddPatchersFromDirectory(Paths.BepInExAssemblyDirectory); assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath); Log.Log(LogLevel.Info, $"{assemblyPatcher.PatcherContext.PatcherPlugins.Count} patcher plugin{(assemblyPatcher.PatcherContext.PatcherPlugins.Count == 1 ? "" : "s")} loaded"); assemblyPatcher.LoadAssemblyDirectories(Paths.DllSearchPaths); Log.Log(LogLevel.Info, $"{assemblyPatcher.PatcherContext.AvailableAssemblies.Count} assemblies discovered"); assemblyPatcher.PatchAndLoad(); } Log.Log(LogLevel.Message, "Preloader finished"); Logger.Listeners.Remove(PreloaderLog); PreloaderLog.Dispose(); } catch (Exception ex) { try { Log.Log(LogLevel.Fatal, "Could not run preloader!"); Log.Log(LogLevel.Fatal, ex); if (!ConsoleManager.ConsoleActive) { //if we've already attached the console, then the log will already be written to the console AllocateConsole(); Console.Write(PreloaderLog); } } catch { } var log = string.Empty; try { // We could use platform-dependent newlines, however the developers use Windows so this will be easier to read :) log = string.Join("\r\n", PreloaderConsoleListener.LogEvents.Select(x => x.ToString()).ToArray()); log += "\r\n"; PreloaderLog?.Dispose(); PreloaderLog = null; } catch { } File.WriteAllText( Path.Combine(Paths.GameRootPath, $"preloader_{DateTime.Now:yyyyMMdd_HHmmss_fff}.log"), log + ex); } }