diff --git a/1.6/Assemblies/PerformanceFish.dll b/1.6/Assemblies/PerformanceFish.dll index 6c995e0..8c95aa2 100644 Binary files a/1.6/Assemblies/PerformanceFish.dll and b/1.6/Assemblies/PerformanceFish.dll differ diff --git a/1.6/Assemblies/PerformanceFish.pdb b/1.6/Assemblies/PerformanceFish.pdb index b83ab76..d4c43d0 100644 Binary files a/1.6/Assemblies/PerformanceFish.pdb and b/1.6/Assemblies/PerformanceFish.pdb differ diff --git a/Source/PerformanceFish/UtilityPrepatches.cs b/Source/PerformanceFish/UtilityPrepatches.cs index 360eac9..c31bdb4 100644 --- a/Source/PerformanceFish/UtilityPrepatches.cs +++ b/Source/PerformanceFish/UtilityPrepatches.cs @@ -26,6 +26,9 @@ public sealed class UtilityPrepatches : ClassWithFishPrepatches public override MethodBase TargetMethodBase { get; } = methodof(LoadedModManager.CreateModClasses); + public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module) + => ilProcessor.ReplaceBodyWith(ReplacementBody); + public static void Prefix() { try @@ -37,6 +40,59 @@ public sealed class UtilityPrepatches : ClassWithFishPrepatches Log.Error($"Exception caught within OnAssembliesLoaded:\n{e}\n{new StackTrace(true)}"); } } + + public static void ReplacementBody() + { + var runningModClasses = RunningModClasses; + var assemblyToModContentPack = BuildAssemblyToModContentPackMap(); + + foreach (var type in typeof(Mod).InstantiableDescendantsAndSelf()) + { + if (type is null) + continue; + + DeepProfiler.Start("Loading " + type?.ToString() + " mod class"); + try + { + if (!runningModClasses.ContainsKey(type)) + { + assemblyToModContentPack.TryGetValue(type.Assembly, out var modContentPack); + runningModClasses[type] = (Mod)Activator.CreateInstance(type, modContentPack); + } + } + catch (Exception ex) + { + Log.Error("Error while instantiating a mod of type " + type?.ToString() + ": " + ex); + } + finally + { + DeepProfiler.End(); + } + } + } + + private static Dictionary BuildAssemblyToModContentPackMap() + { + var runningMods = LoadedModManager.RunningModsListForReading; + var assemblyToModContentPack = new Dictionary(); + + for (var i = 0; i < runningMods.Count; i++) + { + var modContentPack = runningMods[i]; + var loadedAssemblies = modContentPack.assemblies.loadedAssemblies; + + for (var j = 0; j < loadedAssemblies.Count; j++) + assemblyToModContentPack.TryAdd(loadedAssemblies[j], modContentPack); + } + + return assemblyToModContentPack; + } + + private static Dictionary RunningModClasses + => (Dictionary)(_runningModClassesField ??= + AccessTools.Field(typeof(LoadedModManager), "runningModClasses")).GetValue(null)!; + + private static FieldInfo? _runningModClassesField; } public sealed class NoSteamLogWarning : FishPrepatch