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 BetterLoadingScreen v1.0.0
plugins/BetterLoadingScreen/BetterLoadingScreen.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using HG; using HarmonyLib; using IL.RoR2; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using R2API.Utils; using RoR2; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("BetterLoadingScreen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BetterLoadingScreen")] [assembly: AssemblyTitle("BetterLoadingScreen")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [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; } } internal class IsExternalInit { } } namespace BetterLoadingScreen { internal static class Log { internal static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber) { int num = callerPath.LastIndexOf("BetterLoadingScreen"); if (num >= 0) { callerPath = callerPath.Substring(num + "BetterLoadingScreen".Length + 1); } return $"{callerPath}:{callerLineNumber} ({callerMemberName}) "; } internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Error_NoCallerPrefix(object data) { _logSource.LogError(data); } internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Fatal_NoCallerPrefix(object data) { _logSource.LogFatal(data); } internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Info_NoCallerPrefix(object data) { _logSource.LogInfo(data); } internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Message_NoCallerPrefix(object data) { _logSource.LogMessage(data); } internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data)); } internal static void Warning_NoCallerPrefix(object data) { _logSource.LogWarning(data); } } [BepInPlugin("Gorakh.BetterLoadingScreen", "BetterLoadingScreen", "1.0.0")] public class Main : BaseUnityPlugin { private readonly record struct SystemInitializerCall(MethodInfo InitMethod, object Instance, object[] Arguments) { public void Invoke() { InitMethod.Invoke(Instance, Arguments); } } [CompilerGenerated] private static class <>O { public static Manipulator <0>__RoR2Application_InitializeGameRoutine_MoveNext; public static Manipulator <1>__SystemInitializerAttribute_Execute; public static Func<object> <2>__runSystemInitializersAsync; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<float, float> <>9__8_1; public static Func<Instruction, bool> <>9__8_2; public static Manipulator <>9__8_0; public static Func<Instruction, bool> <>9__9_0; public static Func<MethodInfo, object, object[], object> <>9__9_1; public static Func<Instruction, bool> <>9__9_2; public static Func<Instruction, bool> <>9__10_2; public static Func<TMP_Text, bool> <>9__11_0; internal void <Awake>b__8_0(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertyGetter(typeof(ReadableProgress<float>), "value")) })) { val.EmitDelegate<Func<float, float>>((Func<float, float>)((float value) => Util.Remap(value, 0f, 1f, 0f, 0.7f))); } } internal float <Awake>b__8_1(float value) { return Util.Remap(value, 0f, 1f, 0f, 0.7f); } internal bool <Awake>b__8_2(Instruction x) { return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertyGetter(typeof(ReadableProgress<float>), "value")); } internal bool <SystemInitializerAttribute_Execute>b__9_0(Instruction x) { return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo<MethodBase>((Expression<Action<MethodBase>>)((MethodBase _) => _.Invoke(null, null)))); } internal object <SystemInitializerAttribute_Execute>b__9_1(MethodInfo initMethod, object instance, object[] args) { _initializerCallQueue.Enqueue(new SystemInitializerCall(initMethod, instance, args)); return null; } internal bool <SystemInitializerAttribute_Execute>b__9_2(Instruction x) { return ILPatternMatchingExt.MatchStsfld<SystemInitializerAttribute>(x, "hasExecuted"); } internal bool <RoR2Application_InitializeGameRoutine_MoveNext>b__10_2(Instruction x) { return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => SystemInitializerAttribute.Execute()))); } internal bool <runSystemInitializersAsync>b__11_0(TMP_Text label) { return ((Object)label).name.Equals("LoadingPercentIndicator", StringComparison.Ordinal); } } public const string PluginGUID = "Gorakh.BetterLoadingScreen"; public const string PluginAuthor = "Gorakh"; public const string PluginName = "BetterLoadingScreen"; public const string PluginVersion = "1.0.0"; private static Type RoR2Application_InitializeGameRoutine_IteratorType; private static readonly Queue<SystemInitializerCall> _initializerCallQueue = new Queue<SystemInitializerCall>(); private const float SYSTEM_INITIALIZER_START_PERCENT = 0.7f; private void Awake() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00b9: 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_00c4: Expected O, but got Unknown Stopwatch stopwatch = Stopwatch.StartNew(); Log.Init(((BaseUnityPlugin)this).Logger); Type type = findIteratorType(typeof(RoR2Application), "LoadGameContent"); if ((object)type != null) { MethodInfo methodInfo = findIteratorMoveNextMethod(type); if ((object)methodInfo != null) { object obj = <>c.<>9__8_0; if (obj == null) { Manipulator val = delegate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val4 = new ILCursor(il); while (val4.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertyGetter(typeof(ReadableProgress<float>), "value")) })) { val4.EmitDelegate<Func<float, float>>((Func<float, float>)((float value) => Util.Remap(value, 0f, 1f, 0f, 0.7f))); } }; <>c.<>9__8_0 = val; obj = (object)val; } new ILHook((MethodBase)methodInfo, (Manipulator)obj); } } RoR2Application_InitializeGameRoutine_IteratorType = findIteratorType(typeof(RoR2Application), "InitializeGameRoutine"); if ((object)RoR2Application_InitializeGameRoutine_IteratorType != null) { MethodInfo methodInfo2 = findIteratorMoveNextMethod(RoR2Application_InitializeGameRoutine_IteratorType); if ((object)methodInfo2 != null) { object obj2 = <>O.<0>__RoR2Application_InitializeGameRoutine_MoveNext; if (obj2 == null) { Manipulator val2 = RoR2Application_InitializeGameRoutine_MoveNext; <>O.<0>__RoR2Application_InitializeGameRoutine_MoveNext = val2; obj2 = (object)val2; } new ILHook((MethodBase)methodInfo2, (Manipulator)obj2); object obj3 = <>O.<1>__SystemInitializerAttribute_Execute; if (obj3 == null) { Manipulator val3 = SystemInitializerAttribute_Execute; <>O.<1>__SystemInitializerAttribute_Execute = val3; obj3 = (object)val3; } SystemInitializerAttribute.Execute += (Manipulator)obj3; } } stopwatch.Stop(); Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds"); } private static void SystemInitializerAttribute_Execute(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo<MethodBase>((Expression<Action<MethodBase>>)((MethodBase _) => _.Invoke(null, null)))) })) { val.Remove(); val.EmitDelegate<Func<MethodInfo, object, object[], object>>((Func<MethodInfo, object, object[], object>)delegate(MethodInfo initMethod, object instance, object[] args) { _initializerCallQueue.Enqueue(new SystemInitializerCall(initMethod, instance, args)); return null; }); } if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchStsfld<SystemInitializerAttribute>(x, "hasExecuted") })) { val.Emit(OpCodes.Pop); val.Emit(OpCodes.Ldc_I4_0); } } private static void RoR2Application_InitializeGameRoutine_MoveNext(ILContext il) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) FieldInfo field = RoR2Application_InitializeGameRoutine_IteratorType.GetField("<>1__state", BindingFlags.Instance | BindingFlags.NonPublic); if ((object)field == null) { Log.Error("Unable to find iterator state field", "X:\\Git\\RoR2\\BetterLoadingScreen\\BetterLoadingScreen\\Main.cs", "RoR2Application_InitializeGameRoutine_MoveNext", 114); return; } FieldInfo field2 = RoR2Application_InitializeGameRoutine_IteratorType.GetField("<>2__current", BindingFlags.Instance | BindingFlags.NonPublic); if ((object)field2 == null) { Log.Error("Unable to find iterator current field", "X:\\Git\\RoR2\\BetterLoadingScreen\\BetterLoadingScreen\\Main.cs", "RoR2Application_InitializeGameRoutine_MoveNext", 121); return; } ILCursor val = new ILCursor(il); ILLabel[] stateSwitchLabels = Array.Empty<ILLabel>(); if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchSwitch(x, ref stateSwitchLabels) })) { Log.Error("Unable to find iterator state switch", "X:\\Git\\RoR2\\BetterLoadingScreen\\BetterLoadingScreen\\Main.cs", "RoR2Application_InitializeGameRoutine_MoveNext", 130); return; } Instruction next = val.Next; if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => SystemInitializerAttribute.Execute()))) })) { Log.Error("Unable to find SystemInitializer Execute call", "X:\\Git\\RoR2\\BetterLoadingScreen\\BetterLoadingScreen\\Main.cs", "RoR2Application_InitializeGameRoutine_MoveNext", 149); return; } ILLabel val2 = val.DefineLabel(); int num = appendState(val2); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<object>>((Func<object>)runSystemInitializersAsync); val.Emit(OpCodes.Stfld, field2); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldc_I4, num); val.Emit(OpCodes.Stfld, field); val.Emit(OpCodes.Ldc_I4_1); val.Emit(OpCodes.Ret); val.MarkLabel(val2); next.Operand = stateSwitchLabels; int appendState(ILLabel targetLabel) { int num2 = stateSwitchLabels.Length; Array.Resize(ref stateSwitchLabels, stateSwitchLabels.Length + 1); stateSwitchLabels[num2] = targetLabel; return num2; } } private static IEnumerator runSystemInitializersAsync() { TMP_Text loadingPercentIndicatorLabel = (from label in Object.FindObjectsOfType<TMP_Text>() where ((Object)label).name.Equals("LoadingPercentIndicator", StringComparison.Ordinal) select label).FirstOrDefault(); Animation loadingPercentAnimation = (Object.op_Implicit((Object)(object)loadingPercentIndicatorLabel) ? ((Component)loadingPercentIndicatorLabel).GetComponentInChildren<Animation>() : null); StringBuilder loadingTextStringBuilder = StringBuilderPool.RentStringBuilder(); int numCallsCompleted = 0; int totalCalls = _initializerCallQueue.Count; while (_initializerCallQueue.Count > 0) { _initializerCallQueue.Dequeue().Invoke(); numCallsCompleted++; float num = Util.Remap((float)numCallsCompleted / (float)totalCalls, 0f, 1f, 0.7f, 1f); if (Object.op_Implicit((Object)(object)loadingPercentIndicatorLabel)) { loadingTextStringBuilder.Clear(); StringBuilderExtensions.AppendInt(loadingTextStringBuilder, Mathf.FloorToInt(num * 100f), 1u, uint.MaxValue); loadingTextStringBuilder.Append("%"); loadingPercentIndicatorLabel.SetText(loadingTextStringBuilder); } if (Object.op_Implicit((Object)(object)loadingPercentAnimation)) { AnimationClip clip = loadingPercentAnimation.clip; clip.SampleAnimation(((Component)loadingPercentAnimation).gameObject, num * 0.99f * clip.length); } yield return 0; } StringBuilderPool.ReturnStringBuilder(loadingTextStringBuilder); SystemInitializerAttribute.hasExecuted = true; } private static Type findIteratorType(Type declaringType, string iteratorMethodName) { Type type = declaringType.GetNestedTypes(BindingFlags.NonPublic).FirstOrDefault((Type t) => typeof(IEnumerator<object>).IsAssignableFrom(t) && t.Name.StartsWith("<" + iteratorMethodName + ">d__")); if ((object)type == null) { Log.Error("Unable to find " + iteratorMethodName + " iterator class", "X:\\Git\\RoR2\\BetterLoadingScreen\\BetterLoadingScreen\\Main.cs", "findIteratorType", 224); return null; } Log.Info("Found " + iteratorMethodName + " iterator class: " + type.FullName, "X:\\Git\\RoR2\\BetterLoadingScreen\\BetterLoadingScreen\\Main.cs", "findIteratorType", 228); return type; } private static MethodInfo findIteratorMoveNextMethod(Type iteratorType) { MethodInfo method = iteratorType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic); if ((object)method == null) { Log.Error("Unable to find " + iteratorType.FullName + " iterator MoveNext method", "X:\\Git\\RoR2\\BetterLoadingScreen\\BetterLoadingScreen\\Main.cs", "findIteratorMoveNextMethod", 237); return null; } return method; } } }