Fix admin verb PVS issue (#21406)
This commit is contained in:
@@ -60,7 +60,7 @@ namespace Content.Client.Administration.UI.CustomControls
|
|||||||
}
|
}
|
||||||
else if (args.Event.Function == EngineKeyFunctions.UseSecondary && selectedPlayer.NetEntity != null)
|
else if (args.Event.Function == EngineKeyFunctions.UseSecondary && selectedPlayer.NetEntity != null)
|
||||||
{
|
{
|
||||||
_uiManager.GetUIController<VerbMenuUIController>().OpenVerbMenu(_entManager.GetEntity(selectedPlayer.NetEntity.Value));
|
_uiManager.GetUIController<VerbMenuUIController>().OpenVerbMenu(selectedPlayer.NetEntity.Value, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,13 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab
|
|||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class PlayerTab : Control
|
public sealed partial class PlayerTab : Control
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _playerMan = default!;
|
||||||
|
|
||||||
private const string ArrowUp = "↑";
|
private const string ArrowUp = "↑";
|
||||||
private const string ArrowDown = "↓";
|
private const string ArrowDown = "↓";
|
||||||
private readonly Color _altColor = Color.FromHex("#292B38");
|
private readonly Color _altColor = Color.FromHex("#292B38");
|
||||||
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
|
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");
|
||||||
private IEntityManager _entManager;
|
|
||||||
private readonly AdminSystem _adminSystem;
|
private readonly AdminSystem _adminSystem;
|
||||||
private IReadOnlyList<PlayerInfo> _players = new List<PlayerInfo>();
|
private IReadOnlyList<PlayerInfo> _players = new List<PlayerInfo>();
|
||||||
|
|
||||||
@@ -30,7 +32,7 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab
|
|||||||
|
|
||||||
public PlayerTab()
|
public PlayerTab()
|
||||||
{
|
{
|
||||||
_entManager = IoCManager.Resolve<IEntityManager>();
|
IoCManager.InjectDependencies(this);
|
||||||
_adminSystem = _entManager.System<AdminSystem>();
|
_adminSystem = _entManager.System<AdminSystem>();
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
RefreshPlayerList(_adminSystem.PlayerList);
|
RefreshPlayerList(_adminSystem.PlayerList);
|
||||||
@@ -95,13 +97,11 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab
|
|||||||
foreach (var child in PlayerList.Children.ToArray())
|
foreach (var child in PlayerList.Children.ToArray())
|
||||||
{
|
{
|
||||||
if (child is PlayerTabEntry)
|
if (child is PlayerTabEntry)
|
||||||
child.Orphan();
|
child.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
_players = players;
|
_players = players;
|
||||||
|
PlayerCount.Text = $"Players: {_playerMan.PlayerCount}";
|
||||||
var playerManager = IoCManager.Resolve<IPlayerManager>();
|
|
||||||
PlayerCount.Text = $"Players: {playerManager.PlayerCount}";
|
|
||||||
|
|
||||||
var sortedPlayers = new List<PlayerInfo>(players);
|
var sortedPlayers = new List<PlayerInfo>(players);
|
||||||
sortedPlayers.Sort(Compare);
|
sortedPlayers.Sort(Compare);
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ public sealed class AdminUIController : UIController, IOnStateEntered<GameplaySt
|
|||||||
if (function == EngineKeyFunctions.UIClick)
|
if (function == EngineKeyFunctions.UIClick)
|
||||||
_conHost.ExecuteCommand($"vv {entity}");
|
_conHost.ExecuteCommand($"vv {entity}");
|
||||||
else if (function == EngineKeyFunctions.UseSecondary)
|
else if (function == EngineKeyFunctions.UseSecondary)
|
||||||
_verb.OpenVerbMenu(EntityManager.GetEntity(entity), true);
|
_verb.OpenVerbMenu(entity, true);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Robust.Client.Player;
|
|||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controllers;
|
using Robust.Client.UserInterface.Controllers;
|
||||||
using Robust.Shared.Input;
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.Verbs.UI
|
namespace Content.Client.Verbs.UI
|
||||||
{
|
{
|
||||||
@@ -29,7 +30,7 @@ namespace Content.Client.Verbs.UI
|
|||||||
[UISystemDependency] private readonly CombatModeSystem _combatMode = default!;
|
[UISystemDependency] private readonly CombatModeSystem _combatMode = default!;
|
||||||
[UISystemDependency] private readonly VerbSystem _verbSystem = default!;
|
[UISystemDependency] private readonly VerbSystem _verbSystem = default!;
|
||||||
|
|
||||||
public EntityUid CurrentTarget;
|
public NetEntity CurrentTarget;
|
||||||
public SortedSet<Verb> CurrentVerbs = new();
|
public SortedSet<Verb> CurrentVerbs = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -64,8 +65,25 @@ namespace Content.Client.Verbs.UI
|
|||||||
/// </param>
|
/// </param>
|
||||||
public void OpenVerbMenu(EntityUid target, bool force = false, ContextMenuPopup? popup=null)
|
public void OpenVerbMenu(EntityUid target, bool force = false, ContextMenuPopup? popup=null)
|
||||||
{
|
{
|
||||||
if (_playerManager.LocalPlayer?.ControlledEntity is not {Valid: true} user ||
|
DebugTools.Assert(target.IsValid());
|
||||||
_combatMode.IsInCombatMode(user))
|
OpenVerbMenu(EntityManager.GetNetEntity(target), force, popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open a verb menu and fill it with verbs applicable to the given target entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">Entity to get verbs on.</param>
|
||||||
|
/// <param name="force">Used to force showing all verbs. Only works on networked entities if the user is an admin.</param>
|
||||||
|
/// <param name="popup">
|
||||||
|
/// If this is not null, verbs will be placed into the given popup instead.
|
||||||
|
/// </param>
|
||||||
|
public void OpenVerbMenu(NetEntity target, bool force = false, ContextMenuPopup? popup=null)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(target.IsValid());
|
||||||
|
if (_playerManager.LocalEntity is not {Valid: true} user)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!force && _combatMode.IsInCombatMode(user))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
@@ -82,7 +100,7 @@ namespace Content.Client.Verbs.UI
|
|||||||
|
|
||||||
// Add indicator that some verbs may be missing.
|
// Add indicator that some verbs may be missing.
|
||||||
// I long for the day when verbs will all be predicted and this becomes unnecessary.
|
// I long for the day when verbs will all be predicted and this becomes unnecessary.
|
||||||
if (!EntityManager.IsClientSide(target))
|
if (!target.IsClientSide())
|
||||||
{
|
{
|
||||||
_context.AddElement(menu, new ContextMenuElement(Loc.GetString("verb-system-waiting-on-server-text")));
|
_context.AddElement(menu, new ContextMenuElement(Loc.GetString("verb-system-waiting-on-server-text")));
|
||||||
}
|
}
|
||||||
@@ -248,7 +266,7 @@ namespace Content.Client.Verbs.UI
|
|||||||
|
|
||||||
private void HandleVerbsResponse(VerbsResponseEvent msg)
|
private void HandleVerbsResponse(VerbsResponseEvent msg)
|
||||||
{
|
{
|
||||||
if (OpenMenu == null || !OpenMenu.Visible || CurrentTarget != EntityManager.GetEntity(msg.Entity))
|
if (OpenMenu == null || !OpenMenu.Visible || CurrentTarget != msg.Entity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AddServerVerbs(msg.Verbs, OpenMenu);
|
AddServerVerbs(msg.Verbs, OpenMenu);
|
||||||
|
|||||||
@@ -170,28 +170,27 @@ namespace Content.Client.Verbs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public SortedSet<Verb> GetVerbs(EntityUid target, EntityUid user, Type type, bool force = false)
|
public SortedSet<Verb> GetVerbs(EntityUid target, EntityUid user, Type type, bool force = false)
|
||||||
{
|
{
|
||||||
return GetVerbs(target, user, new List<Type>() { type }, force);
|
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(EntityUid target, EntityUid user, List<Type> verbTypes,
|
public SortedSet<Verb> GetVerbs(NetEntity target, EntityUid user, List<Type> verbTypes,
|
||||||
bool force = false)
|
bool force = false)
|
||||||
{
|
{
|
||||||
if (!IsClientSide(target))
|
if (!target.IsClientSide())
|
||||||
{
|
RaiseNetworkEvent(new RequestServerVerbsEvent(target, verbTypes, adminRequest: force));
|
||||||
RaiseNetworkEvent(new RequestServerVerbsEvent(GetNetEntity(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 (!Exists(target))
|
if (!TryGetEntity(target, out var local))
|
||||||
return new();
|
return new();
|
||||||
|
|
||||||
return GetLocalVerbs(target, user, verbTypes, force);
|
return GetLocalVerbs(local.Value, user, verbTypes, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Execute actions associated with the given verb.
|
/// Execute actions associated with the given verb.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -200,8 +199,18 @@ namespace Content.Client.Verbs
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void ExecuteVerb(EntityUid target, Verb verb)
|
public void ExecuteVerb(EntityUid target, Verb verb)
|
||||||
{
|
{
|
||||||
var user = _playerManager.LocalPlayer?.ControlledEntity;
|
ExecuteVerb(GetNetEntity(target), verb);
|
||||||
if (user == null)
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute actions associated with the given verb.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Unless this is a client-exclusive verb, this will also tell the server to run the same verb.
|
||||||
|
/// </remarks>
|
||||||
|
public void ExecuteVerb(NetEntity target, Verb verb)
|
||||||
|
{
|
||||||
|
if ( _playerManager.LocalEntity is not {} user)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// is this verb actually valid?
|
// is this verb actually valid?
|
||||||
@@ -209,16 +218,16 @@ namespace Content.Client.Verbs
|
|||||||
{
|
{
|
||||||
// maybe send an informative pop-up message.
|
// maybe send an informative pop-up message.
|
||||||
if (!string.IsNullOrWhiteSpace(verb.Message))
|
if (!string.IsNullOrWhiteSpace(verb.Message))
|
||||||
_popupSystem.PopupEntity(verb.Message, user.Value);
|
_popupSystem.PopupEntity(verb.Message, user);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verb.ClientExclusive || IsClientSide(target))
|
if (verb.ClientExclusive || target.IsClientSide())
|
||||||
// is this a client exclusive (gui) verb?
|
// is this a client exclusive (gui) verb?
|
||||||
ExecuteVerb(verb, user.Value, target);
|
ExecuteVerb(verb, user, GetEntity(target));
|
||||||
else
|
else
|
||||||
EntityManager.RaisePredictiveEvent(new ExecuteVerbEvent(GetNetEntity(target), verb));
|
EntityManager.RaisePredictiveEvent(new ExecuteVerbEvent(target, verb));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleVerbResponse(VerbsResponseEvent msg)
|
private void HandleVerbResponse(VerbsResponseEvent msg)
|
||||||
|
|||||||
@@ -24,16 +24,17 @@ namespace Content.Shared.Verbs
|
|||||||
if (user == null)
|
if (user == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var target = GetEntity(args.Target);
|
if (!TryGetEntity(args.Target, out var target))
|
||||||
|
return;
|
||||||
|
|
||||||
// It is possible that client-side prediction can cause this event to be raised after the target entity has
|
// It is possible that client-side prediction can cause this event to be raised after the target entity has
|
||||||
// been deleted. So we need to check that the entity still exists.
|
// been deleted. So we need to check that the entity still exists.
|
||||||
if (Deleted(target) || Deleted(user))
|
if (Deleted(user))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get the list of verbs. This effectively also checks that the requested verb is in fact a valid verb that
|
// Get the list of verbs. This effectively also checks that the requested verb is in fact a valid verb that
|
||||||
// the user can perform.
|
// the user can perform.
|
||||||
var verbs = GetLocalVerbs(target, user.Value, args.RequestedVerb.GetType());
|
var verbs = GetLocalVerbs(target.Value, user.Value, args.RequestedVerb.GetType());
|
||||||
|
|
||||||
// Note that GetLocalVerbs might waste time checking & preparing unrelated verbs even though we know
|
// Note that GetLocalVerbs might waste time checking & preparing unrelated verbs even though we know
|
||||||
// precisely which one we want to run. However, MOST entities will only have 1 or 2 verbs of a given type.
|
// precisely which one we want to run. However, MOST entities will only have 1 or 2 verbs of a given type.
|
||||||
@@ -41,7 +42,7 @@ namespace Content.Shared.Verbs
|
|||||||
|
|
||||||
// Find the requested verb.
|
// Find the requested verb.
|
||||||
if (verbs.TryGetValue(args.RequestedVerb, out var verb))
|
if (verbs.TryGetValue(args.RequestedVerb, out var verb))
|
||||||
ExecuteVerb(verb, user.Value, target);
|
ExecuteVerb(verb, user.Value, target.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user