]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add stealthmins (#26263)
authornikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com>
Sun, 24 Mar 2024 15:39:53 +0000 (17:39 +0200)
committerGitHub <noreply@github.com>
Sun, 24 Mar 2024 15:39:53 +0000 (10:39 -0500)
* Add stealthmin command.

* Update Content.Server/Administration/Commands/AdminWhoCommand.cs

As suggested by CE.

Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
* Add admin notifications for admins toggling stealthmin.

* Localize stealthmin command

---------

Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
Content.Server/Administration/Commands/AdminWhoCommand.cs
Content.Server/Administration/Commands/StealthminCommand.cs [new file with mode: 0644]
Content.Server/Administration/Managers/AdminManager.cs
Content.Server/Administration/Managers/IAdminManager.cs
Content.Server/Chat/Managers/ChatManager.cs
Content.Server/Chat/Managers/IChatManager.cs
Content.Shared/Administration/AdminData.cs
Content.Shared/Administration/AdminFlags.cs
Content.Shared/Players/ContentPlayerData.cs
Resources/Locale/en-US/administration/commands/stealthmin-command.ftl [new file with mode: 0644]
Resources/Locale/en-US/administration/managers/admin-manager.ftl

index 9765e8385f0240ef1e3b2e528249249934728624..cf2f8c453c880a030e40a7d97f448d23ce97708f 100644 (file)
@@ -19,6 +19,16 @@ public sealed class AdminWhoCommand : IConsoleCommand
         var adminMgr = IoCManager.Resolve<IAdminManager>();
         var afk = IoCManager.Resolve<IAfkManager>();
 
+        var seeStealth = true;
+
+        // If null it (hopefully) means it is being called from the console.
+        if (shell.Player != null)
+        {
+            var playerData = adminMgr.GetAdminData(shell.Player);
+
+            seeStealth = playerData != null && playerData.CanStealth();
+        }
+
         var sb = new StringBuilder();
         var first = true;
         foreach (var admin in adminMgr.ActiveAdmins)
@@ -30,10 +40,16 @@ public sealed class AdminWhoCommand : IConsoleCommand
             var adminData = adminMgr.GetAdminData(admin)!;
             DebugTools.AssertNotNull(adminData);
 
+            if (adminData.Stealth && !seeStealth)
+                continue;
+
             sb.Append(admin.Name);
             if (adminData.Title is { } title)
                 sb.Append($": [{title}]");
 
+            if (adminData.Stealth)
+                sb.Append(" (S)");
+
             if (shell.Player is { } player && adminMgr.HasAdminFlag(player, AdminFlags.Admin))
             {
                 if (afk.IsAfk(admin))
diff --git a/Content.Server/Administration/Commands/StealthminCommand.cs b/Content.Server/Administration/Commands/StealthminCommand.cs
new file mode 100644 (file)
index 0000000..49d8363
--- /dev/null
@@ -0,0 +1,39 @@
+using Content.Server.Administration.Managers;
+using Content.Shared.Administration;
+using JetBrains.Annotations;
+using Robust.Shared.Console;
+using Robust.Shared.Utility;
+
+namespace Content.Server.Administration.Commands;
+
+[UsedImplicitly]
+[AdminCommand(AdminFlags.Stealth)]
+public sealed class StealthminCommand : LocalizedCommands
+{
+    public override string Command => "stealthmin";
+
+    public override void Execute(IConsoleShell shell, string argStr, string[] args)
+    {
+            var player = shell.Player;
+            if (player == null)
+            {
+                shell.WriteLine(Loc.GetString("cmd-stealthmin-no-console"));
+                return;
+            }
+
+            var mgr = IoCManager.Resolve<IAdminManager>();
+
+            var adminData = mgr.GetAdminData(player);
+
+            DebugTools.AssertNotNull(adminData);
+
+            if (!adminData!.Stealth)
+            {
+                mgr.Stealth(player);
+            }
+            else
+            {
+                mgr.UnStealth(player);
+            }
+    }
+}
index b1cca46e63f8e90a2f59bcf37108a34f0f4d50d3..371755dcef4207f26cb7175eeac13ae5cecacb1d 100644 (file)
@@ -98,6 +98,44 @@ namespace Content.Server.Administration.Managers
             UpdateAdminStatus(session);
         }
 
+        public void Stealth(ICommonSession session)
+        {
+            if (!_admins.TryGetValue(session, out var reg))
+            {
+                throw new ArgumentException($"Player {session} is not an admin");
+            }
+
+            if (reg.Data.Stealth)
+                return;
+
+            var playerData = session.ContentData()!;
+            playerData.Stealthed = true;
+            reg.Data.Stealth = true;
+
+            _chat.DispatchServerMessage(session, Loc.GetString("admin-manager-stealthed-message"));
+            _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-de-admin-message", ("exAdminName", session.Name)), AdminFlags.Stealth);
+            _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-enable-stealth", ("stealthAdminName", session.Name)), flagWhitelist: AdminFlags.Stealth);
+        }
+
+        public void UnStealth(ICommonSession session)
+        {
+            if (!_admins.TryGetValue(session, out var reg))
+            {
+                throw new ArgumentException($"Player {session} is not an admin");
+            }
+
+            if (!reg.Data.Stealth)
+                return;
+
+            var playerData = session.ContentData()!;
+            playerData.Stealthed = false;
+            reg.Data.Stealth = false;
+
+            _chat.DispatchServerMessage(session, Loc.GetString("admin-manager-unstealthed-message"));
+            _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message", ("newAdminName", session.Name)), flagBlacklist: AdminFlags.Stealth);
+            _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-disable-stealth", ("exStealthAdminName", session.Name)), flagWhitelist: AdminFlags.Stealth);
+        }
+
         public void ReAdmin(ICommonSession session)
         {
             if (!_admins.TryGetValue(session, out var reg))
@@ -116,7 +154,16 @@ namespace Content.Server.Administration.Managers
             plyData.ExplicitlyDeadminned = false;
             reg.Data.Active = true;
 
-            _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message", ("newAdminName", session.Name)));
+            if (reg.Data.Stealth)
+            {
+                _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message", ("newAdminName", session.Name)));
+            }
+            else
+            {
+                _chat.DispatchServerMessage(session, Loc.GetString("admin-manager-stealthed-message"));
+                _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-re-admin-message",
+                    ("newAdminName", session.Name)), flagWhitelist: AdminFlags.Stealth);
+            }
 
             SendPermsChangedEvent(session);
             UpdateAdminStatus(session);
