Example #1
0
        public static void Run()
        {
            try
            {
                ConsoleManager.Initialize(false);

                PreloaderLog = new PreloaderConsoleListener();
                Logger.Listeners.Add(PreloaderLog);



                if (ConsoleManager.ConfigConsoleEnabled.Value)
                {
                    ConsoleManager.CreateConsole();
                    Logger.Listeners.Add(new ConsoleLogListener());
                }

                ChainloaderLogHelper.PrintLogInfo(Log);

                Log.LogInfo($"Running under Unity v{FileVersionInfo.GetVersionInfo(Paths.ExecutablePath).FileVersion}");

                Log.LogDebug($"Game executable path: {Paths.ExecutablePath}");
                Log.LogDebug($"Unhollowed assembly directory: {IL2CPPUnhollowedPath}");
                Log.LogDebug($"BepInEx root path: {Paths.BepInExRootPath}");



                UnhollowerLog = Logger.CreateLogSource("Unhollower");
                UnhollowerBaseLib.LogSupport.InfoHandler    += UnhollowerLog.LogInfo;
                UnhollowerBaseLib.LogSupport.WarningHandler += UnhollowerLog.LogWarning;
                UnhollowerBaseLib.LogSupport.TraceHandler   += UnhollowerLog.LogDebug;
                UnhollowerBaseLib.LogSupport.ErrorHandler   += UnhollowerLog.LogError;


                if (ProxyAssemblyGenerator.CheckIfGenerationRequired())
                {
                    ProxyAssemblyGenerator.GenerateAssemblies();
                }


                using (var assemblyPatcher = new AssemblyPatcher())
                {
                    assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath);

                    Log.LogInfo($"{assemblyPatcher.PatcherPlugins.Count} patcher plugin{(assemblyPatcher.PatcherPlugins.Count == 1 ? "" : "s")} loaded");

                    assemblyPatcher.LoadAssemblyDirectory(IL2CPPUnhollowedPath);

                    Log.LogInfo($"{assemblyPatcher.PatcherPlugins.Count} assemblies discovered");

                    assemblyPatcher.PatchAndLoad();
                }


                Logger.Listeners.Remove(PreloaderLog);



                Chainloader = new IL2CPPChainloader();

                Chainloader.Initialize();
            }
            catch (Exception ex)
            {
                Log.LogFatal(ex);

                throw;
            }
        }
Example #2
0
        public static void Start(string[] args)
        {
            if (ConfigEntrypointExecutable.Value == null)
            {
                Log.LogFatal($"Entry executable was not set. Please set this in your config before launching the application");
                Program.ReadExit();
                return;
            }

            string executablePath = Path.GetFullPath(ConfigEntrypointExecutable.Value);

            if (!File.Exists(executablePath))
            {
                Log.LogFatal($"Unable to locate executable: {ConfigEntrypointExecutable.Value}");
                Program.ReadExit();
                return;
            }

            Paths.SetExecutablePath(executablePath);
            Program.ResolveDirectories.Add(Paths.GameRootPath);
            TypeLoader.SearchDirectories.Add(Paths.GameRootPath);

            Logger.Sources.Add(TraceLogSource.CreateSource());

            ChainloaderLogHelper.PrintLogInfo(Log);

            Log.LogInfo($"CLR runtime version: {Environment.Version}");

            Log.LogMessage("Preloader started");

            Assembly entrypointAssembly;

            using (var assemblyPatcher = new AssemblyPatcher())
            {
                assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath);

                Log.LogInfo($"{assemblyPatcher.PatcherPlugins.Count} patcher plugin(s) loaded");

                assemblyPatcher.LoadAssemblyDirectory(Paths.GameRootPath, "dll", "exe");

                Log.LogInfo($"{assemblyPatcher.AssembliesToPatch.Count} assemblies discovered");

                assemblyPatcher.PatchAndLoad();


                var assemblyName = AssemblyName.GetAssemblyName(executablePath);

                entrypointAssembly = assemblyPatcher.LoadedAssemblies.Values.FirstOrDefault(x => x.FullName == assemblyName.FullName);

                if (entrypointAssembly != null)
                {
                    Log.LogDebug("Found patched entrypoint assembly! Using it");
                }
                else
                {
                    Log.LogDebug("Using entrypoint assembly from disk");
                    entrypointAssembly = Assembly.LoadFrom(executablePath);
                }
            }

            Log.LogMessage("Preloader finished");

            var chainloader = new NetChainloader();

            chainloader.Initialize();
            chainloader.Execute();


            AssemblyFix.Execute(entrypointAssembly);

            entrypointAssembly.EntryPoint.Invoke(null, new [] { args });
        }
Example #3
0
        public static void Run(string managedDirectory)
        {
            try
            {
                InitializeHarmony();

                ConsoleManager.Initialize(false);
                AllocateConsole();

                if (managedDirectory != null)
                {
                    ManagedPath = managedDirectory;
                }


                Utility.TryDo(() =>
                {
                    if (ConfigApplyRuntimePatches.Value)
                    {
                        UnityPatches.Apply();
                    }
                }, out var runtimePatchException);

                Logger.Sources.Add(TraceLogSource.CreateSource());
                Logger.Sources.Add(new HarmonyLogSource());

                Logger.Listeners.Add(new ConsoleLogListener());
                PreloaderLog = new PreloaderConsoleListener();
                Logger.Listeners.Add(PreloaderLog);

                ChainloaderLogHelper.PrintLogInfo(Log);

                Log.LogInfo($"Running under Unity v{GetUnityVersion()}");
                Log.LogInfo($"CLR runtime version: {Environment.Version}");
                Log.LogInfo($"Supports SRE: {Utility.CLRSupportsDynamicAssemblies}");

                Log.LogDebug($"Game executable path: {Paths.ExecutablePath}");
                Log.LogDebug($"Unity Managed directory: {ManagedPath}");
                Log.LogDebug($"BepInEx root path: {Paths.BepInExRootPath}");

                if (runtimePatchException != null)
                {
                    Log.LogWarning($"Failed to apply runtime patches for Mono. See more info in the output log. Error message: {runtimePatchException.Message}");
                }

                Log.LogMessage("Preloader started");

                TypeLoader.SearchDirectories.Add(ManagedPath);

                using (var assemblyPatcher = new AssemblyPatcher())
                {
                    assemblyPatcher.PatcherPlugins.Add(new PatcherPlugin
                    {
                        TargetDLLs = () => new[] { ConfigEntrypointAssembly.Value },
                        Patcher    = PatchEntrypoint,
                        TypeName   = "BepInEx.Chainloader"
                    });

                    assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath);

                    Log.LogInfo($"{assemblyPatcher.PatcherPlugins.Count} patcher plugin{(assemblyPatcher.PatcherPlugins.Count == 1 ? "" : "s")} loaded");

                    assemblyPatcher.LoadAssemblyDirectory(ManagedPath);

                    Log.LogInfo($"{assemblyPatcher.PatcherPlugins.Count} assemblies discovered");

                    assemblyPatcher.PatchAndLoad();
                }


                Log.LogMessage("Preloader finished");

                Logger.Listeners.Remove(PreloaderLog);

                PreloaderLog.Dispose();

                Logger.Listeners.Add(new StdOutLogListener());
            }
            catch (Exception ex)
            {
                try
                {
                    Log.LogFatal("Could not run preloader!");
                    Log.LogFatal(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);
            }
        }