AGhostCommand.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using System.Linq;
  2. using Content.Server.GameTicking;
  3. using Content.Server.Ghost;
  4. using Content.Server.Mind;
  5. using Content.Shared.Administration;
  6. using Content.Shared.Ghost;
  7. using Content.Shared.Mind;
  8. using Robust.Server.GameObjects;
  9. using Robust.Server.Player;
  10. using Robust.Shared.Console;
  11. namespace Content.Server.Administration.Commands;
  12. [AdminCommand(AdminFlags.Admin)]
  13. public sealed class AGhostCommand : LocalizedCommands
  14. {
  15. [Dependency] private readonly IEntityManager _entities = default!;
  16. [Dependency] private readonly IPlayerManager _playerManager = default!;
  17. public override string Command => "aghost";
  18. public override string Help => "aghost";
  19. public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
  20. {
  21. if (args.Length == 1)
  22. {
  23. var names = _playerManager.Sessions.OrderBy(c => c.Name).Select(c => c.Name).ToArray();
  24. return CompletionResult.FromHintOptions(names, LocalizationManager.GetString("shell-argument-username-optional-hint"));
  25. }
  26. return CompletionResult.Empty;
  27. }
  28. public override void Execute(IConsoleShell shell, string argStr, string[] args)
  29. {
  30. if (args.Length > 1)
  31. {
  32. shell.WriteError(LocalizationManager.GetString("shell-wrong-arguments-number"));
  33. return;
  34. }
  35. var player = shell.Player;
  36. var self = player != null;
  37. if (player == null)
  38. {
  39. // If you are not a player, you require a player argument.
  40. if (args.Length == 0)
  41. {
  42. shell.WriteError(LocalizationManager.GetString("shell-need-exactly-one-argument"));
  43. return;
  44. }
  45. var didFind = _playerManager.TryGetSessionByUsername(args[0], out player);
  46. if (!didFind)
  47. {
  48. shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist"));
  49. return;
  50. }
  51. }
  52. // If you are a player and a username is provided, a lookup is done to find the target player.
  53. if (args.Length == 1)
  54. {
  55. var didFind = _playerManager.TryGetSessionByUsername(args[0], out player);
  56. if (!didFind)
  57. {
  58. shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist"));
  59. return;
  60. }
  61. }
  62. var mindSystem = _entities.System<SharedMindSystem>();
  63. var metaDataSystem = _entities.System<MetaDataSystem>();
  64. var ghostSystem = _entities.System<SharedGhostSystem>();
  65. var transformSystem = _entities.System<TransformSystem>();
  66. var gameTicker = _entities.System<GameTicker>();
  67. if (!mindSystem.TryGetMind(player, out var mindId, out var mind))
  68. {
  69. shell.WriteError(self
  70. ? LocalizationManager.GetString("aghost-no-mind-self")
  71. : LocalizationManager.GetString("aghost-no-mind-other"));
  72. return;
  73. }
  74. if (mind.VisitingEntity != default && _entities.TryGetComponent<GhostComponent>(mind.VisitingEntity, out var oldGhostComponent))
  75. {
  76. mindSystem.UnVisit(mindId, mind);
  77. // If already an admin ghost, then return to body.
  78. if (oldGhostComponent.CanGhostInteract)
  79. return;
  80. }
  81. var canReturn = mind.CurrentEntity != null
  82. && !_entities.HasComponent<GhostComponent>(mind.CurrentEntity);
  83. var coordinates = player!.AttachedEntity != null
  84. ? _entities.GetComponent<TransformComponent>(player.AttachedEntity.Value).Coordinates
  85. : gameTicker.GetObserverSpawnPoint();
  86. var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates);
  87. transformSystem.AttachToGridOrMap(ghost, _entities.GetComponent<TransformComponent>(ghost));
  88. if (canReturn)
  89. {
  90. // TODO: Remove duplication between all this and "GamePreset.OnGhostAttempt()"...
  91. if (!string.IsNullOrWhiteSpace(mind.CharacterName))
  92. metaDataSystem.SetEntityName(ghost, mind.CharacterName);
  93. else if (!string.IsNullOrWhiteSpace(mind.Session?.Name))
  94. metaDataSystem.SetEntityName(ghost, mind.Session.Name);
  95. mindSystem.Visit(mindId, ghost, mind);
  96. }
  97. else
  98. {
  99. metaDataSystem.SetEntityName(ghost, player.Name);
  100. mindSystem.TransferTo(mindId, ghost, mind: mind);
  101. }
  102. var comp = _entities.GetComponent<GhostComponent>(ghost);
  103. ghostSystem.SetCanReturnToBody(comp, canReturn);
  104. }
  105. }