@@ -168,6 +215,11 @@ namespace Content.Server.Administration.Managers
 
                     _chat.DispatchServerMessage(player, Loc.GetString("admin-manager-admin-permissions-updated-message"));
                 }
+
+                if (player.ContentData()!.Stealthed)
+                {
+                    aData.Stealth = true;
+                }
             }
 
             SendPermsChangedEvent(player);
@@ -290,9 +342,19 @@ namespace Content.Server.Administration.Managers
             }
             else if (e.NewStatus == SessionStatus.Disconnected)
             {
-                if (_admins.Remove(e.Session) && _cfg.GetCVar(CCVars.AdminAnnounceLogout))
+                if (_admins.Remove(e.Session, out var reg ) && _cfg.GetCVar(CCVars.AdminAnnounceLogout))
                 {
-                    _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-logout-message", ("name", e.Session.Name)));
+                    if (reg.Data.Stealth)
+                    {
+                        _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-logout-message",
+                            ("name", e.Session.Name)), flagWhitelist: AdminFlags.Stealth);
+
+                    }
+                    else
+                    {
+                        _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-logout-message",
+                            ("name", e.Session.Name)));
+                    }
                 }
             }
         }
@@ -315,13 +377,27 @@ namespace Content.Server.Administration.Managers
 
             _admins.Add(session, reg);
 
