diff --git a/Content.Client/Administration/AdminSystem.Menu.cs b/Content.Client/Administration/AdminSystem.Menu.cs index 5c2e329056..620fffec0c 100644 --- a/Content.Client/Administration/AdminSystem.Menu.cs +++ b/Content.Client/Administration/AdminSystem.Menu.cs @@ -3,6 +3,7 @@ using Content.Client.Administration.Managers; using Content.Client.Administration.UI; using Content.Client.Administration.UI.Tabs.PlayerTab; using Content.Client.HUD; +using Content.Client.Verbs; using Content.Shared.Input; using Robust.Client.Console; using Robust.Client.Graphics; @@ -11,6 +12,7 @@ using Robust.Client.ResourceManagement; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Shared.GameObjects; +using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.IoC; using Robust.Shared.Network; @@ -30,6 +32,8 @@ namespace Content.Client.Administration [Dependency] private readonly IEntityLookup _entityLookup = default!; [Dependency] private readonly IClientConsoleHost _clientConsoleHost = default!; + [Dependency] private readonly VerbSystem _verbSystem = default!; + private AdminMenuWindow? _window; private readonly List _commandWindows = new(); @@ -142,7 +146,17 @@ namespace Content.Client.Administration || button.PlayerUid == null) return; - _clientConsoleHost.ExecuteCommand($"vv {button.PlayerUid}"); + var uid = button.PlayerUid.Value; + var function = args.Event.Function; + + if (function == EngineKeyFunctions.UIClick) + _clientConsoleHost.ExecuteCommand($"vv {uid}"); + else if (function == ContentKeyFunctions.OpenContextMenu) + _verbSystem.VerbMenu.OpenVerbMenu(uid, true); + else + return; + + args.Event.Handle(); } } } diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs index 3dd0818cf0..3a9624106b 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Content.Client.Administration.UI.CustomControls; using Content.Shared.Administration; diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml index 6a0702be62..c54571d778 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml @@ -1,5 +1,6 @@  + xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls" + EnableAllKeybinds="True"> /// Open a verb menu and fill it work verbs applicable to the given target entity. /// - public void OpenVerbMenu(EntityUid target) + /// Entity to get verbs on. + /// Used to force showing all verbs (mostly for admins). + public void OpenVerbMenu(EntityUid target, bool force = false) { if (_playerManager.LocalPlayer?.ControlledEntity is not {Valid: true} user) return; @@ -49,7 +51,7 @@ namespace Content.Client.Verbs.UI Close(); CurrentTarget = target; - CurrentVerbs = _verbSystem.GetVerbs(target, user, VerbType.All); + CurrentVerbs = _verbSystem.GetVerbs(target, user, VerbType.All, force); if (!target.IsClientSide()) { diff --git a/Content.Client/Verbs/VerbSystem.cs b/Content.Client/Verbs/VerbSystem.cs index a557078d7e..7dfe818fcd 100644 --- a/Content.Client/Verbs/VerbSystem.cs +++ b/Content.Client/Verbs/VerbSystem.cs @@ -180,14 +180,15 @@ namespace Content.Client.Verbs /// Ask the server to send back a list of server-side verbs, and for now return an incomplete list of verbs /// (only those defined locally). /// - public Dictionary> GetVerbs(EntityUid target, EntityUid user, VerbType verbTypes) + public Dictionary> GetVerbs(EntityUid target, EntityUid user, VerbType verbTypes, + bool force = false) { if (!target.IsClientSide()) { - RaiseNetworkEvent(new RequestServerVerbsEvent(target, verbTypes)); + RaiseNetworkEvent(new RequestServerVerbsEvent(target, verbTypes, adminRequest: force)); } - return GetLocalVerbs(target, user, verbTypes); + return GetLocalVerbs(target, user, verbTypes, force); } /// diff --git a/Content.Server/Verbs/VerbSystem.cs b/Content.Server/Verbs/VerbSystem.cs index 83d8a43886..ea68499577 100644 --- a/Content.Server/Verbs/VerbSystem.cs +++ b/Content.Server/Verbs/VerbSystem.cs @@ -1,4 +1,6 @@ +using Content.Server.Administration.Managers; using Content.Server.Popups; +using Content.Shared.Administration; using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.Hands.Components; @@ -15,6 +17,7 @@ namespace Content.Server.Verbs { [Dependency] private readonly SharedAdminLogSystem _logSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly IAdminManager _adminMgr = default!; public override void Initialize() { @@ -43,7 +46,11 @@ namespace Content.Server.Verbs // this, and some verbs (e.g. view variables) won't even care about whether an entity is accessible through // the entity menu or not. - var response = new VerbsResponseEvent(args.EntityUid, GetLocalVerbs(args.EntityUid, attached, args.Type)); + var force = args.AdminRequest && eventArgs.SenderSession is IPlayerSession playerSession && + _adminMgr.HasAdminFlag(playerSession, AdminFlags.Admin); + + var response = + new VerbsResponseEvent(args.EntityUid, GetLocalVerbs(args.EntityUid, attached, args.Type, force)); RaiseNetworkEvent(response, player.ConnectedClient); } diff --git a/Content.Shared/Verbs/SharedVerbSystem.cs b/Content.Shared/Verbs/SharedVerbSystem.cs index fbae16c1b2..fcc1aea26b 100644 --- a/Content.Shared/Verbs/SharedVerbSystem.cs +++ b/Content.Shared/Verbs/SharedVerbSystem.cs @@ -51,7 +51,7 @@ namespace Content.Shared.Verbs bool canAccess = false; if (force || target == user) canAccess = true; - else if (_interactionSystem.InRangeUnobstructed(user, target, ignoreInsideBlocker: true)) + else if (EntityManager.EntityExists(target) && _interactionSystem.InRangeUnobstructed(user, target, ignoreInsideBlocker: true)) { if (user.IsInSameOrParentContainer(target)) canAccess = true; diff --git a/Content.Shared/Verbs/VerbEvents.cs b/Content.Shared/Verbs/VerbEvents.cs index e11386c36b..346b9d0bd6 100644 --- a/Content.Shared/Verbs/VerbEvents.cs +++ b/Content.Shared/Verbs/VerbEvents.cs @@ -21,12 +21,14 @@ namespace Content.Shared.Verbs /// public readonly EntityUid? SlotOwner; + public readonly bool AdminRequest; - public RequestServerVerbsEvent(EntityUid entityUid, VerbType type, EntityUid? slotOwner = null) + public RequestServerVerbsEvent(EntityUid entityUid, VerbType type, EntityUid? slotOwner = null, bool adminRequest = false) { EntityUid = entityUid; Type = type; SlotOwner = slotOwner; + AdminRequest = adminRequest; } }