From 3c0d4ab253461333758c031600cba740594e6ee3 Mon Sep 17 00:00:00 2001 From: DisposableCrewmember42 Date: Sat, 4 Apr 2026 14:38:32 +0000 Subject: [PATCH] feat: Various Admin QOL features (#5436) * feat: added lslaws command * feat: add lswatchlisted command * tweak: nicer formatting for lswatchlisted * tweak: nicer formatting for lslaws * feat: lsobjectives lists everyone's objectives if no user specified * feat: mark ghosted players in players tab * docs: add missing DeltaV patch comment * feat: only alert admins if meatspiking player characters * feat: always alert about station explosions, don't spam off-station alerts * feat: stripping alert tweaks * feat: admin alert on low hour latejoin * refactor: forgot to make onspawncomplete non-async, wasn't necessary after all * feat: EORG alerts * feat: getping command * refactor: remove unused imports, format * refactor: early return in onspawncomplete * feat: add coordinate link to eorg destroy alert * tweak: cache watchlist data to avoid db calls, use in lswatchlisted * fix: null-check in OnNoteAdded * feat: watchlist indicator on admin overlay * feat: optionally mark watchlisted in f7 players * feat: refresh admin playerlist data on wl change * fix: update player list after cache write * feat: add tp links to prayer messages * tweak: don't alert when uncuffing self * tweak: lower uncuff other alert impact if mindshielded * docs: add deltav comments to imports * refactor: address review comments * style: deltav comments on same line as change * performance: get metadata only if objectives > 0 * fix: actually check user if explosion gridPos not on station * style: remove extraneous newlines * refactor: use fancy getOrNew method * feat: refresh player list UI if marking pref changed * feat: latejoin alert hours configurable * fix: also list objectives for non-humanoids and dead people --- .../Administration/AdminNameOverlay.cs | 18 ++- .../UI/Tabs/PlayerTab/PlayerTab.xaml.cs | 44 ++++- .../UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs | 16 +- .../Options/UI/Tabs/AdminOptionsTab.xaml | 2 + .../Options/UI/Tabs/AdminOptionsTab.xaml.cs | 2 + .../Administration/Logs/AdminLogManager.cs | 9 +- .../Administration/Notes/AdminNotesSystem.cs | 83 ++++++++++ .../Administration/Systems/AdminSystem.cs | 11 +- .../Destructible/DestructibleSystem.cs | 3 + .../EntitySystems/ExplosionSystem.cs | 38 ++++- .../Commands/ListObjectivesCommand.cs | 49 +++++- Content.Server/Prayer/PrayerSystem.cs | 3 + .../Administration/Commands/GetPingCommand.cs | 32 ++++ .../Commands/ListLawsCommand.cs | 82 ++++++++++ .../Commands/ListWatchlistedCommand.cs | 54 +++++++ .../_DV/Administration/EventAlertSystem.cs | 153 ++++++++++++++++++ Content.Shared/Administration/PlayerInfo.cs | 5 +- Content.Shared/CCVar/CCVars.Admin.cs | 2 +- Content.Shared/CCVar/CCVars.Interface.cs | 15 ++ Content.Shared/Cuffs/SharedCuffableSystem.cs | 9 +- .../Kitchen/SharedKitchenSpikeSystem.cs | 26 ++- .../Strip/SharedStrippableSystem.cs | 30 +++- Content.Shared/_DV/CCVars/DCCVars.cs | 6 + .../en-US/_DV/administration/admin-qol.ftl | 18 +++ .../_DV/administration/ui/admin-overlay.ftl | 1 + 25 files changed, 687 insertions(+), 24 deletions(-) create mode 100644 Content.Server/_DV/Administration/Commands/GetPingCommand.cs create mode 100644 Content.Server/_DV/Administration/Commands/ListLawsCommand.cs create mode 100644 Content.Server/_DV/Administration/Commands/ListWatchlistedCommand.cs create mode 100644 Content.Server/_DV/Administration/EventAlertSystem.cs create mode 100644 Resources/Locale/en-US/_DV/administration/admin-qol.ftl create mode 100644 Resources/Locale/en-US/_DV/administration/ui/admin-overlay.ftl diff --git a/Content.Client/Administration/AdminNameOverlay.cs b/Content.Client/Administration/AdminNameOverlay.cs index abeed65732..dbf7304ce5 100644 --- a/Content.Client/Administration/AdminNameOverlay.cs +++ b/Content.Client/Administration/AdminNameOverlay.cs @@ -196,8 +196,22 @@ internal sealed class AdminNameOverlay : Overlay // Username color = Color.Yellow; color.A = alpha; - args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.Username, uiScale, playerInfo.Connected ? color : colorDisconnected); - currentOffset += lineoffset; + var usernameSpace = args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.Username, uiScale, playerInfo.Connected ? color : colorDisconnected); // DeltaV - store return value + + // DeltaV - add watchlist suffix START + if (playerInfo.Watchlisted) + { + color = Color.Red; + color.A = alpha; + args.ScreenHandle.DrawString(_fontBold, + screenCoordinates + currentOffset + usernameSpace with { Y = 0 }, + " " + Loc.GetString("admin-overlay-watchlisted-username-suffix"), + uiScale, + color); + } + // DeltaV - add watchlist suffix END + + currentOffset += lineoffset; // DeltaV - moved down from username block // Playtime if (!string.IsNullOrEmpty(playerInfo.PlaytimeString) && _overlayPlaytime) diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs index d32d481c74..371b9952e4 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs @@ -35,6 +35,8 @@ public sealed partial class PlayerTab : Control private AdminPlayerTabColorOption _playerTabColorSetting; private AdminPlayerTabRoleTypeOption _playerTabRoleSetting; private AdminPlayerTabSymbolOption _playerTabSymbolSetting; + private bool _markGhosted; // DeltaV + private bool _markWatchlisted; // DeltaV public event Action? OnEntryKeyBindDown; @@ -51,6 +53,8 @@ public sealed partial class PlayerTab : Control _config.OnValueChanged(CCVars.AdminPlayerTabRoleSetting, RoleSettingChanged, true); _config.OnValueChanged(CCVars.AdminPlayerTabColorSetting, ColorSettingChanged, true); _config.OnValueChanged(CCVars.AdminPlayerTabSymbolSetting, SymbolSettingChanged, true); + _config.OnValueChanged(CCVars.AdminPlayerTabMarkGhosted, MarkGhostedChanged, true); // DeltaV + _config.OnValueChanged(CCVars.AdminPlayerTabMarkWatchlisted, MarkWatchlistedChanged, true); // DeltaV OverlayButton.OnPressed += OverlayButtonPressed; ShowDisconnectedButton.OnPressed += ShowDisconnectedPressed; @@ -66,6 +70,20 @@ public sealed partial class PlayerTab : Control RefreshPlayerList(_adminSystem.PlayerList); } + // DeltaV - mark ghosted, watchlisted START + private void MarkGhostedChanged(bool value) + { + _markGhosted = value; + RefreshPlayerList(_players); + } + + private void MarkWatchlistedChanged(bool value) + { + _markWatchlisted = value; + RefreshPlayerList(_players); + } + // DeltaV - mark ghosted, watchlisted END + #region Antag Overlay private void OverlayEnabled() @@ -152,8 +170,25 @@ public sealed partial class PlayerTab : Control UpdateHeaderSymbols(); - SearchList.PopulateList(sortedPlayers.Select(info => new PlayerListData(info, - $"{info.Username} {info.CharacterName} {info.IdentityName} {info.StartingJob}")) + SearchList.PopulateList(sortedPlayers.Select(info => + { + // DeltaV - additions START + var filteringStringAdditions = ""; + if (_markGhosted && info.Ghost) + { + filteringStringAdditions += " (G)"; + } + + if (_markWatchlisted && info.Watchlisted) + { + filteringStringAdditions += " (WL)"; + } + // DeltaV - additions END + + return new PlayerListData(info, + $"{info.Username} {info.CharacterName} {info.IdentityName} {info.StartingJob}" + + filteringStringAdditions); // DeltaV - append filteringStringAdditions + }) .ToList()); } @@ -167,7 +202,10 @@ public sealed partial class PlayerTab : Control new StyleBoxFlat(button.Index % 2 == 0 ? _altColor : _defaultColor), _playerTabColorSetting, _playerTabRoleSetting, - _playerTabSymbolSetting); + _playerTabSymbolSetting, + _markGhosted, // DeltaV - Add _markGhosted + _markWatchlisted // DeltaV - Add _markWatchlisted + ); button.AddChild(entry); button.ToolTip = $"{player.Username}, {player.CharacterName}, {player.IdentityName}, {player.StartingJob}"; button.StyleClasses.Clear(); diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs index 6a2d939b4b..1302e01287 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml.cs @@ -20,7 +20,10 @@ public sealed partial class PlayerTabEntry : PanelContainer StyleBoxFlat styleBoxFlat, AdminPlayerTabColorOption colorOption, AdminPlayerTabRoleTypeOption roleSetting, - AdminPlayerTabSymbolOption symbolSetting) + AdminPlayerTabSymbolOption symbolSetting, + bool markGhosted, // DeltaV - Add markGhosted + bool markWatchlisted // DeltaV - Add markWatchlisted + ) { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); @@ -73,6 +76,17 @@ public sealed partial class PlayerTabEntry : PanelContainer if (player.IdentityName != player.CharacterName) CharacterLabel.Text += $" [{player.IdentityName}]"; + // DeltaV - Mark ghosted/watchlisted players START + if (player.Ghost && markGhosted) + { + CharacterLabel.Text = $"(G) {CharacterLabel.Text}"; + } + if (player.Watchlisted && markWatchlisted) + { + CharacterLabel.Text = $"(WL) {CharacterLabel.Text}"; + } + // DeltaV - Mark ghosted/watchlisted players END + var roletype = RoleTypeLabel.Text = Loc.GetString(rolePrototype?.Name ?? RoleTypePrototype.FallbackName); var subtype = roles.GetRoleSubtypeLabel(rolePrototype?.Name ?? RoleTypePrototype.FallbackName, player.Subtype); switch (roleSetting) diff --git a/Content.Client/Options/UI/Tabs/AdminOptionsTab.xaml b/Content.Client/Options/UI/Tabs/AdminOptionsTab.xaml index 0fa5ee1754..53e6e29cee 100644 --- a/Content.Client/Options/UI/Tabs/AdminOptionsTab.xaml +++ b/Content.Client/Options/UI/Tabs/AdminOptionsTab.xaml @@ -9,6 +9,8 @@ + +