Skip to content
This repository was archived by the owner on Dec 23, 2025. It is now read-only.

Commit 5fa56ba

Browse files
Strip All Debug Verb (space-wizards#37426)
* init * yippee * review * permission check * command * loc * review * review * Apply suggestions from code review --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
1 parent a3418d5 commit 5fa56ba

5 files changed

Lines changed: 109 additions & 18 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using Content.Shared.Administration;
2+
using Content.Shared.Hands.Components;
3+
using Content.Shared.Hands.EntitySystems;
4+
using Content.Shared.Inventory;
5+
using Robust.Shared.Console;
6+
7+
namespace Content.Server.Administration.Commands;
8+
9+
[AdminCommand(AdminFlags.Debug)]
10+
public sealed class StripAllCommand : LocalizedEntityCommands
11+
{
12+
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
13+
[Dependency] private readonly InventorySystem _inventorySystem = default!;
14+
15+
public override string Command => "stripall";
16+
17+
public override void Execute(IConsoleShell shell, string argStr, string[] args)
18+
{
19+
if (args.Length != 1)
20+
{
21+
shell.WriteLine(Loc.GetString("shell-need-exactly-one-argument"));
22+
return;
23+
}
24+
25+
if (!NetEntity.TryParse(args[0], out var targetUidNet) || !EntityManager.TryGetEntity(targetUidNet, out var targetEntity))
26+
{
27+
shell.WriteLine(Loc.GetString("shell-entity-uid-must-be-number"));
28+
return;
29+
}
30+
31+
if (!EntityManager.TryGetComponent<InventoryComponent>(targetEntity, out var inventory))
32+
{
33+
shell.WriteLine(Loc.GetString("shell-entity-target-lacks-component", ("componentName", nameof(InventoryComponent))));
34+
return;
35+
}
36+
37+
var slots = _inventorySystem.GetSlotEnumerator((targetEntity.Value, inventory));
38+
while (slots.NextItem(out _, out var slot))
39+
{
40+
_inventorySystem.TryUnequip(targetEntity.Value, targetEntity.Value, slot.Name, true, true, inventory: inventory);
41+
}
42+
43+
if (EntityManager.TryGetComponent<HandsComponent>(targetEntity, out var hands))
44+
{
45+
foreach (var hand in _handsSystem.EnumerateHands(targetEntity.Value, hands))
46+
{
47+
_handsSystem.TryDrop(targetEntity.Value,
48+
hand,
49+
checkActionBlocker: false,
50+
doDropInteraction: false,
51+
handsComp: hands);
52+
}
53+
}
54+
}
55+
56+
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
57+
{
58+
if (args.Length == 1)
59+
{
60+
return CompletionResult.FromHintOptions(
61+
CompletionHelper.Components<InventoryComponent>(args[0]),
62+
Loc.GetString("cmd-stripall-player-completion"));
63+
}
64+
65+
return CompletionResult.Empty;
66+
}
67+
}
68+

Content.Server/Administration/Systems/AdminVerbSystem.cs

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
using Content.Server.Disposal.Tube;
55
using Content.Server.EUI;
66
using Content.Server.Ghost.Roles;
7-
using Content.Server.Mind;
87
using Content.Server.Mind.Commands;
8+
using Content.Server.Mind;
99
using Content.Server.Prayer;
10+
using Content.Server.Silicons.Laws;
1011
using Content.Server.Station.Systems;
1112
using Content.Shared.Administration;
1213
using Content.Shared.Chemistry.Components.SolutionManager;
@@ -15,26 +16,26 @@
1516
using Content.Shared.Database;
1617
using Content.Shared.Examine;
1718
using Content.Shared.GameTicking;
19+
using Content.Shared.Hands.Components;
1820
using Content.Shared.Inventory;
1921
using Content.Shared.Mind.Components;
22+
using Content.Shared.Movement.Components;
2023
using Content.Shared.Popups;
24+
using Content.Shared.Silicons.Laws.Components;
25+
using Content.Shared.Silicons.StationAi;
2126
using Content.Shared.Verbs;
2227
using Robust.Server.Console;
2328
using Robust.Server.GameObjects;
29+
using Robust.Server.Player;
2430
using Robust.Shared.Console;
2531
using Robust.Shared.Map.Components;
32+
using Robust.Shared.Physics.Components;
2633
using Robust.Shared.Player;
2734
using Robust.Shared.Prototypes;
2835
using Robust.Shared.Timing;
2936
using Robust.Shared.Toolshed;
3037
using Robust.Shared.Utility;
3138
using System.Linq;
32-
using Content.Server.Silicons.Laws;
33-
using Content.Shared.Movement.Components;
34-
using Content.Shared.Silicons.Laws.Components;
35-
using Robust.Server.Player;
36-
using Content.Shared.Silicons.StationAi;
37-
using Robust.Shared.Physics.Components;
3839
using static Content.Shared.Configurable.ConfigurationComponent;
3940

4041
namespace Content.Server.Administration.Systems
@@ -463,19 +464,34 @@ private void AddDebugVerbs(GetVerbsEvent<Verb> args)
463464
args.Verbs.Add(verb);
464465
}
465466

