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 PausedTimerOnTP v1.0.0
PausedTimerOnTP.dll
Decompiled a day agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PausedTimerOnTP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PausedTimerOnTP")] [assembly: AssemblyTitle("PausedTimerOnTP")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 PausedTimerOnTP { public enum StopTrigger { OnActivation, OnChargeComplete } [BepInPlugin("Bruce.PausedTimerOnTP", "PausedTimerOnTP", "1.0.0")] public class PausedTimerOnTPPlugin : BaseUnityPlugin { public const string PluginAuthor = "Bruce"; public const string PluginName = "PausedTimerOnTP"; public const string PluginGUID = "Bruce.PausedTimerOnTP"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<StopTrigger> Trigger; internal static bool TimerFrozen; private static float frozenAt; private bool patchApplied; private bool fallbackWarningLogged; private Harmony harmony; private void Awake() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. When false the run timer behaves exactly like vanilla."); Trigger = ((BaseUnityPlugin)this).Config.Bind<StopTrigger>("General", "StopTrigger", StopTrigger.OnActivation, "OnActivation: stop the timer the moment the teleporter is activated.\nOnChargeComplete: keep it running during the boss/charge and stop it at 100% charge."); Enabled.SettingChanged += delegate { if (!Enabled.Value) { Unfreeze("disabled in config"); } }; TeleporterInteraction.onTeleporterBeginChargingGlobal += OnTeleporterBeginCharging; TeleporterInteraction.onTeleporterChargedGlobal += OnTeleporterCharged; Stage.onStageStartGlobal += OnStageStart; Run.onRunStartGlobal += OnRunStart; harmony = new Harmony("Bruce.PausedTimerOnTP"); try { harmony.CreateClassProcessor(typeof(RunStopwatchPatch)).Patch(); patchApplied = true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not patch Run.ShouldUpdateRunStopwatch; using fallback clamp instead. " + ex.Message)); } ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded (trigger: {2}).", "PausedTimerOnTP", "1.0.0", Trigger.Value)); } private void OnDestroy() { TeleporterInteraction.onTeleporterBeginChargingGlobal -= OnTeleporterBeginCharging; TeleporterInteraction.onTeleporterChargedGlobal -= OnTeleporterCharged; Stage.onStageStartGlobal -= OnStageStart; Run.onRunStartGlobal -= OnRunStart; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private void OnTeleporterBeginCharging(TeleporterInteraction teleporter) { if (Trigger.Value == StopTrigger.OnActivation) { Freeze("teleporter activated"); } } private void OnTeleporterCharged(TeleporterInteraction teleporter) { if (Trigger.Value == StopTrigger.OnChargeComplete) { Freeze("teleporter fully charged"); } } private void OnStageStart(Stage stage) { Unfreeze("new stage"); } private void OnRunStart(Run run) { Unfreeze("new run"); } private void Freeze(string reason) { if (NetworkServer.active && Enabled.Value && !TimerFrozen && !((Object)(object)Run.instance == (Object)null)) { frozenAt = Run.instance.GetRunStopwatch(); TimerFrozen = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Run timer stopped at {frozenAt:F1}s ({reason})."); } } private void Unfreeze(string reason) { if (TimerFrozen) { TimerFrozen = false; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Run timer released (" + reason + ").")); } } private void FixedUpdate() { if (!TimerFrozen || !NetworkServer.active) { return; } Run instance = Run.instance; if (!((Object)(object)instance == (Object)null) && Math.Abs(instance.GetRunStopwatch() - frozenAt) > 0.05f) { instance.SetRunStopwatch(frozenAt); if (!fallbackWarningLogged) { fallbackWarningLogged = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)(patchApplied ? "Stopwatch kept advancing despite the patch (a Run subclass may override it); clamping instead." : "Clamping run stopwatch via fallback.")); } } } } [HarmonyPatch(typeof(Run), "ShouldUpdateRunStopwatch")] internal static class RunStopwatchPatch { [HarmonyPostfix] private static void Postfix(ref bool __result) { if (PausedTimerOnTPPlugin.TimerFrozen) { __result = false; } } } }