NetPreloader.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Reflection;
  5. using BepInEx.Bootstrap;
  6. using BepInEx.Configuration;
  7. using BepInEx.Logging;
  8. using BepInEx.NetLauncher.RuntimeFixes;
  9. using BepInEx.Preloader.Core;
  10. using BepInEx.Preloader.Core.Logging;
  11. namespace BepInEx.NetLauncher
  12. {
  13. public static class NetPreloader
  14. {
  15. private static readonly ManualLogSource Log = PreloaderLogger.Log;
  16. public static void Start(string[] args)
  17. {
  18. if (string.IsNullOrEmpty(ConfigEntrypointExecutable.Value))
  19. {
  20. Log.LogFatal($"Entry executable was not set. Please set this in your config before launching the application");
  21. Program.ReadExit();
  22. return;
  23. }
  24. string executablePath = Path.GetFullPath(ConfigEntrypointExecutable.Value);
  25. if (!File.Exists(executablePath))
  26. {
  27. Log.LogFatal($"Unable to locate executable: {ConfigEntrypointExecutable.Value}");
  28. Program.ReadExit();
  29. return;
  30. }
  31. Paths.SetExecutablePath(executablePath);
  32. Program.ResolveDirectories.Add(Paths.GameRootPath);
  33. TypeLoader.SearchDirectories.Add(Paths.GameRootPath);
  34. Logger.Sources.Add(TraceLogSource.CreateSource());
  35. ChainloaderLogHelper.PrintLogInfo(Log);
  36. Log.LogInfo($"CLR runtime version: {Environment.Version}");
  37. Log.LogMessage("Preloader started");
  38. Assembly entrypointAssembly;
  39. using (var assemblyPatcher = new AssemblyPatcher())
  40. {
  41. assemblyPatcher.AddPatchersFromDirectory(Paths.PatcherPluginPath);
  42. Log.LogInfo($"{assemblyPatcher.PatcherPlugins.Count} patcher plugin(s) loaded");
  43. assemblyPatcher.LoadAssemblyDirectory(Paths.GameRootPath, "dll", "exe");
  44. Log.LogInfo($"{assemblyPatcher.AssembliesToPatch.Count} assemblies discovered");
  45. assemblyPatcher.PatchAndLoad();
  46. var assemblyName = AssemblyName.GetAssemblyName(executablePath);
  47. entrypointAssembly = assemblyPatcher.LoadedAssemblies.Values.FirstOrDefault(x => x.FullName == assemblyName.FullName);
  48. if (entrypointAssembly != null)
  49. {
  50. Log.LogDebug("Found patched entrypoint assembly! Using it");
  51. }
  52. else
  53. {
  54. Log.LogDebug("Using entrypoint assembly from disk");
  55. entrypointAssembly = Assembly.LoadFrom(executablePath);
  56. }
  57. }
  58. Log.LogMessage("Preloader finished");
  59. var chainloader = new NetChainloader();
  60. chainloader.Initialize();
  61. chainloader.Execute();
  62. AssemblyFix.Execute(entrypointAssembly);
  63. entrypointAssembly.EntryPoint.Invoke(null, new [] { args });
  64. }
  65. #region Config
  66. private static readonly ConfigEntry<string> ConfigEntrypointExecutable = ConfigFile.CoreConfig.Bind<string>(
  67. "Preloader.Entrypoint", "Assembly",
  68. null,
  69. "The local filename of the .NET executable to target.");
  70. #endregion
  71. }
  72. }