From dbf65b45992b2fbe5a46150772de3f634e6b4c08 Mon Sep 17 00:00:00 2001 From: Lyndomen <49795619+Lyndomen@users.noreply.github.com> Date: Tue, 18 Feb 2025 23:21:12 -0500 Subject: [PATCH] =?UTF-8?q?port=20auto=20ahelp=20spam=20ban=20and=20ahelp?= =?UTF-8?q?=20cooldown=20from=20=E2=AD=90STARLIGHT=E2=AD=90=20(#3010)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit starlight license time --- .../Administration/Systems/BwoinkSystem.cs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Content.Server/Administration/Systems/BwoinkSystem.cs b/Content.Server/Administration/Systems/BwoinkSystem.cs index 6276304a75..e4220abc45 100644 --- a/Content.Server/Administration/Systems/BwoinkSystem.cs +++ b/Content.Server/Administration/Systems/BwoinkSystem.cs @@ -18,6 +18,7 @@ using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.GameTicking; using Content.Shared.Mind; +using Content.Shared.Database; // Starlight using Content.Shared.Players.RateLimiting; using JetBrains.Annotations; using Robust.Server.Player; @@ -38,6 +39,7 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IAdminManager _adminManager = default!; + [Dependency] private readonly IBanManager _banManager = default!; // Starlight [Dependency] private readonly IConfigurationManager _config = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPlayerLocator _playerLocator = default!; @@ -80,6 +82,14 @@ namespace Content.Server.Administration.Systems // Should be shorter than DescriptionMax private const ushort MessageLengthCap = 3000; + // Begin Starlight additions + private readonly TimeSpan _messageCooldown = TimeSpan.FromSeconds(2); + + private readonly Queue<(NetUserId Channel, string Text, TimeSpan Timestamp)> _recentMessages = new(); + private const int MaxRecentMessages = 10; + private const int SpamCheckMessageCount = 3; + // End Starlight additions + // Text to be used to cut off messages that are too long. Should be shorter than MessageLengthCap private const string TooLongText = "... **(too long)**"; @@ -726,6 +736,18 @@ namespace Content.Server.Administration.Systems return; } + // Begin Starlight Changes + var currentTime = _timing.RealTime; + + if (IsOnCooldown(message.UserId, currentTime)) + return; + + if (IsSpam(message.UserId, message.Text)) + _banManager.CreateServerBan(senderSession.UserId, senderSession.Name, null, null, null, 0, NoteSeverity.High, "Automatic AHELP Antispam system Ban, If this ban is wrong, file an appeal."); + + AddToRecentMessages(message.UserId, message.Text, currentTime); + // End Starlight Changes + if (_rateLimit.CountAction(eventArgs.SenderSession, RateLimitKey) != RateLimitStatus.Allowed) return; @@ -993,6 +1015,43 @@ namespace Content.Server.Administration.Systems /// public bool OnCall; } + + // Begin Starlight Changes + private void AddToRecentMessages(NetUserId channelId, string text, TimeSpan timestamp) + { + _recentMessages.Enqueue((channelId, text, timestamp)); + + if (_recentMessages.Count > MaxRecentMessages) + { + _recentMessages.Dequeue(); + } + } + + private bool IsOnCooldown(NetUserId channelId, TimeSpan currentTime) + { + var lastMessage = _recentMessages + .Where(msg => msg.Channel == channelId) + .OrderByDescending(msg => msg.Timestamp) + .FirstOrDefault(); + + return lastMessage != default && (currentTime - lastMessage.Timestamp) < _messageCooldown; + } + + private bool IsSpam(NetUserId channelId, string text) + { + var recentMessages = _recentMessages + .Where(msg => msg.Channel == channelId) + .OrderByDescending(msg => msg.Timestamp) + .Take(10); + + return recentMessages.All(msg => msg.Text == text) && recentMessages.Count() >= 5; + } + + public IEnumerable<(NetUserId Channel, string Text, TimeSpan Timestamp)> GetRecentMessages() + { + return _recentMessages; + } + // End Starlight Changes } public sealed class AHelpMessageParams