Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of NGPlus AdminTools v1.0.7
plugins/StartupProfiler.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HarmonyLib; using Mono.Cecil; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("StartupProfiler")] [assembly: AssemblyDescription("Log and report the time each plugin takes to load")] [assembly: AssemblyProduct("StartupProfiler")] [assembly: Guid("6081c5ae-ab5a-456b-a29f-3eef9ad9eedf")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("https://github.com/BepInEx/BepInEx.Debug")] [assembly: AssemblyCopyright("Copyright © 2020")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: AssemblyVersion("9.0.0.0")] namespace Common { internal static class Metadata { public const string Version = "9.0"; } } namespace StartupProfiler { public class StartupProfiler { private static ManualLogSource logger; private static Harmony harmony; private static Stopwatch chainTimer; private static string[] unityMethods = new string[3] { "Awake", "Start", "Main" }; private static readonly Dictionary<Type, KeyValuePair<BepInPlugin, Stopwatch>> timers = new Dictionary<Type, KeyValuePair<BepInPlugin, Stopwatch>>(); public static MethodInfo StartTimerMethodInfo = typeof(StartupProfiler).GetMethod("StartTimer"); public static MethodInfo StopTimerMethodInfo = typeof(StartupProfiler).GetMethod("StopTimer"); public static IEnumerable<string> TargetDLLs { get; } = new string[0]; public static void Patch(AssemblyDefinition ass) { } public static void Finish() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown logger = Logger.CreateLogSource("StartupProfiler"); harmony = new Harmony("StartupProfiler"); harmony.Patch((MethodBase)typeof(Chainloader).GetMethod("Initialize"), (HarmonyMethod)null, new HarmonyMethod(typeof(StartupProfiler).GetMethod("ChainloaderHook")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void ChainloaderHook() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_006b: Expected O, but got Unknown //IL_006b: Expected O, but got Unknown harmony.Patch((MethodBase)typeof(Chainloader).GetMethod("Start"), new HarmonyMethod(typeof(StartupProfiler).GetMethod("ChainloaderPre")), new HarmonyMethod(typeof(StartupProfiler).GetMethod("ChainloaderPost")), new HarmonyMethod(typeof(StartupProfiler).GetMethod("FindPluginTypes")), (HarmonyMethod)null, (HarmonyMethod)null); } public static void ChainloaderPre() { chainTimer = new Stopwatch(); chainTimer.Start(); } public static IEnumerable<CodeInstruction> FindPluginTypes(IEnumerable<CodeInstruction> instructions) { foreach (CodeInstruction code in instructions) { if (code.opcode == OpCodes.Callvirt && code.operand.ToString().Contains("AddComponent")) { yield return new CodeInstruction(OpCodes.Call, (object)typeof(StartupProfiler).GetMethod("PatchPlugin")); } yield return code; } } public static Type PatchPlugin(Type type) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0087: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00cb: Expected O, but got Unknown BepInPlugin key = (BepInPlugin)type.GetCustomAttributes(inherit: false).First((object x) => (object)x.GetType() == typeof(BepInPlugin)); timers[type] = new KeyValuePair<BepInPlugin, Stopwatch>(key, new Stopwatch()); string[] array = unityMethods; foreach (string name in array) { MethodInfo method = type.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)method != null) { harmony.Patch((MethodBase)method, new HarmonyMethod(StartTimerMethodInfo), new HarmonyMethod(StopTimerMethodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (ConstructorInfo constructorInfo in constructors) { harmony.Patch((MethodBase)constructorInfo, new HarmonyMethod(StartTimerMethodInfo), new HarmonyMethod(StopTimerMethodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } return type; } public static void StartTimer(object __instance) { if (timers.TryGetValue(__instance.GetType(), out var value)) { value.Value.Start(); } } public static void StopTimer(object __instance) { if (timers.TryGetValue(__instance.GetType(), out var value)) { value.Value.Stop(); } } public static void ChainloaderPost() { chainTimer.Stop(); ((MonoBehaviour)ThreadingHelper.Instance).StartCoroutine(PrintResults()); } public static IEnumerator PrintResults() { yield return null; logger.LogInfo((object)$"Chainloader total: {chainTimer.ElapsedMilliseconds} ms"); logger.LogInfo((object)$"Plugins total: {timers.Sum((KeyValuePair<Type, KeyValuePair<BepInPlugin, Stopwatch>> x) => x.Value.Value.ElapsedMilliseconds)} ms"); foreach (KeyValuePair<Type, KeyValuePair<BepInPlugin, Stopwatch>> item in timers.OrderByDescending((KeyValuePair<Type, KeyValuePair<BepInPlugin, Stopwatch>> x) => x.Value.Value.ElapsedMilliseconds)) { logger.LogInfo((object)$"{item.Value.Key.GUID}: {item.Value.Value.ElapsedMilliseconds} ms"); } harmony.UnpatchAll(harmony.Id); } } }