+            if (session.ContentData()!.Stealthed)
+                reg.Data.Stealth = true;
+
             if (!session.ContentData()!.ExplicitlyDeadminned)
             {
                 reg.Data.Active = true;
 
                 if (_cfg.GetCVar(CCVars.AdminAnnounceLogin))
                 {
-                    _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-login-message", ("name", session.Name)));
+                    if (reg.Data.Stealth)
+                    {
+
+                        _chat.DispatchServerMessage(session, Loc.GetString("admin-manager-stealthed-message"));
+                        _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-login-message",
+                            ("name", session.Name)), flagWhitelist: AdminFlags.Stealth);
+                    }
+                    else
+                    {
+                        _chat.SendAdminAnnouncement(Loc.GetString("admin-manager-admin-login-message",
+                            ("name", session.Name)));
+                    }
                 }
 
                 SendPermsChangedEvent(session);
index a52ec7b099cd1fafa46eaee7775fc9270f5b2c33..95967b24acae1147d6cf461492163064136ba59a 100644 (file)
@@ -41,6 +41,16 @@ namespace Content.Server.Administration.Managers
         /// </summary>
         void ReAdmin(ICommonSession session);
 
+        /// <summary>
+        ///     Make admin hidden from adminwho.
+        /// </summary>
+        void Stealth(ICommonSession session);
+
+        /// <summary>
+        ///     Unhide admin from adminwho.
+        /// </summary>
+        void UnStealth(ICommonSession session);
+
         /// <summary>
         ///     Re-loads the permissions of an player in case their admin data changed DB-side.
         /// </summary>
index 6d54bedf86c816ebb7997b0377b60b88608de6d7..d12bbfe53c9504b882ff18cdc46b0507bf00d337 100644 (file)
@@ -125,9 +125,23 @@ namespace Content.Server.Chat.Managers
                 _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Server message to {player:Player}: {message}");
         }
 
-        public void SendAdminAnnouncement(string message)
+        public void SendAdminAnnouncement(string message, AdminFlags? flagBlacklist, AdminFlags? flagWhitelist)
         {
-            var clients = _adminManager.ActiveAdmins.Select(p => p.Channel);
+            var clients = _adminManager.ActiveAdmins.Where(p =>
+            {
+                var adminData = _adminManager.GetAdminData(p);
+
+                DebugTools.AssertNotNull(adminData);
+
+                if (adminData == null)
+                    return false;
+
+                if (flagBlacklist != null && adminData.HasFlag(flagBlacklist.Value))
+                    return false;
+
+                return flagWhitelist == null || adminData.HasFlag(flagWhitelist.Value);
+
+            }).Select(p => p.Channel);
 
             var wrappedMessage = Loc.GetString("chat-manager-send-admin-announcement-wrap-message",
                 ("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")), ("message", FormattedMessage.EscapeText(message)));
index e5fa8d5f4dc0077cbf1b3a24290eac3df9dcad49..59945bf5ca6f3d61b688948034c8a8ddd1663ffd 100644 (file)
@@ -1,4 +1,5 @@
 using System.Diagnostics.CodeAnalysis;
+using Content.Shared.Administration;
 using Content.Shared.Chat;
 using Robust.Shared.Network;
 using Robust.Shared.Player;
@@ -21,7 +22,7 @@ namespace Content.Server.Chat.Managers
         void TrySendOOCMessage(ICommonSession player, string message, OOCChatType type);
 
         void SendHookOOC(string sender, string message);
-        void SendAdminAnnouncement(string message);
+        void SendAdminAnnouncement(string message, AdminFlags? flagBlacklist = null, AdminFlags? flagWhitelist = null);
         void SendAdminAlert(string message);
         void SendAdminAlert(EntityUid player, string message);
 
