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 SafeLogoutTimer v0.9.3
plugins/SafeLogoutTimer/SafeLogoutTimer.dll
Decompiled a month agousing System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using Jotunn.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("SafeLogoutTimer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SafeLogoutTimer")] [assembly: AssemblyTitle("SafeLogoutTimer")] [assembly: AssemblyVersion("1.0.0.0")] namespace SafeLogoutTimer; [BepInPlugin("local.valheim.safelogouttimer", "Safe Logout Timer", "0.9.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { private enum CountdownAction { None, Logout, Quit } [HarmonyPatch(typeof(Menu), "OnLogoutYes")] private static class MenuLogoutPatch { private static bool Prefix(Menu __instance) { if (!((Object)(object)_instance == (Object)null)) { return _instance.BeginCountdown(__instance, CountdownAction.Logout); } return true; } } [HarmonyPatch(typeof(Menu), "OnQuitYes")] private static class MenuQuitPatch { private static bool Prefix(Menu __instance) { if (!((Object)(object)_instance == (Object)null)) { return _instance.BeginCountdown(__instance, CountdownAction.Quit); } return true; } } [HarmonyPatch(typeof(Menu), "Show")] private static class MenuShowPatch { private static bool Prefix() { if ((Object)(object)_instance == (Object)null || _instance._countdownAction == CountdownAction.None) { return true; } int seconds = Mathf.Max(0, Mathf.CeilToInt(_instance._countdownEnd - Time.realtimeSinceStartup)); _instance.ShowCountdownMessage(seconds); return false; } } [HarmonyPatch(typeof(Player), "OnDamaged")] private static class PlayerDamagedPatch { private static void Postfix(Player __instance, HitData hit) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && hit != null && hit.GetTotalDamage() > 0f) { _instance?.CancelForAction(); } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] private static class PlayerAttackPatch { private static void Postfix(Humanoid __instance, bool __result) { if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { _instance?.CancelForAction(); } } } public const string PluginGuid = "local.valheim.safelogouttimer"; public const string PluginName = "Safe Logout Timer"; public const string PluginVersion = "0.9.3"; private const int LogoutSeconds = 10; private const float MovementToleranceMeters = 0.75f; private static Plugin _instance; private static bool _allowVanillaAction; private CountdownAction _countdownAction; private Menu _countdownMenu; private Vector3 _countdownStartPosition; private float _countdownEnd; private int _lastShownSecond = -1; private Coroutine _countdownCoroutine; private void Awake() { _instance = this; Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "local.valheim.safelogouttimer"); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded; timer={2}s, Alt+F4 ignored", "Safe Logout Timer", "0.9.3", 10)); } private void OnDestroy() { if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private bool BeginCountdown(Menu menu, CountdownAction action) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (_allowVanillaAction || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return true; } if (_countdownAction != CountdownAction.None) { int seconds = Mathf.Max(0, Mathf.CeilToInt(_countdownEnd - Time.realtimeSinceStartup)); menu.Hide(); ShowCountdownMessage(seconds); return false; } _countdownAction = action; _countdownMenu = menu; _countdownStartPosition = ((Component)Player.m_localPlayer).transform.position; _countdownEnd = Time.realtimeSinceStartup + 10f; _lastShownSecond = -1; menu.Hide(); ShowCountdownMessage(10); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Started {action} countdown ({10}s)"); _countdownCoroutine = ((MonoBehaviour)this).StartCoroutine(CountdownRoutine()); return false; } private IEnumerator CountdownRoutine() { while (_countdownAction != CountdownAction.None) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { CancelCountdown(null); break; } float num = 0.5625f; Vector3 val = ((Component)localPlayer).transform.position - _countdownStartPosition; if (((Vector3)(ref val)).sqrMagnitude > num) { CancelCountdown("Wylogowanie anulowane — poruszyłeś się"); break; } int num2 = Mathf.Max(0, Mathf.CeilToInt(_countdownEnd - Time.realtimeSinceStartup)); if (num2 != _lastShownSecond) { ShowCountdownMessage(num2); } if (Time.realtimeSinceStartup >= _countdownEnd) { ExecuteVanillaAction(); break; } yield return null; } } private void ShowCountdownMessage(int seconds) { _lastShownSecond = seconds; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, (seconds > 0) ? $"Wylogowanie za {seconds} s — nie ruszaj się" : "Wylogowywanie…", 0, (Sprite)null, false); } } private void CancelCountdown(string reason) { if (_countdownAction != CountdownAction.None) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Cancelled {_countdownAction} countdown"); _countdownAction = CountdownAction.None; _countdownMenu = null; _countdownCoroutine = null; if (!string.IsNullOrEmpty(reason) && (Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, reason, 0, (Sprite)null, false); } } } private void ExecuteVanillaAction() { CountdownAction countdownAction = _countdownAction; Menu countdownMenu = _countdownMenu; _countdownAction = CountdownAction.None; _countdownMenu = null; _countdownCoroutine = null; if ((Object)(object)countdownMenu == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Countdown completed, but the menu instance is no longer available"); return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Completed {countdownAction} countdown; invoking the original game action"); _allowVanillaAction = true; try { switch (countdownAction) { case CountdownAction.Logout: countdownMenu.OnLogoutYes(); break; case CountdownAction.Quit: countdownMenu.OnQuitYes(); break; } } finally { _allowVanillaAction = false; } } private void CancelForAction() { CancelCountdown("Wylogowanie anulowane — wykonałeś akcję"); } }