Skip to content

Commit

Permalink
Merge Upstream (space-wizards#343)
Browse files Browse the repository at this point in the history
* Fix double label on chem jugs (space-wizards#29137)

* Automatic changelog update

* Fix DresserFilled storagefill rarely causing an error (space-wizards#29135)

Add ClothingUniformJumpskirtColorPink to an OrGroup

* Fix female reptilians not having gasp sounds (space-wizards#29143)

inital

* clean up weather systems (space-wizards#28792)

* clean up weather systems

* Update WeatherComponent.cs

* Update SharedWeatherSystem.cs

* some fix

* Update SharedWeatherSystem.cs

* Update WeatherComponent.cs

* Update WeatherComponent.cs

* revert autoPause

* Update SharedWeatherSystem.cs

* Implement vital chef's hat functionality (space-wizards#25950)

* Implement crucial chef's hat functionality

* Unified stopping code and added events.

* Added documentation to events

* Rerun tests

* Made review changes, and fixed potential desync bug.

* Update whitelist

* Automatic changelog update

* Add cvar to disable round end pvs overrides (space-wizards#29151)

* Update submodule to 226.1.0 (space-wizards#29159)

* Fix conveyor mispredicts (space-wizards#28157)

* Fix conveyor mispredicts

Instead of tracking active conveyors we instead track the conveyed entities. This also handles things like stacking conveyors more gracely.

* Fix ActiveConveyor

* Fix lerping

* Automatic changelog update

* Replace StationRandomTransform (space-wizards#29149)

* Revert "Rotate and Offset station CCVar nuke (space-wizards#26175)"

This reverts commit 44b20f6.

# Conflicts:
#	Content.Server/Station/Systems/StationSystem.cs
#	Resources/Prototypes/Maps/europa.yml

* Fix

* Review

* Add warning cones to engivend (space-wizards#29085)

Add cones to engivend

* Automatic changelog update

* arachnid inventory layout fix (space-wizards#29165)

arachnid inventory layout fixC

* Automatic changelog update

* Turn interaction related attempt events into structs (space-wizards#29168)

* Turn InteractionAttemptEvent into a struct event

* readonly

* GettingInteractedWithAttemptEvent

* ConsciousAttemptEvent

* Add the most anticipated gun in the game. Foam Force. (space-wizards#29103)

* Foam Force

* make it available somewhere

* add clumsyproof and nuke dev item

* reorganize

* oopsy files

* Strap!

* woopsie layering

* fix grammar to rerun tests for rogue unrelated test fail.

* cleanup

* I eepy layer forgetti spaghetti

* For real last necessary commit

* Oops I broke the law! feexed

* Decided to just change it to the same source as the poster source in our repo for consistency.

* Automatic changelog update

* Fix material storage going BRRT (space-wizards#29167)

If the volume hits 0 we just remove it.

* Automatic changelog update

* Fix air alarms (space-wizards#29172)

Broken by space-wizards#28272

* Automatic changelog update

* Hidden loadout groups (space-wizards#29170)

* loadout hiding

* department of redundancy department

* Upgrade rsi-diff's changed files action | Make it only return rsi and png changes (space-wizards#29185)

It was brought up to me in space-wizards#29179 (comment) (and from a dm from them) that space bars can cause issues with the rsi bot.

Upon investigation its case we use "space-delimited" on the "get changes files" check. Which returns ALL changed files. Even if the change has nothing to do with png's or rsi's (example a downstream merging upstream)

* unhardcode thief MaxSelectedSets (space-wizards#29175)

* unhardcode thief MaxSelectedSets

* we do a little copy paste :trollface:

* :trollface:

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>

* PullingController cooldown change (space-wizards#29177)

* Revert "Automatic changelog update"

This reverts commit 3358aef.

* Revert "Revert "Automatic changelog update""

This reverts commit 3d0b6a7.

* Removal of the throw cooldown as it felt sluggish and unresponsive before.

* Decrease meteor frequency (space-wizards#29194)

* Automatic changelog update

* Security Resprite (space-wizards#29082)

* security resprite

* hos cap fix

* i forgor

* further fixes

* my furniture is broken

* fedora update

* Automatic changelog update

* Make Hamlet a valid chef's hat pilot (space-wizards#29191)

* Fix Underwing wings (space-wizards#29092)

* add

* tweak thickness of stripe

* Add some happier medibot messages! (space-wizards#29147)

* Happy!

* opps

* one more

* Automatic changelog update

* shorten short raffle (space-wizards#28685)

* Automatic changelog update

* Fix some lathe recipe textures showing up blank (space-wizards#28683)

* Update lathes to use entity prototype

* ScrollContainer my hero

* gets rid of excess newlines

---------

Co-authored-by: plykiya <plykiya@protonmail.com>

* Grammar fix to medibot! (space-wizards#29197)

fixed

* Restore default panic bunker and tweak baby jail (space-wizards#29198)

restore default panic bunker

* Fixed cartridges installing more than once (space-wizards#29187)

* fixed cartridges installing more than once

* replaced prototypes with CartridgeComponent

* relocated checks from InstallProgram to InstallCartridge

* Automatic changelog update

* Musician's skirt (space-wizards#29203)

* Sprites&Meta

* Changing prototypes

* Adding to Theater vend

* Sprite_Change

* Sprite_Change

* Prototype_Changes

Is this exactly how it should be?...

* FUCKING FIX

* weh

---------

Co-authored-by: Арт <123451459+JustArt1m@users.noreply.github.com>

* Automatic changelog update

* hos cap resprite (space-wizards#29208)

* hos cap resprite

* 1. 2. 3 4 Oh

* Automatic changelog update

* Rejig device link sink & source startup & shutdown (space-wizards#29035)

* Fix DeviceLinkSinkComponent not updating sources on shutdown

* Log error

* Misc link changes & fixes

* Fix core

* Add prediction for Tech Disks, cleanup (space-wizards#29061)

* Add prediction for Tech Disks, cleanup

* Remove IsServer check in OnMapInit

* Use HashSet for techs, remove LINQ

* Code cleanup: radio jammer (space-wizards#29052)

* Code cleanup for radio jammer

* More Entity<T> for the people, and fix an accidental variable reuse

* Partial buckling refactor (space-wizards#29031)

* partial buckling refactor

* git mv test

* change test namespace

* git mv test

* Update test namespace

* Add pulling test

* Network BuckleTime

* Add two more tests

* smelly

* Fix documentation typo (space-wizards#29209)

Fix everything.

* Emergency toolbox fill rework (space-wizards#29202)

* emergency toolbox fill rework

* Fuck

* Add wet floor sign & warning cone to autolathe (space-wizards#29205)

* Add wet floor sign & warning cone to autolathe

* removing

* Automatic changelog update

* Tools batch files (space-wizards#29179)

* Tools batch files

* fine

* Fix terrible portable scrubber unlit layers (space-wizards#29232)

Jesus fucking christ man

* Prevent fly-by fixture from powering containment field generator (space-wizards#29225)

* Prevent fly-by fixture from powering containment field generator

* Update according to review

* Automatic changelog update

* Hide moth antenna and lizard frills with hardsuit helmets, fix lizard snouts not being hidden (space-wizards#29214)

* inital

* Update ClothingSystem.cs

* Update helmets.yml

* Automatic changelog update

* Fix and enable TestEmptyLoadout (space-wizards#29228)

* Fix and enabled TestEmptyLoadout

* Fine, have a real name

* Fix brokey code :)

* Fix entities getting stuck red (space-wizards#28981)

* Automatic changelog update

* Update submodule to 226.2.0 (space-wizards#29247)

* add a type specifier where one was forgor (space-wizards#29250)

* add a type specifier where one was forgor

* Fix other way because degub conditions

* okay this feels kinda dumb but it does fix it.

* Update Content.Client/Effects/ColorFlashEffectSystem.cs

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Make winter coat hood hide certain markings (space-wizards#29238)

Update base_clothinghead.yml

* Fix ERT becoming sleeper agents and add sleeper agent preferences (space-wizards#27817)

* b

* Update antags.ftl

* m

* ok

* Update events.yml

* antag

* a

* Create InitialInfectedExemptComponent.cs

* Delete InitialInfectedExemptComponent.cs

* yes

* Delete InitialInfectedExemptComponent.cs

* Create AntagImmuneComponent.cs

* Automatic changelog update

* fixed Syndicate smokes pack being half-filled (space-wizards#28371)

* Automatic changelog update

* Buff cube boxes (space-wizards#29251)

* Automatic changelog update

* moves explosive tech to T1 (space-wizards#29227)

moves explo tech to T1

* Automatic changelog update

* made cup ramen eatable with anything with the fork component (space-wizards#27826)

* made cup ramen eatable with anything with the fork component

* removed extra png

* made cupramen fillable with water, and made hot ramen dry ramen.

---------

Co-authored-by: redfire1331 <Redfire1331@users.noreply.github.com>

* Automatic changelog update

* Survival Box Loadouts, Nitrogen Emergency tanks (space-wizards#29131)

* Nitrogen survival boxes

* Zero-setup workaround

* clown box

* cleanup and universal tanks

* cleanup

* more cleanup

* hide loadoutgroups

* remaining survival boxes

* space ninja

* Revert "space ninja"

This reverts commit a650f41.

* weh

* weh

* undo appearance change of syndicate survival boxes

* indentation fix and missing label

* You can now pry multiple tiles at once (space-wizards#29231)

* You can now pry multiple tiles at once

* More advanced do after duplicate checking.

Instead of just saying "lol tile prying can raise duplicates", we now have a system so tile prying can properly distinguish events on 2 different tiles. This is achieved with a virtual function on DoAfterEvent.

* Automatic changelog update

* Fix prying speed & log (space-wizards#29210)

* cleanup prototypes with `PryingComponent` & fix jaws of life prying speed

* Minor cleanup for tools and prying systems

Remove some obsolete methods.

* Fix doafter continues when not held & log

* Modifiy delays for floor prying

* Fix test fail

* Automatic changelog update

* golden plunger (space-wizards#29043)

* golden plunger

* Add wood material (the handle is still wood)

* 52 hours

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Rate limit ahelps (space-wizards#29219)

* Make chat rate limits a general-purpose system.

Intending to use this with ahelps next.

* Rate limt ahelps

Fixes space-wizards#28762

* Review comments

* return empty string for invalid identity (space-wizards#29274)

Co-authored-by: deltanedas <@deltanedas:kde.org>

* Make Loadout MinLimit not count failed attempts (space-wizards#29264)

Loadout MinLimit doesn't count failed attempts

* Add logging to SharedStorageSystem prototype indexing failure (space-wizards#29273)

* Fix null exceptions in SurveillanceCameraMonitorSystem (space-wizards#29275)

* Add IsNullOrEmpty checks before indexing KnownSubnets

* actor

* Make stasis bed power toggleable (space-wizards#29268)

Stasis bed is now power toggleable

* Automatic changelog update

* Replace BlockSolutionAccessComponent with an attempt event (space-wizards#26988)

* BlockSolutionAccessComponent now only blocks one specified solution.

* Significant overhaul
Separated spilling when worn functionality into its own component/system.
Removed BlockSolutionAccessComponent.
Added an event for solution access.

* fix initial infected icons and add a briefing to the character menu (space-wizards#29259)

* Automatic changelog update

* feat: update cyborg parts naming for them to be ordered consistently,… (space-wizards#29272)

feat: update cyborg parts naming for them to be ordered consistently, closes space-wizards#29270

---------

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
Co-authored-by: Mr. 27 <45323883+Dutch-VanDerLinde@users.noreply.github.com>
Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
Co-authored-by: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Co-authored-by: IProduceWidgets <107586145+IProduceWidgets@users.noreply.github.com>
Co-authored-by: osjarw <62134478+osjarw@users.noreply.github.com>
Co-authored-by: Vasilis <vasilis@pikachu.systems>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: Rouge2t7 <81053047+Sarahon@users.noreply.github.com>
Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Co-authored-by: Flareguy <78941145+Flareguy@users.noreply.github.com>
Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com>
Co-authored-by: beck-thompson <107373427+beck-thompson@users.noreply.github.com>
Co-authored-by: HS <81934438+HolySSSS@users.noreply.github.com>
Co-authored-by: Plykiya <58439124+Plykiya@users.noreply.github.com>
Co-authored-by: plykiya <plykiya@protonmail.com>
Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
Co-authored-by: Truoizys <153248924+Truoizys@users.noreply.github.com>
Co-authored-by: Арт <123451459+JustArt1m@users.noreply.github.com>
Co-authored-by: TsjipTsjip <19798667+TsjipTsjip@users.noreply.github.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Co-authored-by: Alice "Arimah" Heurlin <30327355+arimah@users.noreply.github.com>
Co-authored-by: neutrino <67447925+neutrino-laser@users.noreply.github.com>
Co-authored-by: Boaz1111 <149967078+Boaz1111@users.noreply.github.com>
Co-authored-by: Redfire1331 <125223432+Redfire1331@users.noreply.github.com>
Co-authored-by: redfire1331 <Redfire1331@users.noreply.github.com>
Co-authored-by: MilenVolf <63782763+MilenVolf@users.noreply.github.com>
Co-authored-by: Ghagliiarghii <68826635+Ghagliiarghii@users.noreply.github.com>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: Alex Pavlenko <diraven@users.noreply.github.com>
  • Loading branch information
Show file tree
Hide file tree
Showing 117 changed files with 1,362 additions and 474 deletions.
68 changes: 35 additions & 33 deletions Content.Client/Effects/ColorFlashEffectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Animations;
using Robust.Shared.Collections;
using Robust.Shared.Player;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Client.Effects;

public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AnimationPlayerSystem _animation = default!;
[Dependency] private readonly IComponentFactory _factory = default!;

/// <summary>
/// It's a little on the long side but given we use multiple colours denoting what happened it makes it easier to register.
/// </summary>
private const float AnimationLength = 0.30f;
private const string AnimationKey = "color-flash-effect";
private ValueList<EntityUid> _toRemove = new();

public override void Initialize()
{
Expand All @@ -44,8 +46,28 @@ private void OnEffectAnimationCompleted(EntityUid uid, ColorFlashEffectComponent
{
sprite.Color = component.Color;
}
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = AllEntityQuery<ColorFlashEffectComponent>();
_toRemove.Clear();

// Can't use deferred removal on animation completion or it will cause issues.
while (query.MoveNext(out var uid, out _))
{
if (_animation.HasRunningAnimation(uid, AnimationKey))
continue;

RemCompDeferred<ColorFlashEffectComponent>(uid);
_toRemove.Add(uid);
}

foreach (var ent in _toRemove)
{
RemComp<ColorFlashEffectComponent>(ent);
}
}

private Animation? GetDamageAnimation(EntityUid uid, Color color, SpriteComponent? sprite = null)
Expand Down Expand Up @@ -82,51 +104,31 @@ private void OnColorFlashEffect(ColorFlashEffectEvent ev)
{
var ent = GetEntity(nent);

if (Deleted(ent))
if (Deleted(ent) || !TryComp(ent, out SpriteComponent? sprite))
{
continue;
}

if (!TryComp(ent, out AnimationPlayerComponent? player))
{
player = (AnimationPlayerComponent) _factory.GetComponent(typeof(AnimationPlayerComponent));
player.Owner = ent;
player.NetSyncEnabled = false;
AddComp(ent, player);
}

// Need to stop the existing animation first to ensure the sprite color is fixed.
// Otherwise we might lerp to a red colour instead.
if (_animation.HasRunningAnimation(ent, player, AnimationKey))
{
_animation.Stop(ent, player, AnimationKey);
}

if (!TryComp<SpriteComponent>(ent, out var sprite))
{
continue;
}

if (TryComp<ColorFlashEffectComponent>(ent, out var effect))
if (!TryComp(ent, out ColorFlashEffectComponent? comp))
{
sprite.Color = effect.Color;
#if DEBUG
DebugTools.Assert(!_animation.HasRunningAnimation(ent, AnimationKey));
#endif
}

_animation.Stop(ent, AnimationKey);
var animation = GetDamageAnimation(ent, color, sprite);

if (animation == null)
continue;

if (!TryComp(ent, out ColorFlashEffectComponent? comp))
{
comp = (ColorFlashEffectComponent) _factory.GetComponent(typeof(ColorFlashEffectComponent));
comp.Owner = ent;
comp.NetSyncEnabled = false;
AddComp(ent, comp);
continue;
}

EnsureComp<ColorFlashEffectComponent>(ent, out comp);
comp.NetSyncEnabled = false;
comp.Color = sprite.Color;
_animation.Play((ent, player), animation, AnimationKey);

_animation.Play(ent, animation, AnimationKey);
}
}
}
2 changes: 1 addition & 1 deletion Content.Client/Gravity/FloatingVisualizerSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ private void OnAnimationCompleted(EntityUid uid, FloatingVisualsComponent compon
if (args.Key != component.AnimationKey)
return;

FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime, !component.CanFloat);
FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime, stop: !component.CanFloat);
}
}
17 changes: 17 additions & 0 deletions Content.Server/Administration/Systems/AdminVerbSystem.Antags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public sealed partial class AdminVerbSystem
[ValidatePrototypeId<EntityPrototype>]
private const string DefaultTraitorRule = "Traitor";

[ValidatePrototypeId<EntityPrototype>]
private const string DefaultInitialInfectedRule = "Zombie";

[ValidatePrototypeId<EntityPrototype>]
private const string DefaultNukeOpRule = "LoneOpsSpawn";

Expand Down Expand Up @@ -63,6 +66,20 @@ private void AddAntagVerbs(GetVerbsEvent<Verb> args)
};
args.Verbs.Add(traitor);

Verb initialInfected = new()
{
Text = Loc.GetString("admin-verb-text-make-initial-infected"),
Category = VerbCategory.Antag,
Icon = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/job_icons.rsi"), "InitialInfected"),
Act = () =>
{
_antag.ForceMakeAntag<ZombieRuleComponent>(targetPlayer, DefaultInitialInfectedRule);
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-verb-make-initial-infected"),
};
args.Verbs.Add(initialInfected);

Verb zombie = new()
{
Text = Loc.GetString("admin-verb-text-make-zombie"),
Expand Down
23 changes: 23 additions & 0 deletions Content.Server/Administration/Systems/BwoinkSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Content.Server.Afk;
using Content.Server.Discord;
using Content.Server.GameTicking;
using Content.Server.Players.RateLimiting;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Mind;
Expand All @@ -27,6 +28,8 @@ namespace Content.Server.Administration.Systems
[UsedImplicitly]
public sealed partial class BwoinkSystem : SharedBwoinkSystem
{
private const string RateLimitKey = "AdminHelp";

[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
Expand All @@ -35,6 +38,7 @@ public sealed partial class BwoinkSystem : SharedBwoinkSystem
[Dependency] private readonly GameTicker _gameTicker = default!;
[Dependency] private readonly SharedMindSystem _minds = default!;
[Dependency] private readonly IAfkManager _afkManager = default!;
[Dependency] private readonly PlayerRateLimitManager _rateLimit = default!;

[GeneratedRegex(@"^https://discord\.com/api/webhooks/(\d+)/((?!.*/).*)$")]
private static partial Regex DiscordRegex();
Expand Down Expand Up @@ -80,6 +84,22 @@ public override void Initialize()

SubscribeLocalEvent<GameRunLevelChangedEvent>(OnGameRunLevelChanged);
SubscribeNetworkEvent<BwoinkClientTypingUpdated>(OnClientTypingUpdated);

_rateLimit.Register(
RateLimitKey,
new RateLimitRegistration
{
CVarLimitPeriodLength = CCVars.AhelpRateLimitPeriod,
CVarLimitCount = CCVars.AhelpRateLimitCount,
PlayerLimitedAction = PlayerRateLimitedAction
});
}

private void PlayerRateLimitedAction(ICommonSession obj)
{
RaiseNetworkEvent(
new BwoinkTextMessage(obj.UserId, default, Loc.GetString("bwoink-system-rate-limited"), playSound: false),
obj.Channel);
}

private void OnOverrideChanged(string obj)
Expand Down Expand Up @@ -395,6 +415,9 @@ protected override void OnBwoinkTextMessage(BwoinkTextMessage message, EntitySes
return;
}

if (_rateLimit.CountAction(eventArgs.SenderSession, RateLimitKey) != RateLimitStatus.Allowed)
return;

var escapedText = FormattedMessage.EscapeText(message.Text);

string bwoinkText;
Expand Down
7 changes: 7 additions & 0 deletions Content.Server/Antag/Components/AntagImmuneComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Content.Server.Antag.Components;

[RegisterComponent]
public partial class AntagImmuneComponent : Component
{

}
85 changes: 21 additions & 64 deletions Content.Server/Chat/Managers/ChatManager.RateLimit.cs
Original file line number Diff line number Diff line change
@@ -1,84 +1,41 @@
using System.Runtime.InteropServices;
using Content.Server.Players.RateLimiting;
using Content.Shared.CCVar;
using Content.Shared.Database;
using Robust.Shared.Enums;
using Robust.Shared.Player;
using Robust.Shared.Timing;

namespace Content.Server.Chat.Managers;

internal sealed partial class ChatManager
{
private readonly Dictionary<ICommonSession, RateLimitDatum> _rateLimitData = new();
private const string RateLimitKey = "Chat";

public bool HandleRateLimit(ICommonSession player)
private void RegisterRateLimits()
{
ref var datum = ref CollectionsMarshal.GetValueRefOrAddDefault(_rateLimitData, player, out _);
var time = _gameTiming.RealTime;
if (datum.CountExpires < time)
{
// Period expired, reset it.
var periodLength = _configurationManager.GetCVar(CCVars.ChatRateLimitPeriod);
datum.CountExpires = time + TimeSpan.FromSeconds(periodLength);
datum.Count = 0;
datum.Announced = false;
}

var maxCount = _configurationManager.GetCVar(CCVars.ChatRateLimitCount);
datum.Count += 1;

if (datum.Count <= maxCount)
return true;

// Breached rate limits, inform admins if configured.
if (_configurationManager.GetCVar(CCVars.ChatRateLimitAnnounceAdmins))
{
if (datum.NextAdminAnnounce < time)
_rateLimitManager.Register(RateLimitKey,
new RateLimitRegistration
{
SendAdminAlert(Loc.GetString("chat-manager-rate-limit-admin-announcement", ("player", player.Name)));
var delay = _configurationManager.GetCVar(CCVars.ChatRateLimitAnnounceAdminsDelay);
datum.NextAdminAnnounce = time + TimeSpan.FromSeconds(delay);
}
}

if (!datum.Announced)
{
DispatchServerMessage(player, Loc.GetString("chat-manager-rate-limited"), suppressLog: true);
_adminLogger.Add(LogType.ChatRateLimited, LogImpact.Medium, $"Player {player} breached chat rate limits");

datum.Announced = true;
}

return false;
CVarLimitPeriodLength = CCVars.ChatRateLimitPeriod,
CVarLimitCount = CCVars.ChatRateLimitCount,
CVarAdminAnnounceDelay = CCVars.ChatRateLimitAnnounceAdminsDelay,
PlayerLimitedAction = RateLimitPlayerLimited,
AdminAnnounceAction = RateLimitAlertAdmins,
AdminLogType = LogType.ChatRateLimited,
});
}

private void PlayerStatusChanged(object? sender, SessionStatusEventArgs e)
private void RateLimitPlayerLimited(ICommonSession player)
{
if (e.NewStatus == SessionStatus.Disconnected)
_rateLimitData.Remove(e.Session);
DispatchServerMessage(player, Loc.GetString("chat-manager-rate-limited"), suppressLog: true);
}

private struct RateLimitDatum
private void RateLimitAlertAdmins(ICommonSession player)
{
/// <summary>
/// Time stamp (relative to <see cref="IGameTiming.RealTime"/>) this rate limit period will expire at.
/// </summary>
public TimeSpan CountExpires;

/// <summary>
/// How many messages have been sent in the current rate limit period.
/// </summary>
public int Count;

/// <summary>
/// Have we announced to the player that they've been blocked in this rate limit period?
/// </summary>
public bool Announced;
if (_configurationManager.GetCVar(CCVars.ChatRateLimitAnnounceAdmins))
SendAdminAlert(Loc.GetString("chat-manager-rate-limit-admin-announcement", ("player", player.Name)));
}

/// <summary>
/// Time stamp (relative to <see cref="IGameTiming.RealTime"/>) of the
/// next time we can send an announcement to admins about rate limit breach.
/// </summary>
public TimeSpan NextAdminAnnounce;
public RateLimitStatus HandleRateLimit(ICommonSession player)
{
return _rateLimitManager.CountAction(player, RateLimitKey);
}
}
10 changes: 4 additions & 6 deletions Content.Server/Chat/Managers/ChatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
using Content.Server.Administration.Managers;
using Content.Server.Administration.Systems;
using Content.Server.MoMMI;
using Content.Server.Players.RateLimiting;
using Content.Server.Preferences.Managers;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.Mind;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Replays;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Server.Chat.Managers
Expand All @@ -43,8 +42,7 @@ internal sealed partial class ChatManager : IChatManager
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly INetConfigurationManager _netConfigManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly PlayerRateLimitManager _rateLimitManager = default!;

/// <summary>
/// The maximum length a player-sent message can be sent
Expand All @@ -64,7 +62,7 @@ public void Initialize()
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
_configurationManager.OnValueChanged(CCVars.AdminOocEnabled, OnAdminOocEnabledChanged, true);

_playerManager.PlayerStatusChanged += PlayerStatusChanged;
RegisterRateLimits();
}

private void OnOocEnabledChanged(bool val)
Expand Down Expand Up @@ -206,7 +204,7 @@ public void SendHookOOC(string sender, string message)
/// <param name="type">The type of message.</param>
public void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type)
{
if (!HandleRateLimit(player))
if (HandleRateLimit(player) != RateLimitStatus.Allowed)
return;

// Check if message exceeds the character limit
Expand Down
4 changes: 3 additions & 1 deletion Content.Server/Chat/Managers/IChatManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Players;
using Content.Server.Players.RateLimiting;
using Content.Shared.Administration;
using Content.Shared.Chat;
using Robust.Shared.Network;
Expand Down Expand Up @@ -50,6 +52,6 @@ void ChatMessageToMany(ChatChannel channel, string message, string wrappedMessag
/// </summary>
/// <param name="player">The player sending a chat message.</param>
/// <returns>False if the player has violated rate limits and should be blocked from sending further messages.</returns>
bool HandleRateLimit(ICommonSession player);
RateLimitStatus HandleRateLimit(ICommonSession player);
}
}
Loading

0 comments on commit 4100c74

Please sign in to comment.