]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Make aghost command work on other players using optional argument (#26546)
authorSimon <63975668+Simyon264@users.noreply.github.com>
Sun, 31 Mar 2024 02:05:44 +0000 (04:05 +0200)
committerGitHub <noreply@github.com>
Sun, 31 Mar 2024 02:05:44 +0000 (13:05 +1100)
* Translations

* Make aghost command work on other players using optional argument

* Reviews

Content.Server/Administration/Commands/AGhost.cs
Resources/Locale/en-US/administration/commands/aghost.ftl [new file with mode: 0644]
Resources/Locale/en-US/shell.ftl

index d541b1c8840a5ea59dd625679ca51e40f655eed6..935114e7a6830d6b95276fe03545e357ad12d01d 100644 (file)
-using Content.Server.GameTicking;
+using System.Linq;
+using Content.Server.GameTicking;
+using Content.Server.Ghost;
+using Content.Server.Mind;
 using Content.Shared.Administration;
 using Content.Shared.Ghost;
 using Content.Shared.Mind;
+using Robust.Server.GameObjects;
+using Robust.Server.Player;
 using Robust.Shared.Console;
 
-namespace Content.Server.Administration.Commands
+namespace Content.Server.Administration.Commands;
+
+[AdminCommand(AdminFlags.Admin)]
+public sealed class AGhost : LocalizedCommands
 {
-    [AdminCommand(AdminFlags.Admin)]
-    public sealed class AGhost : IConsoleCommand
+    [Dependency] private readonly IEntityManager _entities = default!;
+    [Dependency] private readonly IPlayerManager _playerManager = default!;
+
+    public override string Command => "aghost";
+    public override string Description => LocalizationManager.GetString("aghost-description");
+    public override string Help => "aghost";
+
+    public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
     {
-        [Dependency] private readonly IEntityManager _entities = default!;
+        if (args.Length == 1)
+        {
+            var names = _playerManager.Sessions.OrderBy(c => c.Name).Select(c => c.Name).ToArray();
+            return CompletionResult.FromHintOptions(names, LocalizationManager.GetString("shell-argument-username-optional-hint"));
+        }
 
-        public string Command => "aghost";
-        public string Description => "Makes you an admin ghost.";
-        public string Help => "aghost";
+        return CompletionResult.Empty;
+    }
 
-        public void Execute(IConsoleShell shell, string argStr, string[] args)
+    public override void Execute(IConsoleShell shell, string argStr, string[] args)
+    {
+        if (args.Length > 1)
         {
-            var player = shell.Player;
-            if (player == null)
+            shell.WriteError(LocalizationManager.GetString("shell-wrong-arguments-number"));
+            return;
+        }
+
+        var player = shell.Player;
+        var self = player != null;
+        if (player == null)
+        {
+            // If you are not a player, you require a player argument.
+            if (args.Length == 0)
             {
-                shell.WriteLine("Nah");
+                shell.WriteError(LocalizationManager.GetString("shell-need-exactly-one-argument"));
                 return;
             }
 
-            var mindSystem = _entities.System<SharedMindSystem>();
-            if (!mindSystem.TryGetMind(player, out var mindId, out var mind))
+            var didFind = _playerManager.TryGetSessionByUsername(args[0], out player);
+            if (!didFind)
             {
-                shell.WriteLine("You can't ghost here!");
+                shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist"));
                 return;
             }
+        }
 
-            var metaDataSystem = _entities.System<MetaDataSystem>();
-
-            if (mind.VisitingEntity != default && _entities.TryGetComponent<GhostComponent>(mind.VisitingEntity, out var oldGhostComponent))
+        // If you are a player and a username is provided, a lookup is done to find the target player.
+        if (args.Length == 1)
+        {
+            var didFind = _playerManager.TryGetSessionByUsername(args[0], out player);
+            if (!didFind)
             {
-                mindSystem.UnVisit(mindId, mind);
-                // If already an admin ghost, then return to body.
-                if (oldGhostComponent.CanGhostInteract)
-                    return;
+                shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist"));
+                return;
             }
+        }
 
-            var canReturn = mind.CurrentEntity != null
-                            && !_entities.HasComponent<GhostComponent>(mind.CurrentEntity);
-            var coordinates = player.AttachedEntity != null
-                ? _entities.GetComponent<TransformComponent>(player.AttachedEntity.Value).Coordinates
-                : EntitySystem.Get<GameTicker>().GetObserverSpawnPoint();
-            var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates);
-            _entities.GetComponent<TransformComponent>(ghost).AttachToGridOrMap();
+        var mindSystem = _entities.System<SharedMindSystem>();
+        var metaDataSystem = _entities.System<MetaDataSystem>();
+        var ghostSystem = _entities.System<SharedGhostSystem>();
+        var transformSystem = _entities.System<TransformSystem>();
+        var gameTicker = _entities.System<GameTicker>();
 
-            if (canReturn)
-            {
-                // TODO: Remove duplication between all this and "GamePreset.OnGhostAttempt()"...
-                if (!string.IsNullOrWhiteSpace(mind.CharacterName))
-                    metaDataSystem.SetEntityName(ghost, mind.CharacterName);
-                else if (!string.IsNullOrWhiteSpace(mind.Session?.Name))
-                    metaDataSystem.SetEntityName(ghost, mind.Session.Name);
+        if (!mindSystem.TryGetMind(player, out var mindId, out var mind))
+        {
+            shell.WriteError(self
+                ? LocalizationManager.GetString("aghost-no-mind-self")
+                : LocalizationManager.GetString("aghost-no-mind-other"));
+            return;
+        }
 
-                mindSystem.Visit(mindId, ghost, mind);
-            }
-            else
-            {
-                metaDataSystem.SetEntityName(ghost, player.Name);
-                mindSystem.TransferTo(mindId, ghost, mind: mind);
-            }
+        if (mind.VisitingEntity != default && _entities.TryGetComponent<GhostComponent>(mind.VisitingEntity, out var oldGhostComponent))
+        {
+            mindSystem.UnVisit(mindId, mind);
+            // If already an admin ghost, then return to body.
+            if (oldGhostComponent.CanGhostInteract)
+                return;
+        }
+
+        var canReturn = mind.CurrentEntity != null
+                        && !_entities.HasComponent<GhostComponent>(mind.CurrentEntity);
+        var coordinates = player!.AttachedEntity != null
+            ? _entities.GetComponent<TransformComponent>(player.AttachedEntity.Value).Coordinates
+            : gameTicker.GetObserverSpawnPoint();
+        var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates);
+        transformSystem.AttachToGridOrMap(ghost, _entities.GetComponent<TransformComponent>(ghost));
+
+        if (canReturn)
+        {
+            // TODO: Remove duplication between all this and "GamePreset.OnGhostAttempt()"...
+            if (!string.IsNullOrWhiteSpace(mind.CharacterName))
+                metaDataSystem.SetEntityName(ghost, mind.CharacterName);
+            else if (!string.IsNullOrWhiteSpace(mind.Session?.Name))
+                metaDataSystem.SetEntityName(ghost, mind.Session.Name);
 
-            var comp = _entities.GetComponent<GhostComponent>(ghost);
-            EntitySystem.Get<SharedGhostSystem>().SetCanReturnToBody(comp, canReturn);
+            mindSystem.Visit(mindId, ghost, mind);
         }
+        else
+        {
+            metaDataSystem.SetEntityName(ghost, player.Name);
+            mindSystem.TransferTo(mindId, ghost, mind: mind);
+        }
+
+        var comp = _entities.GetComponent<GhostComponent>(ghost);
+        ghostSystem.SetCanReturnToBody(comp, canReturn);
     }
 }
diff --git a/Resources/Locale/en-US/administration/commands/aghost.ftl b/Resources/Locale/en-US/administration/commands/aghost.ftl
new file mode 100644 (file)
index 0000000..4de0639
--- /dev/null
@@ -0,0 +1,3 @@
+aghost-description = Makes you an admin ghost.
+aghost-no-mind-self = You can't ghost here!
+aghost-no-mind-other = They can't ghost here!
index 7a66fbc794d721659b4d43be549a897d17301ef2..34460f001a056d97ccdd4ae7d9d615a879f15583 100644 (file)
@@ -47,3 +47,4 @@ shell-argument-number-invalid = Argument {$index} must be a valid number!
 
 # Hints
 shell-argument-username-hint = <username>
+shell-argument-username-optional-hint = [username]