From: Simon <63975668+Simyon264@users.noreply.github.com> Date: Sun, 31 Mar 2024 02:05:44 +0000 (+0200) Subject: Make aghost command work on other players using optional argument (#26546) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=87a56b25c3f06ea98661684b8e62f8acb0afee85;p=space-station-14.git Make aghost command work on other players using optional argument (#26546) * Translations * Make aghost command work on other players using optional argument * Reviews --- diff --git a/Content.Server/Administration/Commands/AGhost.cs b/Content.Server/Administration/Commands/AGhost.cs index d541b1c884..935114e7a6 100644 --- a/Content.Server/Administration/Commands/AGhost.cs +++ b/Content.Server/Administration/Commands/AGhost.cs @@ -1,72 +1,122 @@ -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(); - 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(); - - if (mind.VisitingEntity != default && _entities.TryGetComponent(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(mind.CurrentEntity); - var coordinates = player.AttachedEntity != null - ? _entities.GetComponent(player.AttachedEntity.Value).Coordinates - : EntitySystem.Get().GetObserverSpawnPoint(); - var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates); - _entities.GetComponent(ghost).AttachToGridOrMap(); + var mindSystem = _entities.System(); + var metaDataSystem = _entities.System(); + var ghostSystem = _entities.System(); + var transformSystem = _entities.System(); + var gameTicker = _entities.System(); - 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(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(mind.CurrentEntity); + var coordinates = player!.AttachedEntity != null + ? _entities.GetComponent(player.AttachedEntity.Value).Coordinates + : gameTicker.GetObserverSpawnPoint(); + var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates); + transformSystem.AttachToGridOrMap(ghost, _entities.GetComponent(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(ghost); - EntitySystem.Get().SetCanReturnToBody(comp, canReturn); + mindSystem.Visit(mindId, ghost, mind); } + else + { + metaDataSystem.SetEntityName(ghost, player.Name); + mindSystem.TransferTo(mindId, ghost, mind: mind); + } + + var comp = _entities.GetComponent(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 index 0000000000..4de0639981 --- /dev/null +++ b/Resources/Locale/en-US/administration/commands/aghost.ftl @@ -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! diff --git a/Resources/Locale/en-US/shell.ftl b/Resources/Locale/en-US/shell.ftl index 7a66fbc794..34460f001a 100644 --- a/Resources/Locale/en-US/shell.ftl +++ b/Resources/Locale/en-US/shell.ftl @@ -47,3 +47,4 @@ shell-argument-number-invalid = Argument {$index} must be a valid number! # Hints shell-argument-username-hint = +shell-argument-username-optional-hint = [username]