Stop admin verb pop-in (#27450)
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.Administration.Managers;
|
||||||
|
using Content.Shared.Mind.Components;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
using Robust.Client.Console;
|
using Robust.Client.Console;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -11,10 +14,12 @@ namespace Content.Client.Administration.Systems
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IClientConGroupController _clientConGroupController = default!;
|
[Dependency] private readonly IClientConGroupController _clientConGroupController = default!;
|
||||||
[Dependency] private readonly IClientConsoleHost _clientConsoleHost = default!;
|
[Dependency] private readonly IClientConsoleHost _clientConsoleHost = default!;
|
||||||
|
[Dependency] private readonly ISharedAdminManager _admin = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<GetVerbsEvent<Verb>>(AddAdminVerbs);
|
SubscribeLocalEvent<GetVerbsEvent<Verb>>(AddAdminVerbs);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAdminVerbs(GetVerbsEvent<Verb> args)
|
private void AddAdminVerbs(GetVerbsEvent<Verb> args)
|
||||||
@@ -33,6 +38,24 @@ namespace Content.Client.Administration.Systems
|
|||||||
};
|
};
|
||||||
args.Verbs.Add(verb);
|
args.Verbs.Add(verb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_admin.IsAdmin(args.User))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_admin.HasAdminFlag(args.User, AdminFlags.Admin))
|
||||||
|
args.ExtraCategories.Add(VerbCategory.Admin);
|
||||||
|
|
||||||
|
if (_admin.HasAdminFlag(args.User, AdminFlags.Fun) && HasComp<MindContainerComponent>(args.Target))
|
||||||
|
args.ExtraCategories.Add(VerbCategory.Antag);
|
||||||
|
|
||||||
|
if (_admin.HasAdminFlag(args.User, AdminFlags.Debug))
|
||||||
|
args.ExtraCategories.Add(VerbCategory.Debug);
|
||||||
|
|
||||||
|
if (_admin.HasAdminFlag(args.User, AdminFlags.Fun))
|
||||||
|
args.ExtraCategories.Add(VerbCategory.Smite);
|
||||||
|
|
||||||
|
if (_admin.HasAdminFlag(args.User, AdminFlags.Admin))
|
||||||
|
args.ExtraCategories.Add(VerbCategory.Tricks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace Content.Client.Verbs.UI
|
|||||||
|
|
||||||
public NetEntity CurrentTarget;
|
public NetEntity CurrentTarget;
|
||||||
public SortedSet<Verb> CurrentVerbs = new();
|
public SortedSet<Verb> CurrentVerbs = new();
|
||||||
|
public List<VerbCategory> ExtraCategories = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Separate from <see cref="ContextMenuUIController.RootMenu"/>, since we can open a verb menu as a submenu
|
/// Separate from <see cref="ContextMenuUIController.RootMenu"/>, since we can open a verb menu as a submenu
|
||||||
@@ -91,19 +92,12 @@ namespace Content.Client.Verbs.UI
|
|||||||
menu.MenuBody.DisposeAllChildren();
|
menu.MenuBody.DisposeAllChildren();
|
||||||
|
|
||||||
CurrentTarget = target;
|
CurrentTarget = target;
|
||||||
CurrentVerbs = _verbSystem.GetVerbs(target, user, Verb.VerbTypes, force);
|
CurrentVerbs = _verbSystem.GetVerbs(target, user, Verb.VerbTypes, out ExtraCategories, force);
|
||||||
OpenMenu = menu;
|
OpenMenu = menu;
|
||||||
|
|
||||||
// Fill in client-side verbs.
|
// Fill in client-side verbs.
|
||||||
FillVerbPopup(menu);
|
FillVerbPopup(menu);
|
||||||
|
|
||||||
// Add indicator that some verbs may be missing.
|
|
||||||
// I long for the day when verbs will all be predicted and this becomes unnecessary.
|
|
||||||
if (!target.IsClientSide())
|
|
||||||
{
|
|
||||||
_context.AddElement(menu, new ContextMenuElement(Loc.GetString("verb-system-waiting-on-server-text")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// if popup isn't null (ie we are opening out of an entity menu element),
|
// if popup isn't null (ie we are opening out of an entity menu element),
|
||||||
// assume that that is going to handle opening the submenu properly
|
// assume that that is going to handle opening the submenu properly
|
||||||
if (popup != null)
|
if (popup != null)
|
||||||
@@ -128,11 +122,19 @@ namespace Content.Client.Verbs.UI
|
|||||||
var element = new VerbMenuElement(verb);
|
var element = new VerbMenuElement(verb);
|
||||||
_context.AddElement(popup, element);
|
_context.AddElement(popup, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (listedCategories.Add(verb.Category.Text))
|
else if (listedCategories.Add(verb.Category.Text))
|
||||||
AddVerbCategory(verb.Category, popup);
|
AddVerbCategory(verb.Category, popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ExtraCategories != null)
|
||||||
|
{
|
||||||
|
foreach (var category in ExtraCategories)
|
||||||
|
{
|
||||||
|
if (listedCategories.Add(category.Text))
|
||||||
|
AddVerbCategory(category, popup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
popup.InvalidateMeasure();
|
popup.InvalidateMeasure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,10 +155,11 @@ namespace Content.Client.Verbs.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbsInCategory.Count == 0)
|
if (verbsInCategory.Count == 0 && !ExtraCategories.Contains(category))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var element = new VerbMenuElement(category, verbsInCategory[0].TextStyleClass);
|
var style = verbsInCategory.FirstOrDefault()?.TextStyleClass ?? Verb.DefaultTextStyleClass;
|
||||||
|
var element = new VerbMenuElement(category, style);
|
||||||
_context.AddElement(popup, element);
|
_context.AddElement(popup, element);
|
||||||
|
|
||||||
// Create the pop-up that appears when hovering over this element
|
// Create the pop-up that appears when hovering over this element
|
||||||
|
|||||||
@@ -165,29 +165,23 @@ namespace Content.Client.Verbs
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asks the server to send back a list of server-side verbs, for the given verb type.
|
|
||||||
/// </summary>
|
|
||||||
public SortedSet<Verb> GetVerbs(EntityUid target, EntityUid user, Type type, bool force = false)
|
|
||||||
{
|
|
||||||
return GetVerbs(GetNetEntity(target), user, new List<Type>() { type }, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ask the server to send back a list of server-side verbs, and for now return an incomplete list of 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).
|
/// (only those defined locally).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SortedSet<Verb> GetVerbs(NetEntity target, EntityUid user, List<Type> verbTypes,
|
public SortedSet<Verb> GetVerbs(NetEntity target, EntityUid user, List<Type> verbTypes, out List<VerbCategory> extraCategories, bool force = false)
|
||||||
bool force = false)
|
|
||||||
{
|
{
|
||||||
if (!target.IsClientSide())
|
if (!target.IsClientSide())
|
||||||
RaiseNetworkEvent(new RequestServerVerbsEvent(target, verbTypes, adminRequest: force));
|
RaiseNetworkEvent(new RequestServerVerbsEvent(target, verbTypes, adminRequest: force));
|
||||||
|
|
||||||
// Some admin menu interactions will try get verbs for entities that have not yet been sent to the player.
|
// Some admin menu interactions will try get verbs for entities that have not yet been sent to the player.
|
||||||
if (!TryGetEntity(target, out var local))
|
if (!TryGetEntity(target, out var local))
|
||||||
|
{
|
||||||
|
extraCategories = new();
|
||||||
return new();
|
return new();
|
||||||
|
}
|
||||||
|
|
||||||
return GetLocalVerbs(local.Value, user, verbTypes, force);
|
return GetLocalVerbs(local.Value, user, verbTypes, out extraCategories, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -55,13 +55,21 @@ namespace Content.Shared.Verbs
|
|||||||
return GetLocalVerbs(target, user, new List<Type>() { type }, force);
|
return GetLocalVerbs(target, user, new List<Type>() { type }, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="GetLocalVerbs(Robust.Shared.GameObjects.EntityUid,Robust.Shared.GameObjects.EntityUid,System.Type,bool)"/>
|
||||||
|
public SortedSet<Verb> GetLocalVerbs(EntityUid target, EntityUid user, List<Type> types, bool force = false)
|
||||||
|
{
|
||||||
|
return GetLocalVerbs(target, user, types, out _, force);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raises a number of events in order to get all verbs of the given type(s) defined in local systems. This
|
/// Raises a number of events in order to get all verbs of the given type(s) defined in local systems. This
|
||||||
/// does not request verbs from the server.
|
/// does not request verbs from the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SortedSet<Verb> GetLocalVerbs(EntityUid target, EntityUid user, List<Type> types, bool force = false)
|
public SortedSet<Verb> GetLocalVerbs(EntityUid target, EntityUid user, List<Type> types,
|
||||||
|
out List<VerbCategory> extraCategories, bool force = false)
|
||||||
{
|
{
|
||||||
SortedSet<Verb> verbs = new();
|
SortedSet<Verb> verbs = new();
|
||||||
|
extraCategories = new();
|
||||||
|
|
||||||
// accessibility checks
|
// accessibility checks
|
||||||
bool canAccess = false;
|
bool canAccess = false;
|
||||||
@@ -108,7 +116,7 @@ namespace Content.Shared.Verbs
|
|||||||
// TODO: fix this garbage and use proper generics or reflection or something else, not this.
|
// TODO: fix this garbage and use proper generics or reflection or something else, not this.
|
||||||
if (types.Contains(typeof(InteractionVerb)))
|
if (types.Contains(typeof(InteractionVerb)))
|
||||||
{
|
{
|
||||||
var verbEvent = new GetVerbsEvent<InteractionVerb>(user, target, @using, hands, canInteract, canAccess);
|
var verbEvent = new GetVerbsEvent<InteractionVerb>(user, target, @using, hands, canInteract, canAccess, extraCategories);
|
||||||
RaiseLocalEvent(target, verbEvent, true);
|
RaiseLocalEvent(target, verbEvent, true);
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
@@ -117,35 +125,35 @@ namespace Content.Shared.Verbs
|
|||||||
&& @using != null
|
&& @using != null
|
||||||
&& @using != target)
|
&& @using != target)
|
||||||
{
|
{
|
||||||
var verbEvent = new GetVerbsEvent<UtilityVerb>(user, target, @using, hands, canInteract, canAccess);
|
var verbEvent = new GetVerbsEvent<UtilityVerb>(user, target, @using, hands, canInteract, canAccess, extraCategories);
|
||||||
RaiseLocalEvent(@using.Value, verbEvent, true); // directed at used, not at target
|
RaiseLocalEvent(@using.Value, verbEvent, true); // directed at used, not at target
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types.Contains(typeof(InnateVerb)))
|
if (types.Contains(typeof(InnateVerb)))
|
||||||
{
|
{
|
||||||
var verbEvent = new GetVerbsEvent<InnateVerb>(user, target, @using, hands, canInteract, canAccess);
|
var verbEvent = new GetVerbsEvent<InnateVerb>(user, target, @using, hands, canInteract, canAccess, extraCategories);
|
||||||
RaiseLocalEvent(user, verbEvent, true);
|
RaiseLocalEvent(user, verbEvent, true);
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types.Contains(typeof(AlternativeVerb)))
|
if (types.Contains(typeof(AlternativeVerb)))
|
||||||
{
|
{
|
||||||
var verbEvent = new GetVerbsEvent<AlternativeVerb>(user, target, @using, hands, canInteract, canAccess);
|
var verbEvent = new GetVerbsEvent<AlternativeVerb>(user, target, @using, hands, canInteract, canAccess, extraCategories);
|
||||||
RaiseLocalEvent(target, verbEvent, true);
|
RaiseLocalEvent(target, verbEvent, true);
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types.Contains(typeof(ActivationVerb)))
|
if (types.Contains(typeof(ActivationVerb)))
|
||||||
{
|
{
|
||||||
var verbEvent = new GetVerbsEvent<ActivationVerb>(user, target, @using, hands, canInteract, canAccess);
|
var verbEvent = new GetVerbsEvent<ActivationVerb>(user, target, @using, hands, canInteract, canAccess, extraCategories);
|
||||||
RaiseLocalEvent(target, verbEvent, true);
|
RaiseLocalEvent(target, verbEvent, true);
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types.Contains(typeof(ExamineVerb)))
|
if (types.Contains(typeof(ExamineVerb)))
|
||||||
{
|
{
|
||||||
var verbEvent = new GetVerbsEvent<ExamineVerb>(user, target, @using, hands, canInteract, canAccess);
|
var verbEvent = new GetVerbsEvent<ExamineVerb>(user, target, @using, hands, canInteract, canAccess, extraCategories);
|
||||||
RaiseLocalEvent(target, verbEvent, true);
|
RaiseLocalEvent(target, verbEvent, true);
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
@@ -153,7 +161,7 @@ namespace Content.Shared.Verbs
|
|||||||
// generic verbs
|
// generic verbs
|
||||||
if (types.Contains(typeof(Verb)))
|
if (types.Contains(typeof(Verb)))
|
||||||
{
|
{
|
||||||
var verbEvent = new GetVerbsEvent<Verb>(user, target, @using, hands, canInteract, canAccess);
|
var verbEvent = new GetVerbsEvent<Verb>(user, target, @using, hands, canInteract, canAccess, extraCategories);
|
||||||
RaiseLocalEvent(target, verbEvent, true);
|
RaiseLocalEvent(target, verbEvent, true);
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
@@ -161,7 +169,7 @@ namespace Content.Shared.Verbs
|
|||||||
if (types.Contains(typeof(EquipmentVerb)))
|
if (types.Contains(typeof(EquipmentVerb)))
|
||||||
{
|
{
|
||||||
var access = canAccess || _interactionSystem.CanAccessEquipment(user, target);
|
var access = canAccess || _interactionSystem.CanAccessEquipment(user, target);
|
||||||
var verbEvent = new GetVerbsEvent<EquipmentVerb>(user, target, @using, hands, canInteract, access);
|
var verbEvent = new GetVerbsEvent<EquipmentVerb>(user, target, @using, hands, canInteract, access, extraCategories);
|
||||||
RaiseLocalEvent(target, verbEvent);
|
RaiseLocalEvent(target, verbEvent);
|
||||||
verbs.UnionWith(verbEvent.Verbs);
|
verbs.UnionWith(verbEvent.Verbs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ namespace Content.Shared.Verbs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly SortedSet<TVerb> Verbs = new();
|
public readonly SortedSet<TVerb> Verbs = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Additional verb categories to show in the pop-up menu, even if there are no verbs currently associated
|
||||||
|
/// with that category. This is mainly useful to prevent verb menu pop-in. E.g., admins will get admin/debug
|
||||||
|
/// related verbs on entities, even though most of those verbs are all defined server-side.
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<VerbCategory> ExtraCategories;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Can the user physically access the target?
|
/// Can the user physically access the target?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -123,7 +130,7 @@ namespace Content.Shared.Verbs
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public readonly EntityUid? Using;
|
public readonly EntityUid? Using;
|
||||||
|
|
||||||
public GetVerbsEvent(EntityUid user, EntityUid target, EntityUid? @using, HandsComponent? hands, bool canInteract, bool canAccess)
|
public GetVerbsEvent(EntityUid user, EntityUid target, EntityUid? @using, HandsComponent? hands, bool canInteract, bool canAccess, List<VerbCategory> extraCategories)
|
||||||
{
|
{
|
||||||
User = user;
|
User = user;
|
||||||
Target = target;
|
Target = target;
|
||||||
@@ -131,6 +138,7 @@ namespace Content.Shared.Verbs
|
|||||||
Hands = hands;
|
Hands = hands;
|
||||||
CanAccess = canAccess;
|
CanAccess = canAccess;
|
||||||
CanInteract = canInteract;
|
CanInteract = canInteract;
|
||||||
|
ExtraCategories = extraCategories;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
verb-system-waiting-on-server-text = Waiting on Server...
|
|
||||||
verb-system-null-server-response = Entity not in view. You should not see this.
|
verb-system-null-server-response = Entity not in view. You should not see this.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user