add forceghost admin command (#35518)

* add forceghost admin command

* sweep linq under the rug

* braces

* ûse LocalizedEntityCommands
This commit is contained in:
slarticodefast
2025-03-08 03:39:04 +01:00
committed by GitHub
parent cca537fb33
commit 531f5619be
4 changed files with 76 additions and 4 deletions

View File

@@ -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;
}
}

View File

@@ -50,7 +50,7 @@ namespace Content.Server.Ghost
mind = _entities.GetComponent<MindComponent>(mindId); 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")); shell.WriteLine(Loc.GetString("ghost-command-denied"));
} }

View File

@@ -499,7 +499,7 @@ namespace Content.Server.Ghost
return 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)) if (!Resolve(mindId, ref mind))
return false; return false;
@@ -507,7 +507,12 @@ namespace Content.Server.Ghost
var playerEntity = mind.CurrentEntity; var playerEntity = mind.CurrentEntity;
if (playerEntity != null && viaCommand) if (playerEntity != null && viaCommand)
{
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"); _adminLog.Add(LogType.Mind, $"{EntityManager.ToPrettyString(playerEntity.Value):player} is attempting to ghost via command");
}
var handleEv = new GhostAttemptHandleEvent(mind, canReturnGlobal); var handleEv = new GhostAttemptHandleEvent(mind, canReturnGlobal);
RaiseLocalEvent(handleEv); RaiseLocalEvent(handleEv);
@@ -516,7 +521,7 @@ namespace Content.Server.Ghost
if (handleEv.Handled) if (handleEv.Handled)
return handleEv.Result; 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 if (mind.Session != null) // Logging is suppressed to prevent spam from ghost attempts caused by movement attempts
{ {

View File

@@ -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>