]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
add forceghost admin command (#35518)
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Sat, 8 Mar 2025 02:39:04 +0000 (03:39 +0100)
committerGitHub <noreply@github.com>
Sat, 8 Mar 2025 02:39:04 +0000 (13:39 +1100)
* add forceghost admin command

* sweep linq under the rug

* braces

* ûse LocalizedEntityCommands

Content.Server/Administration/Commands/ForceGhostCommand.cs [new file with mode: 0644]
Content.Server/Ghost/GhostCommand.cs
Content.Server/Ghost/GhostSystem.cs
Resources/Locale/en-US/administration/commands/forceghost.ftl [new file with mode: 0644]

diff --git a/Content.Server/Administration/Commands/ForceGhostCommand.cs b/Content.Server/Administration/Commands/ForceGhostCommand.cs
new file mode 100644 (file)
index 0000000..68a77b7
--- /dev/null
@@ -0,0 +1,61 @@
+using Content.Server.GameTicking;
+using Content.Server.Ghost;
+using Content.Shared.Administration;
+using Content.Shared.GameTicking;
+using Content.Shared.Mind;
+using Robust.Server.Player;
+using Robust.Shared.Console;
+
+namespace Content.Server.Administration.Commands;
+
+[AdminCommand(AdminFlags.Admin)]
+public sealed class ForceGhostCommand : LocalizedEntityCommands
+{
+    [Dependency] private readonly IEntityManager _entityManager = default!;
+    [Dependency] private readonly IPlayerManager _playerManager = default!;
+    [Dependency] private readonly GameTicker _gameTicker = default!;
+    [Dependency] private readonly SharedMindSystem _mind = default!;
+    [Dependency] private readonly GhostSystem _ghost = default!;
+
+    public override string Command => "forceghost";
+
+    public override void Execute(IConsoleShell shell, string argStr, string[] args)
+    {
+        if (args.Length == 0 || args.Length > 1)
+        {
+            shell.WriteError(LocalizationManager.GetString("shell-wrong-arguments-number"));
+            return;
+        }
+
+        if (!_playerManager.TryGetSessionByUsername(args[0], out var player))
+        {
+            shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist"));
+            return;
+        }
+
+        if (!_gameTicker.PlayerGameStatuses.TryGetValue(player.UserId, out var playerStatus) ||
+            playerStatus is not PlayerGameStatus.JoinedGame)
+        {
+            shell.WriteLine(Loc.GetString("cmd-forceghost-error-lobby"));
+            return;
+        }
+
+        if (!_mind.TryGetMind(player, out var mindId, out var mind))
+            (mindId, mind) = _mind.CreateMind(player.UserId);
+
+        if (!_ghost.OnGhostAttempt(mindId, false, true, true, mind))
+            shell.WriteLine(Loc.GetString("cmd-forceghost-denied"));
+    }
+
+    public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
+    {
+        if (args.Length == 1)
+        {
+            return CompletionResult.FromHintOptions(
+                CompletionHelper.SessionNames(players: _playerManager),
+                Loc.GetString("cmd-forceghost-hint"));
+        }
+
+        return CompletionResult.Empty;
+    }
+}
index 927f9c8082fc5ce30ef72b2d76cea42ef80bef24..f5df115fde14faee974c28360a921cc056f74659 100644 (file)
@@ -50,7 +50,7 @@ namespace Content.Server.Ghost
                 mind = _entities.GetComponent<MindComponent>(mindId);
             }
 
-            if (!_entities.System<GhostSystem>().OnGhostAttempt(mindId, true, true, mind))
+            if (!_entities.System<GhostSystem>().OnGhostAttempt(mindId, true, true, mind: mind))
             {
                 shell.WriteLine(Loc.GetString("ghost-command-denied"));
             }
index b5e9894ee37bff26f6ab6d4205784f9f116f40aa..5bfa208b1c6c4a40701886b4225c4d81a58aa211 100644 (file)
@@ -499,7 +499,7 @@ namespace Content.Server.Ghost
             return ghost;
         }
 
-        public bool OnGhostAttempt(EntityUid mindId, bool canReturnGlobal, bool viaCommand = false, MindComponent? mind = null)
+        public bool OnGhostAttempt(EntityUid mindId, bool canReturnGlobal, bool viaCommand = false, bool forced = false, MindComponent? mind = null)
         {
             if (!Resolve(mindId, ref mind))
                 return false;
@@ -507,7 +507,12 @@ namespace Content.Server.Ghost
             var playerEntity = mind.CurrentEntity;
 
             if (playerEntity != null && viaCommand)
-                _adminLog.Add(LogType.Mind, $"{EntityManager.ToPrettyString(playerEntity.Value):player} is attempting to ghost via command");
+            {
+                if (forced)
+                    _adminLog.Add(LogType.Mind, $"{EntityManager.ToPrettyString(playerEntity.Value):player} was forced to ghost via command");
+                else
+                    _adminLog.Add(LogType.Mind, $"{EntityManager.ToPrettyString(playerEntity.Value):player} is attempting to ghost via command");
+            }
 
             var handleEv = new GhostAttemptHandleEvent(mind, canReturnGlobal);
             RaiseLocalEvent(handleEv);
@@ -516,7 +521,7 @@ namespace Content.Server.Ghost
             if (handleEv.Handled)
                 return handleEv.Result;
 
-            if (mind.PreventGhosting)
+            if (mind.PreventGhosting && !forced)
             {
                 if (mind.Session != null) // Logging is suppressed to prevent spam from ghost attempts caused by movement attempts
                 {
diff --git a/Resources/Locale/en-US/administration/commands/forceghost.ftl b/Resources/Locale/en-US/administration/commands/forceghost.ftl
new file mode 100644 (file)
index 0000000..9d74409
--- /dev/null
@@ -0,0 +1,6 @@
+cmd-forceghost-desc = Makes a player an observer.
+cmd-forceghost-help = Usage: forceghost <player>
+
+cmd-forceghost-error-lobby = Target player can't ghost right now. They are not in the game!
+cmd-forceghost-denied = Failed to ghost the target player.
+cmd-forceghost-hint = <player>