using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using BepInEx.Logging; using HarmonyLib; namespace BepInEx.NET.Framework.Launcher.RuntimeFixes; internal class AssemblyFixes { private static Assembly EntryAssembly { get; set; } public static Dictionary AssemblyLocations { get; } = new(StringComparer.InvariantCultureIgnoreCase); public static void Execute(Assembly entryAssembly) { EntryAssembly = entryAssembly; Harmony.CreateAndPatchAll(typeof(AssemblyFixes), "io.bepinex.assemblyfix"); } [HarmonyPrefix] [HarmonyPatch(typeof(Assembly), nameof(Assembly.GetEntryAssembly))] public static bool GetEntryAssemblyPrefix(ref Assembly __result) { Logger.Log(LogLevel.Debug, "Ran GetEntryAssembly"); __result = EntryAssembly; return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Assembly), nameof(Assembly.Load), typeof(string))] public static bool LoadByName(ref Assembly __result, string assemblyString) { __result = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(x => x.GetName().FullName == assemblyString); Logger.Log(LogLevel.Debug, $"LoadByName: {assemblyString} : {__result != null}"); return __result != null; } [HarmonyPrefix] [HarmonyPatch("System.Reflection.RuntimeAssembly", nameof(Assembly.Location), MethodType.Getter)] public static bool GetLocation(ref string __result, Assembly __instance) { Logger.Log(LogLevel.Debug, $"GetLocation: {__instance.FullName}"); if (AssemblyLocations.TryGetValue(__instance.FullName, out var location)) { __result = location; return false; } return true; } // This is commented out because it should be implemented alongside GetLocation, but seems to crash the runtime // Might be because the target type should be System.Reflection.RuntimeAssembly //[HarmonyPrefix] //[HarmonyPatch(typeof(Assembly), nameof(Assembly.CodeBase), MethodType.Getter)] //public static bool GetCodeBase(ref string __result, Assembly __instance) //{ // if (AssemblyLocations.TryGetValue(__instance.FullName, out var location)) // { // __result = $"file://{location.Replace('\\', '/')}"; // return false; // } // return true; //} }