]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add small cooldown to NukeKeypadEnterMessages (#41831)
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Fri, 12 Dec 2025 00:58:51 +0000 (01:58 +0100)
committerGitHub <noreply@github.com>
Fri, 12 Dec 2025 00:58:51 +0000 (00:58 +0000)
* cooldown

* d

* time offset serializer

* undo button disabling according to feedback

* Update Content.Client/Nuke/NukeBoundUserInterface.cs

Content.Server/Nuke/NukeComponent.cs
Content.Server/Nuke/NukeSystem.cs
Content.Shared/Nuke/NukeUiMessages.cs

index cd1c0227eb83c5812afda2314fe79efe7cf7d225..e46680460f3b9987db9bc92a5623e58d3326ddbb 100644 (file)
@@ -5,6 +5,7 @@ using Content.Shared.Explosion;
 using Content.Shared.Nuke;
 using Robust.Shared.Audio;
 using Robust.Shared.Map;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
 using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
 
 namespace Content.Server.Nuke
@@ -164,6 +165,14 @@ namespace Content.Server.Nuke
         [DataField]
         public string EnteredCode = "";
 
+        /// <summary>
+        ///     Time at which the last nuke code was entered.
+        ///     Used to apply a cooldown to prevent clients from attempting to brute force the nuke code by sending keypad messages every tick.
+        ///     <seealso cref="SharedNukeComponent.EnterCodeCooldown"/>
+        /// </summary>
+        [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
+        public TimeSpan LastCodeEnteredAt = TimeSpan.Zero;
+
         /// <summary>
         ///     Current status of a nuclear bomb.
         /// </summary>
index 3788d2b2ab57268d439336ab452015cd35f357a2..130cc1965629e61b2aa290848c821d283d07c7d6 100644 (file)
@@ -18,11 +18,10 @@ using Robust.Server.GameObjects;
 using Robust.Shared.Audio;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Containers;
-using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
-using Robust.Shared.Player;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
+using Robust.Shared.Timing;
 
 namespace Content.Server.Nuke;
 
@@ -45,6 +44,7 @@ public sealed class NukeSystem : EntitySystem
     [Dependency] private readonly UserInterfaceSystem _ui = default!;
     [Dependency] private readonly AppearanceSystem _appearance = default!;
     [Dependency] private readonly TurfSystem _turf = default!;
+    [Dependency] private readonly IGameTiming _timing = default!;
 
     /// <summary>
     ///     Used to calculate when the nuke song should start playing for maximum kino with the nuke sfx
@@ -232,6 +232,12 @@ public sealed class NukeSystem : EntitySystem
         if (component.Status != NukeStatus.AWAIT_CODE)
             return;
 
+        var curTime = _timing.CurTime;
+        if (curTime < component.LastCodeEnteredAt + SharedNukeComponent.EnterCodeCooldown)
+            return; // Validate that they are not entering codes faster than the cooldown.
+
+        component.LastCodeEnteredAt = curTime;
+
         UpdateStatus(uid, component);
         UpdateUserInterface(uid, component);
     }
index 1c35cac7b079dd76c0b9409802ba47b46074e17f..8f5e16395c3db75ebbad89f179c186e844f82c16 100644 (file)
@@ -5,6 +5,12 @@ namespace Content.Shared.Nuke
     public abstract partial class SharedNukeComponent : Component
     {
         public const string NukeDiskSlotId = "Nuke";
+
+        /// <summary>
+        /// Cooldown time between attempts to enter the nuke code.
+        /// Used to prevent clients from trying to brute force it.
+        /// </summary>
+        public static readonly TimeSpan EnterCodeCooldown = TimeSpan.FromSeconds(1);
     }
 
     [Serializable, NetSerializable]