Please disclose if your mod was created primarily 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 NoDrowsyDragonDriving v1.0.0
NoDrowsyDragonDriving.dll
Decompiled 17 hours agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("NoDrowsyDragonDriving")] [assembly: AssemblyDescription("Preserves saddle riding during SleepSkip vote flow.")] [assembly: AssemblyCompany("sighsorry")] [assembly: AssemblyProduct("NoDrowsyDragonDriving")] [assembly: AssemblyCopyright("Copyright (c) sighsorry")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 NoDrowsyDragonDriving { [BepInPlugin("sighsorry.NoDrowsyDragonDriving", "NoDrowsyDragonDriving", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class NoDrowsyDragonDrivingPlugin : BaseUnityPlugin { internal const string ModGuid = "sighsorry.NoDrowsyDragonDriving"; internal const string ModName = "NoDrowsyDragonDriving"; internal const string ModVersion = "1.0.0"; private const string ConfigFileName = "sighsorry.NoDrowsyDragonDriving.cfg"; private static readonly string ConfigFileFullPath = Path.Combine(Paths.ConfigPath, "sighsorry.NoDrowsyDragonDriving.cfg"); internal static readonly ManualLogSource Log = Logger.CreateLogSource("NoDrowsyDragonDriving"); internal static ConfigEntry<bool>? DetachGuardEnabled; internal static ConfigEntry<int>? DetachGuardGraceWindowMs; internal static ConfigEntry<int>? DetachGuardGraceMaxUses; internal static ConfigEntry<int>? DetachGuardGraceMaxFrames; private readonly Harmony _harmony = new Harmony("sighsorry.NoDrowsyDragonDriving"); private FileSystemWatcher? _configWatcher; private DateTime _lastConfigReloadUtc = DateTime.MinValue; private static readonly TimeSpan ConfigReloadDebounce = TimeSpan.FromMilliseconds(250.0); private void Awake() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown DetachGuardEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enable Riding Detach Guard", true, "Enable/disable riding detach guard during sleep-stop flow. This setting updates live."); DetachGuardEnabled.SettingChanged += OnDetachGuardSettingChanged; DetachGuardGraceWindowMs = ((BaseUnityPlugin)this).Config.Bind<int>("1 - General", "Detach Guard Extra Window (ms)", 300, new ConfigDescription("Extra post-SleepStop guard window in milliseconds for off-stack detach calls. 0 disables.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2000), Array.Empty<object>())); DetachGuardGraceWindowMs.SettingChanged += OnDetachGuardTuningChanged; DetachGuardGraceMaxUses = ((BaseUnityPlugin)this).Config.Bind<int>("1 - General", "Detach Guard Extra Blocks", 2, new ConfigDescription("How many detach calls can be blocked during the extra post-SleepStop window. 0 disables.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), Array.Empty<object>())); DetachGuardGraceMaxUses.SettingChanged += OnDetachGuardTuningChanged; DetachGuardGraceMaxFrames = ((BaseUnityPlugin)this).Config.Bind<int>("1 - General", "Detach Guard Extra Window (frames)", 6, new ConfigDescription("Maximum frame distance from SleepStop for extra off-stack guard blocks. Lower values reduce false positives.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 120), Array.Empty<object>())); DetachGuardGraceMaxFrames.SettingChanged += OnDetachGuardTuningChanged; SetupWatcher(); _harmony.PatchAll(); Log.LogInfo((object)"NoDrowsyDragonDriving loaded"); Log.LogInfo((object)string.Format("{0}: guard={1}, graceWindowMs={2}, graceFrames={3}, graceBlocks={4}", "NoDrowsyDragonDriving", DetachGuardEnabled?.Value ?? true, DetachGuardGraceWindowMs?.Value ?? 0, DetachGuardGraceMaxFrames?.Value ?? 0, DetachGuardGraceMaxUses?.Value ?? 0)); } private void OnDestroy() { if (DetachGuardEnabled != null) { DetachGuardEnabled.SettingChanged -= OnDetachGuardSettingChanged; } if (DetachGuardGraceWindowMs != null) { DetachGuardGraceWindowMs.SettingChanged -= OnDetachGuardTuningChanged; } if (DetachGuardGraceMaxUses != null) { DetachGuardGraceMaxUses.SettingChanged -= OnDetachGuardTuningChanged; } if (DetachGuardGraceMaxFrames != null) { DetachGuardGraceMaxFrames.SettingChanged -= OnDetachGuardTuningChanged; } _configWatcher?.Dispose(); _harmony.UnpatchSelf(); } private void SetupWatcher() { _configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sighsorry.NoDrowsyDragonDriving.cfg") { IncludeSubdirectories = false, SynchronizingObject = ThreadingHelper.SynchronizingObject, EnableRaisingEvents = true }; _configWatcher.Changed += ReadConfigValues; _configWatcher.Created += ReadConfigValues; _configWatcher.Renamed += ReadConfigValues; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } DateTime utcNow = DateTime.UtcNow; if (utcNow - _lastConfigReloadUtc < ConfigReloadDebounce) { return; } _lastConfigReloadUtc = utcNow; try { ((BaseUnityPlugin)this).Config.Reload(); } catch (Exception ex) { Log.LogError((object)("NoDrowsyDragonDriving: failed to reload config. " + ex.GetType().Name + ": " + ex.Message)); } } private void OnDetachGuardSettingChanged(object? sender, EventArgs e) { bool flag = DetachGuardEnabled?.Value ?? true; if (!flag) { SleepSkipRidingState.ClearDetachBlockState(); } Log.LogInfo((object)("NoDrowsyDragonDriving: Riding detach guard " + (flag ? "enabled" : "disabled") + " (live update).")); } private void OnDetachGuardTuningChanged(object? sender, EventArgs e) { int num = Math.Max(0, DetachGuardGraceWindowMs?.Value ?? 0); int num2 = Math.Max(0, DetachGuardGraceMaxUses?.Value ?? 0); int num3 = Math.Max(0, DetachGuardGraceMaxFrames?.Value ?? 0); SleepSkipRidingState.TrimDetachGraceStateToCurrentConfig(); Log.LogInfo((object)string.Format("{0}: Detach guard extra window updated (window={1}ms, frames={2}, blocks={3}).", "NoDrowsyDragonDriving", num, num3, num2)); } } [HarmonyPatch] internal static class SleepSkipOpenMenuPatch { private const string TargetTypeName = "SleepSkip.SleepSkipPlugin"; private const string TargetMethodName = "OpenMenuOnClient"; private const string VoteYesRpcName = "VoteYes"; private const string VoteNoRpcName = "VoteNo"; private static MethodBase? TargetMethod() { return AccessTools.Method("SleepSkip.SleepSkipPlugin:OpenMenuOnClient", (Type[])null, (Type[])null); } private static bool Prefix() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } if (!SleepSkipRidingState.IsPlayerRidingSaddle(localPlayer)) { return true; } switch (SleepSkipRidingState.GetPopupAutoChoice()) { case SleepSkipRidingState.PopupAutoChoiceSetting.AlwaysAccept: SleepSkipRidingState.SendVote("VoteYes"); return false; case SleepSkipRidingState.PopupAutoChoiceSetting.AlwaysDecline: SleepSkipRidingState.SendVote("VoteNo"); return false; default: return true; } } } [HarmonyPatch(typeof(Game), "SleepStop")] internal static class GameSleepStopPatch { private static void Prefix() { SleepSkipRidingState.EnterSleepStopScope(); if (SleepSkipRidingState.IsDetachGuardEnabled()) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && SleepSkipRidingState.IsPlayerRidingSaddle(localPlayer)) { SleepSkipRidingState.ArmDetachBlock(); } } } private static Exception? Finalizer(Exception? __exception) { SleepSkipRidingState.ExitSleepStopScope(); return __exception; } } [HarmonyPatch(typeof(Character), "AttachStop")] internal static class CharacterAttachStopPatch { private static bool Prefix(Character __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } return !SleepSkipRidingState.ShouldBlockDetach(); } } [HarmonyPatch(typeof(Player), "AttachStop")] internal static class PlayerAttachStopPatch { private static bool Prefix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } return !SleepSkipRidingState.ShouldBlockDetach(); } } [HarmonyPatch(typeof(Player), "StopDoodadControl")] internal static class PlayerStopDoodadControlPatch { private static bool Prefix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } return !SleepSkipRidingState.ShouldBlockDetach(); } } internal static class SleepSkipRidingState { internal enum PopupAutoChoiceSetting { Ask, AlwaysAccept, AlwaysDecline } private const string SleepSkipTypeName = "SleepSkip.SleepSkipPlugin"; private const string PopupAutoChoiceFieldName = "PopupAutoChoice"; private const double BlockTimeoutSeconds = 2.0; private static DateTime s_detachBlockUntilUtc = DateTime.MinValue; private static DateTime s_detachGraceUntilUtc = DateTime.MinValue; private static int s_detachGraceRemaining; private static DateTime s_lastSleepStopUtc = DateTime.MinValue; private static int s_lastSleepStopFrame = -1; private static int s_sleepStopScopeDepth; private static PropertyInfo? s_popupChoiceValueProperty; private static bool s_loggedPopupChoiceFieldMissing; private static bool s_loggedPopupChoiceReadFailed; private static readonly Type? SleepSkipType = AccessTools.TypeByName("SleepSkip.SleepSkipPlugin"); private static readonly FieldInfo? PopupAutoChoiceField = ((SleepSkipType != null) ? AccessTools.Field(SleepSkipType, "PopupAutoChoice") : null); internal static bool IsPlayerRidingSaddle(Player player) { if (!((Character)player).IsAttached()) { return false; } try { IDoodadController doodadController = player.GetDoodadController(); return doodadController is Sadle; } catch { return false; } } internal static bool IsDetachGuardEnabled() { return NoDrowsyDragonDrivingPlugin.DetachGuardEnabled?.Value ?? true; } internal static void ArmDetachBlock() { if (IsDetachGuardEnabled()) { DateTime dateTime = (s_lastSleepStopUtc = DateTime.UtcNow); s_lastSleepStopFrame = Time.frameCount; s_detachBlockUntilUtc = dateTime.AddSeconds(2.0); int num = Math.Max(0, NoDrowsyDragonDrivingPlugin.DetachGuardGraceWindowMs?.Value ?? 0); int num2 = Math.Max(0, NoDrowsyDragonDrivingPlugin.DetachGuardGraceMaxUses?.Value ?? 0); if (num > 0 && num2 > 0) { s_detachGraceUntilUtc = dateTime.AddMilliseconds(num); s_detachGraceRemaining = num2; } else { s_detachGraceUntilUtc = DateTime.MinValue; s_detachGraceRemaining = 0; } } } internal static void EnterSleepStopScope() { s_sleepStopScopeDepth++; } internal static void ExitSleepStopScope() { s_sleepStopScopeDepth = Math.Max(0, s_sleepStopScopeDepth - 1); } internal static void ClearDetachBlockState() { s_detachBlockUntilUtc = DateTime.MinValue; s_detachGraceUntilUtc = DateTime.MinValue; s_detachGraceRemaining = 0; s_lastSleepStopUtc = DateTime.MinValue; s_lastSleepStopFrame = -1; s_sleepStopScopeDepth = 0; } internal static void TrimDetachGraceStateToCurrentConfig() { int num = Math.Max(0, NoDrowsyDragonDrivingPlugin.DetachGuardGraceWindowMs?.Value ?? 0); int num2 = Math.Max(0, NoDrowsyDragonDrivingPlugin.DetachGuardGraceMaxUses?.Value ?? 0); if (num <= 0 || num2 <= 0) { s_detachGraceUntilUtc = DateTime.MinValue; s_detachGraceRemaining = 0; } else if (s_detachGraceRemaining > num2) { s_detachGraceRemaining = num2; } } internal static bool ShouldBlockDetach() { if (!IsDetachGuardEnabled()) { return false; } DateTime utcNow = DateTime.UtcNow; bool flag = utcNow <= s_detachBlockUntilUtc; bool flag2 = utcNow <= s_detachGraceUntilUtc && s_detachGraceRemaining > 0; if (!flag && !flag2) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !IsPlayerRidingSaddle(localPlayer)) { return false; } if (s_sleepStopScopeDepth > 0) { return true; } if (!flag2) { return false; } int frameBudget = Math.Max(0, NoDrowsyDragonDrivingPlugin.DetachGuardGraceMaxFrames?.Value ?? 0); if (!IsRecentSleepStop(frameBudget, utcNow)) { return false; } s_detachGraceRemaining = Math.Max(0, s_detachGraceRemaining - 1); return true; } private static bool IsRecentSleepStop(int frameBudget, DateTime nowUtc) { if (s_lastSleepStopUtc == DateTime.MinValue || s_lastSleepStopFrame < 0) { return false; } if (nowUtc > s_detachGraceUntilUtc) { return false; } if (frameBudget <= 0) { return false; } int num = Time.frameCount - s_lastSleepStopFrame; if (num < 0) { return false; } return num <= frameBudget; } internal static PopupAutoChoiceSetting GetPopupAutoChoice() { if (PopupAutoChoiceField == null) { if (!s_loggedPopupChoiceFieldMissing) { s_loggedPopupChoiceFieldMissing = true; NoDrowsyDragonDrivingPlugin.Log.LogWarning((object)"SleepSkip PopupAutoChoice field was not found. Falling back to Ask."); } return PopupAutoChoiceSetting.Ask; } try { object value = PopupAutoChoiceField.GetValue(null); if (value == null) { return PopupAutoChoiceSetting.Ask; } if ((object)s_popupChoiceValueProperty == null) { s_popupChoiceValueProperty = value.GetType().GetProperty("Value"); } if (s_popupChoiceValueProperty == null) { if (!s_loggedPopupChoiceReadFailed) { s_loggedPopupChoiceReadFailed = true; NoDrowsyDragonDrivingPlugin.Log.LogWarning((object)"SleepSkip PopupAutoChoice.Value property was not found. Falling back to Ask."); } return PopupAutoChoiceSetting.Ask; } string text = s_popupChoiceValueProperty.GetValue(value)?.ToString() ?? string.Empty; if (1 == 0) { } PopupAutoChoiceSetting result = ((text == "AlwaysAccept") ? PopupAutoChoiceSetting.AlwaysAccept : ((text == "AlwaysDecline") ? PopupAutoChoiceSetting.AlwaysDecline : PopupAutoChoiceSetting.Ask)); if (1 == 0) { } return result; } catch (Exception ex) { if (!s_loggedPopupChoiceReadFailed) { s_loggedPopupChoiceReadFailed = true; NoDrowsyDragonDrivingPlugin.Log.LogWarning((object)("Failed to read SleepSkip PopupAutoChoice. Falling back to Ask. " + ex.GetType().Name + ": " + ex.Message)); } return PopupAutoChoiceSetting.Ask; } } internal static void SendVote(string rpcName) { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, rpcName, new object[1] { ZNet.GetUID() }); } } } }