466-
// Set clothing verb
467-
if (_groupController.CanCommand(player, "setoutfit") &&
468-
EntityManager.HasComponent<InventoryComponent>(args.Target))
467+
if (TryComp<InventoryComponent>(args.Target, out var inventoryComponent))
469468
{
470-
Verb verb = new()
469+
// Strip all verb
470+
if (_groupController.CanCommand(player, "stripall"))
471471
{
472-
Text = Loc.GetString("set-outfit-verb-get-data-text"),
473-
Category = VerbCategory.Debug,
474-
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/outfit.svg.192dpi.png")),
475-
Act = () => _euiManager.OpenEui(new SetOutfitEui(GetNetEntity(args.Target)), player),
476-
Impact = LogImpact.Medium
477-
};
478-
args.Verbs.Add(verb);
472+
args.Verbs.Add(new Verb
473+
{
474+
Text = Loc.GetString("strip-all-verb-get-data-text"),
475+
Category = VerbCategory.Debug,
476+
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/outfit.svg.192dpi.png")),
477+
Act = () => _console.RemoteExecuteCommand(player, $"stripall \"{args.Target}\""),
478+
Impact = LogImpact.Medium
479+
});
480+
}
481+
482+
// set outfit verb
483+
if (_groupController.CanCommand(player, "setoutfit"))
484+
{
485+
Verb verb = new()
486+
{
487+
Text = Loc.GetString("set-outfit-verb-get-data-text"),
488+
Category = VerbCategory.Debug,
489+
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/outfit.svg.192dpi.png")),
490+
Act = () => _euiManager.OpenEui(new SetOutfitEui(GetNetEntity(args.Target)), player),
491+
Impact = LogImpact.Medium
492+
};
493+
args.Verbs.Add(verb);
494+
}
479495
}
480496

481497
// In range unoccluded verb
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# stripall
2+
cmd-stripall-desc = Strips an entity of all their inventory and hands.
3+
cmd-stripall-help = Usage: stripall <EntityUid>
4+
5+
cmd-stripall-player-completion = <EntityUid>

Resources/Locale/en-US/shell.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ shell-entity-uid-must-be-number = EntityUid must be a number.
3434
shell-could-not-find-entity = Could not find entity {$entity}
3535
shell-could-not-find-entity-with-uid = Could not find entity with uid {$uid}
3636
shell-entity-with-uid-lacks-component = Entity with uid {$uid} doesn't have {INDEFINITE($componentName)} {$componentName} component
37+
shell-entity-target-lacks-component = Target entity doesn't have {INDEFINITE($componentName)} {$componentName} component
3738
shell-invalid-color-hex = Invalid color hex!
3839
shell-target-player-does-not-exist = Target player does not exist!
3940
shell-target-entity-does-not-have-message = Target entity does not have {INDEFINITE($missing)} {$missing}!

Resources/Locale/en-US/strip/strippable-component.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ strippable-component-alert-owner-interact = {CAPITALIZE(THE($user))} is fumbling
1616
1717
# StripVerb
1818
strip-verb-get-data-text = Strip
19+
strip-all-verb-get-data-text = Strip All
1920
2021
## UI
2122

0 commit comments

Comments
 (0)