Decompiled source of WhatsTakingSoLong v1.0.0

BepInEx/patchers/WhatsTakingSoLong/LoadAnalyzer.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("LoadOptimizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LoadOptimizer")]
[assembly: AssemblyTitle("LoadOptimizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LoadingTimer
{
	public static class LoadingTimer
	{
		public delegate void orig_ctor(BaseUnityPlugin self);

		public delegate void orig_Awake(BaseUnityPlugin self);

		public delegate void orig_Enable(BaseUnityPlugin self);

		internal static class Logger
		{
			private static readonly ManualLogSource logSource = Logger.CreateLogSource("WhatsTakingSoLong");

			public static void Info(object data)
			{
				logSource.LogInfo(data);
			}

			public static void Error(object data)
			{
				logSource.LogError(data);
			}

			public static void Warn(object data)
			{
				logSource.LogWarning(data);
			}

			public static void Fatal(object data)
			{
				logSource.LogFatal(data);
			}

			public static void Message(object data)
			{
				logSource.LogMessage(data);
			}

			public static void Debug(object data)
			{
				logSource.LogDebug(data);
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction<Scene, Scene> <0>__LogAllLoadTimes;

			public static Manipulator <1>__IL_Awake;
		}

		public static ManualLogSource ModLogger;

		public static Dictionary<orig_Awake, BaseUnityPlugin> awakes;

		public static TypeReference StopwatchTypeRef;

		public static Stopwatch GlobalLoadTime;

		public static List<KeyValuePair<string, double>> loadTimes = new List<KeyValuePair<string, double>>();

		public static IEnumerable<string> TargetDLLs { get; } = new string[0];


		public static void Patch(AssemblyDefinition def)
		{
		}

		public static void Initialize()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			Logger.Error("Initializing LoadingTimer.");
			GlobalLoadTime = Stopwatch.StartNew();
			Hook val = new Hook((MethodBase)typeof(BaseUnityPlugin).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, Array.Empty<Type>(), null), typeof(LoadingTimer).GetMethod("BaseUnityPlugin_ctor", BindingFlags.Static | BindingFlags.Public));
			SceneManager.activeSceneChanged += LogAllLoadTimes;
			AssemblyDefinition val2 = AssemblyDefinition.ReadAssembly(typeof(Stopwatch).Assembly.Location);
			Type typeFromHandle = typeof(Stopwatch);
			StopwatchTypeRef = val2.MainModule.ImportReference(typeFromHandle);
			Logger.Error("Acquired TypeReference for Stopwatch: " + (object)StopwatchTypeRef);
		}

		public static void LogAllLoadTimes(Scene scene, Scene scene2)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (!(((Scene)(ref activeScene)).name != "title"))
			{
				Logger.Error("Loading took a total time of: " + GlobalLoadTime.Elapsed);
				IOrderedEnumerable<KeyValuePair<string, double>> source = loadTimes.OrderByDescending((KeyValuePair<string, double> x) => x.Value);
				for (int i = 0; i < source.Count(); i++)
				{
					KeyValuePair<string, double> keyValuePair = source.ElementAt(i);
					string text = keyValuePair.Value.ToString("N7");
					Logger.Error(keyValuePair.Key + " took " + text + "s to load.");
				}
				SceneManager.activeSceneChanged -= LogAllLoadTimes;
			}
		}

		public static void BaseUnityPlugin_ctor(orig_ctor orig, BaseUnityPlugin self)
		{
			if (!TryHookMethod(self, "Awake") && !TryHookMethod(self, "OnEnable"))
			{
				TryHookMethod(self, "Start");
			}
			orig(self);
		}

		public static bool TryHookMethod(BaseUnityPlugin self, string name)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			try
			{
				MethodInfo method = ((object)self).GetType().GetMethod(name, (BindingFlags)(-1));
				object obj = <>O.<1>__IL_Awake;
				if (obj == null)
				{
					Manipulator val = IL_Awake;
					<>O.<1>__IL_Awake = val;
					obj = (object)val;
				}
				ILHook val2 = new ILHook((MethodBase)method, (Manipulator)obj);
			}
			catch
			{
				return false;
			}
			return true;
		}

		public static void IL_Awake(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			VariableDefinition val2 = new VariableDefinition(StopwatchTypeRef);
			val.IL.Body.Variables.Add(val2);
			int index = ((VariableReference)val2).Index;
			val.Index = 0;
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<BaseUnityPlugin, Stopwatch>>((Func<BaseUnityPlugin, Stopwatch>)((BaseUnityPlugin plugin) => Stopwatch.StartNew()));
			val.Emit(OpCodes.Stloc, index);
			bool flag = false;
			while (!flag)
			{
				if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchRet(x)
				}))
				{
					flag = true;
				}
			}
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc, index);
			val.EmitDelegate<Action<BaseUnityPlugin, Stopwatch>>((Action<BaseUnityPlugin, Stopwatch>)delegate(BaseUnityPlugin plugin, Stopwatch stopwatch)
			{
				loadTimes.Add(new KeyValuePair<string, double>(plugin.Info.Metadata.Name, stopwatch.Elapsed.TotalSeconds));
			});
		}
	}
}