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 RemoteLever v1.0.3
RemoteLever.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("RemoteLever")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RemoteLever")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0947733e-d699-4472-8c49-1d8d08d42652")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace RemoteLever; [BepInPlugin("azumi.remotelever", "RemoteLever", "1.0.3")] public class RemoteLeverPlugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<Key> LeverKey; internal static ConfigEntry<bool> EnableAutoDeparture; internal static ConfigEntry<int> AutoDepartureHour; internal static ConfigEntry<int> AutoDepartureMinute; internal static ConfigEntry<string> AutoDepartureAmPm; internal static bool EjectResetInProgress; private Harmony harmony; internal static void LockLeverForReset() { if (!EjectResetInProgress) { EjectResetInProgress = true; Log.LogInfo((object)"Remote lever locked: player eject/reset sequence started."); } } internal static void UnlockLeverAfterReset() { if (EjectResetInProgress) { EjectResetInProgress = false; Log.LogInfo((object)"Remote lever unlocked: player eject/reset sequence completed."); } } internal static bool IsLeverLocked(StartOfRound round) { if (EjectResetInProgress) { return true; } if ((Object)(object)round != (Object)null && round.firingPlayersCutsceneRunning) { return true; } return false; } internal static void ShowTip(string title, string message) { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip(title, message, false, false, "LC_Tip1"); } } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("azumi.remotelever"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RemoteLever loaded."); LeverKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Lever Key", (Key)98, "Remote lever control key."); EnableAutoDeparture = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto", "Enable Auto Departure", false, "Automatically pull the lever and return to orbit at the configured in game time."); AutoDepartureHour = ((BaseUnityPlugin)this).Config.Bind<int>("Auto", "Auto Departure Hour", 6, new ConfigDescription("Scheduled departure hour (12-hour format).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), Array.Empty<object>())); AutoDepartureMinute = ((BaseUnityPlugin)this).Config.Bind<int>("Auto", "Auto Departure Minute", 0, new ConfigDescription("Scheduled departure minute.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 59), Array.Empty<object>())); AutoDepartureAmPm = ((BaseUnityPlugin)this).Config.Bind<string>("Auto", "Auto Departure AM/PM", "PM", new ConfigDescription("Scheduled departure AM/PM.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "AM", "PM" }), Array.Empty<object>())); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Automatic Departure: " + (EnableAutoDeparture.Value ? "Enabled" : "Disabled"))); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Scheduled time: {AutoDepartureHour.Value}:{AutoDepartureMinute.Value:00} {AutoDepartureAmPm.Value}"); } } [HarmonyPatch(typeof(HUDManager))] internal class HUDManagerPatch { private static float lastPressTime; private static bool autoDepartureTriggered; private static bool wasShipLanded; [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePatch() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return; } if (instance.shipHasLanded && !wasShipLanded) { wasShipLanded = true; autoDepartureTriggered = false; RemoteLeverPlugin.Log.LogInfo((object)"Ship has landed on moon. Automatic departure timer initialized."); if (RemoteLeverPlugin.EnableAutoDeparture.Value) { RemoteLeverPlugin.Log.LogInfo((object)("Automatic departure scheduled for " + $"{RemoteLeverPlugin.AutoDepartureHour.Value}:" + $"{RemoteLeverPlugin.AutoDepartureMinute.Value:00} " + RemoteLeverPlugin.AutoDepartureAmPm.Value)); } } if (!instance.shipHasLanded && wasShipLanded) { wasShipLanded = false; RemoteLeverPlugin.Log.LogInfo((object)"Ship is no longer on the moon. Automatic departure state reset."); } CheckAutomaticDeparture(instance); CheckManualLeverInput(instance); } private static void CheckAutomaticDeparture(StartOfRound round) { if (!RemoteLeverPlugin.EnableAutoDeparture.Value || autoDepartureTriggered || (Object)(object)GameNetworkManager.Instance == (Object)null || !GameNetworkManager.Instance.isHostingGame || RemoteLeverPlugin.IsLeverLocked(round) || !round.shipHasLanded || round.shipIsLeaving || round.travellingToNewLevel || round.beganLoadingNewLevel || ((Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonIsGenerating)) { return; } TimeOfDay instance = TimeOfDay.Instance; if ((Object)(object)instance == (Object)null || !instance.timeHasStarted || ((Object)(object)round.currentLevel != (Object)null && !round.currentLevel.planetHasTime)) { return; } int configuredTargetMinutes = GetConfiguredTargetMinutes(); int currentGameTimeMinutes = GetCurrentGameTimeMinutes(instance); if (currentGameTimeMinutes < configuredTargetMinutes) { return; } StartMatchLever val = Object.FindObjectOfType<StartMatchLever>(); if ((Object)(object)val == (Object)null) { RemoteLeverPlugin.Log.LogWarning((object)"Automatic departure failed: StartMatchLever not found."); return; } autoDepartureTriggered = true; try { RemoteLeverPlugin.Log.LogInfo((object)("Automatic departure triggered at " + FormatTime12Hour(currentGameTimeMinutes) + ".")); val.LeverAnimation(); val.EndGame(); if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.AddTextToChatOnServer("<color=#00FFFF>[RemoteLever]</color> Automatic ship departure initiated at " + FormatTime12Hour(currentGameTimeMinutes) + ".", -1); } } catch (Exception arg) { autoDepartureTriggered = false; RemoteLeverPlugin.Log.LogError((object)$"Automatic departure exception: {arg}"); } } private static bool IsInputBlocked() { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val != (Object)null) { if (val.inTerminalMenu) { RemoteLeverPlugin.Log.LogInfo((object)"Remote lever blocked: terminal menu open."); return true; } if (val.isTypingChat) { RemoteLeverPlugin.Log.LogInfo((object)"Remote lever blocked: player is typing chat."); return true; } } Terminal val2 = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val2 != (Object)null && val2.terminalInUse) { RemoteLeverPlugin.Log.LogInfo((object)"Remote lever blocked: terminal is in use."); return true; } return false; } private static int GetConfiguredTargetMinutes() { int num = RemoteLeverPlugin.AutoDepartureHour.Value; int value = RemoteLeverPlugin.AutoDepartureMinute.Value; string value2 = RemoteLeverPlugin.AutoDepartureAmPm.Value; if (value2 == "AM") { if (num == 12) { num = 0; } } else if (num != 12) { num += 12; } return num * 60 + value; } private static int GetCurrentGameTimeMinutes(TimeOfDay timeOfDay) { int num = Mathf.FloorToInt(timeOfDay.normalizedTimeOfDay * (60f * (float)timeOfDay.numberOfHours)); num += 360; return num % 1440; } private static string FormatTime12Hour(int totalMinutes) { totalMinutes %= 1440; int num = totalMinutes / 60; int num2 = totalMinutes % 60; string arg = ((num >= 12) ? "PM" : "AM"); int num3 = num % 12; if (num3 == 0) { num3 = 12; } return $"{num3}:{num2:00} {arg}"; } private static void CheckManualLeverInput(StartOfRound round) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (Keyboard.current == null) { return; } Key value = RemoteLeverPlugin.LeverKey.Value; if ((int)value == 0) { return; } ButtonControl val = (ButtonControl)(object)Keyboard.current[value]; if (val == null || !val.wasPressedThisFrame || IsInputBlocked()) { return; } if (RemoteLeverPlugin.IsLeverLocked(round)) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: eject/reset sequence is in progress."); RemoteLeverPlugin.ShowTip("Remote Lever", "Remote Lever cannot be used while the eject sequence is in progress."); } else { if (Time.time - lastPressTime < 0.5f) { return; } lastPressTime = Time.time; if ((Object)(object)GameNetworkManager.Instance == (Object)null) { return; } if (!GameNetworkManager.Instance.isHostingGame) { HUDManager.Instance.DisplayTip("Remote Lever", "Only the host can control the ship.", false, false, "LC_Tip1"); return; } StartMatchLever val2 = Object.FindObjectOfType<StartMatchLever>(); if (!((Object)(object)val2 == (Object)null)) { try { if (round.shipIsLeaving) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: ship is already leaving."); } else if (round.travellingToNewLevel) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: travelling to a new level."); } else if (round.beganLoadingNewLevel) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: new level loading has begun."); } else if (round.shipLeftAutomatically) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: ship already left automatically."); } else if ((Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonIsGenerating) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: dungeon is generating."); } else if (round.inShipPhase) { if (round.shipHasLanded) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: inconsistent Orbit state (inShipPhase=true, shipHasLanded=true)."); } else { RemoteLeverPlugin.Log.LogInfo((object)"Triggering landing remotely..."); val2.LeverAnimation(); val2.StartGame(); HUDManager.Instance.AddTextToChatOnServer("<color=#00FFFF>[RemoteLever]</color> Ship landing initiated remotely.", -1); } } else if (!round.shipHasLanded) { RemoteLeverPlugin.Log.LogWarning((object)"Remote lever ignored: ship has not landed."); } else { RemoteLeverPlugin.Log.LogInfo((object)"Triggering departure remotely..."); autoDepartureTriggered = true; val2.LeverAnimation(); val2.EndGame(); HUDManager.Instance.AddTextToChatOnServer("<color=#00FFFF>[RemoteLever]</color> Ship departure initiated remotely.", -1); } return; } catch (Exception arg) { RemoteLeverPlugin.Log.LogError((object)$"Remote lever exception: {arg}"); return; } } RemoteLeverPlugin.Log.LogWarning((object)"StartMatchLever not found."); } } } [HarmonyPatch(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc")] internal static class FirePlayersAfterDeadlinePatch { [HarmonyPrefix] private static void Prefix() { RemoteLeverPlugin.LockLeverForReset(); } } [HarmonyPatch(typeof(StartOfRound), "EndPlayersFiredSequenceClientRpc")] internal static class EndPlayersFiredSequencePatch { [HarmonyPostfix] private static void Postfix() { RemoteLeverPlugin.UnlockLeverAfterReset(); } } [HarmonyPatch(typeof(StartMatchLever), "EndGame")] internal static class StartMatchLeverEndGamePatch { [HarmonyPrefix] private static bool Prefix(StartMatchLever __instance) { StartOfRound playersManager = __instance.playersManager; if ((Object)(object)playersManager == (Object)null) { return true; } if (RemoteLeverPlugin.IsLeverLocked(playersManager)) { RemoteLeverPlugin.Log.LogWarning((object)"EndGame blocked: eject/reset sequence is in progress."); return false; } return true; } } [HarmonyPatch(typeof(StartMatchLever), "StartGame")] internal static class StartMatchLeverStartGamePatch { [HarmonyPrefix] private static bool Prefix(StartMatchLever __instance) { StartOfRound playersManager = __instance.playersManager; if ((Object)(object)playersManager == (Object)null) { return true; } if (RemoteLeverPlugin.IsLeverLocked(playersManager)) { RemoteLeverPlugin.Log.LogWarning((object)"StartGame blocked: eject/reset sequence is in progress."); return false; } return true; } }