index 5b5873bce36d7025ea7e058796c8000a88735467..229edbcd4c365bd4a9674eb36d3901f1ce5026d5 100644 (file)
@@ -12,6 +12,11 @@ namespace Content.Shared.Administration
         /// </summary>
         public bool Active;
 
+        /// <summary>
+        /// Whether the admin is in stealth mode and won't appear in adminwho to admins without the Stealth flag.
+        /// </summary>
+        public bool Stealth;
+
         /// <summary>
         ///     The admin's title.
         /// </summary>
@@ -56,6 +61,14 @@ namespace Content.Shared.Administration
             return HasFlag(AdminFlags.Admin);
         }
 
+        /// <summary>
+        /// Check if this admin can be hidden and see other hidden admins.
+        /// </summary>
+        public bool CanStealth()
+        {
+            return HasFlag(AdminFlags.Stealth);
+        }
+
         public bool CanAdminReloadPrototypes()
         {
             return HasFlag(AdminFlags.Host);
index f7d7efb1dbdfbf3a69b33ac15831c7df04d2aa2a..52161cf3f3a1c186cfa00d8b31d1dcce086e851c 100644 (file)
         /// </summary>
         MassBan = 1 << 15,
 
+        /// <summary>
+        /// Allows you to remain hidden from adminwho except to other admins with this flag.
+        /// </summary>
+        Stealth = 1 << 16,
+
         /// <summary>
         ///     Dangerous host permissions like scsi.
         /// </summary>
index 7545eb58fcdbca62eb81f07096a8a0a732c930a6..16b6ace3a1fc780d97fd9bafedf1c1cc50aa1a08 100644 (file)
@@ -1,4 +1,5 @@
-using Content.Shared.GameTicking;
+using Content.Shared.Administration;
+using Content.Shared.GameTicking;
 using Content.Shared.Mind;
 using Robust.Shared.Network;
 
@@ -37,9 +38,14 @@ public sealed class ContentPlayerData
     /// </summary>
     public bool ExplicitlyDeadminned { get; set; }
 
+    /// <summary>
+    /// If true, the admin will not show up in adminwho except to admins with the <see cref="AdminFlags.Stealth"/> flag.
+    /// </summary>
+    public bool Stealthed { get; set; }
+
     public ContentPlayerData(NetUserId userId, string name)
     {
         UserId = userId;
         Name = name;
     }
-}
\ No newline at end of file
+}
diff --git a/Resources/Locale/en-US/administration/commands/stealthmin-command.ftl b/Resources/Locale/en-US/administration/commands/stealthmin-command.ftl
new file mode 100644 (file)
index 0000000..4fb5e52
--- /dev/null
@@ -0,0 +1,3 @@
+cmd-stealthmin-desc = Toggle whether others can see you in adminwho.
+cmd-stealthmin-help = Usage: stealthmin\nUse stealthmin to toggle whether you appear in the output of the adminwho command.
+cmd-stealthmin-no-console = You cannot use this command from the server console.
index b1bbcc4c8c143d65635933e1f37e0b9085c0b29a..b70f550fc372aeeaf0dfe61e5a75c6dcfd40ff66 100644 (file)
@@ -6,4 +6,8 @@ admin-manager-no-longer-admin-message = You are no longer an admin.
 admin-manager-admin-permissions-updated-message = Your admin permission have been updated.
 admin-manager-admin-logout-message = Admin logout: {$name}
 admin-manager-admin-login-message = Admin login: {$name}
-admin-manager-admin-data-host-title = Host
\ No newline at end of file
+admin-manager-admin-data-host-title = Host
+admin-manager-stealthed-message = You are now a hidden admin.
+admin-manager-unstealthed-message = You are no longer hidden.
+admin-manager-self-enable-stealth = {$stealthAdminName} is now hidden.
+admin-manager-self-disable-stealth = {$exStealthAdminName} is no longer hidden.