Equipment verbs & admin inventory access. (#14315)

This commit is contained in:
Leon Friedrich
2023-03-06 06:12:08 +13:00
committed by GitHub
parent a9b268af49
commit b148bebd60
29 changed files with 499 additions and 141 deletions

View File

@@ -1,4 +1,5 @@
using Content.Shared.Administration;
using Content.Shared.Administration.Managers;
using Robust.Server.Player;
@@ -7,7 +8,7 @@ namespace Content.Server.Administration.Managers
/// <summary>
/// Manages server administrators and their permission flags.
/// </summary>
public interface IAdminManager
public interface IAdminManager : ISharedAdminManager
{
/// <summary>
/// Fired when the permissions of an admin on the server changed.
@@ -47,26 +48,6 @@ namespace Content.Server.Administration.Managers
/// <returns><see langword="null" /> if the player is not an admin.</returns>
AdminData? GetAdminData(IPlayerSession session, bool includeDeAdmin = false);
/// <summary>
/// Gets the admin data for a player, if they are an admin.
/// </summary>
/// <param name="uid">The entity being controlled by the player.</param>
/// <param name="includeDeAdmin">
/// Whether to return admin data for admins that are current de-adminned.
/// </param>
/// <returns><see langword="null" /> if the player is not an admin.</returns>
AdminData? GetAdminData(EntityUid uid, bool includeDeAdmin = false);
/// <summary>
/// See if a player has an admin flag.
/// </summary>
/// <returns>True if the player is and admin and has the specified flags.</returns>
bool HasAdminFlag(EntityUid player, AdminFlags flag)
{
var data = GetAdminData(player);
return data != null && data.HasFlag(flag);
}
/// <summary>
/// See if a player has an admin flag.
/// </summary>

View File

@@ -19,6 +19,7 @@ using Content.Shared.Stacks;
using Content.Shared.Throwing;
using JetBrains.Annotations;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Input.Binding;
@@ -42,6 +43,8 @@ namespace Content.Server.Hands.Systems
[Dependency] private readonly PullingSystem _pullingSystem = default!;
[Dependency] private readonly ThrowingSystem _throwingSystem = default!;
[Dependency] private readonly StorageSystem _storageSystem = default!;
[Dependency] private readonly ISharedPlayerManager _player = default!;
[Dependency] private readonly IConfigurationManager _configuration = default!;
public override void Initialize()
{
@@ -99,7 +102,7 @@ namespace Content.Server.Hands.Systems
if (finalPosition.EqualsApprox(initialPosition.Position, tolerance: 0.1f))
return;
var filter = Filter.Pvs(item);
var filter = Filter.Pvs(item, entityManager: EntityManager, playerManager: _player, cfgManager: _configuration);
if (exclude != null)
filter = filter.RemoveWhereAttachedEntity(entity => entity == exclude);

View File

@@ -21,6 +21,7 @@ using Content.Server.ServerUpdates;
using Content.Server.Voting.Managers;
using Content.Shared.Administration;
using Content.Shared.Administration.Logs;
using Content.Shared.Administration.Managers;
using Content.Shared.Kitchen;
using Content.Shared.Module;
@@ -41,6 +42,7 @@ namespace Content.Server.IoC
IoCManager.Register<ServerUpdateManager>();
IoCManager.Register<IObjectivesManager, ObjectivesManager>();
IoCManager.Register<IAdminManager, AdminManager>();
IoCManager.Register<ISharedAdminManager, AdminManager>();
IoCManager.Register<EuiManager, EuiManager>();
IoCManager.Register<IVoteManager, VoteManager>();
IoCManager.Register<IPlayerLocator, PlayerLocator>();

View File

@@ -123,13 +123,13 @@ public sealed class SharpSystem : EntitySystem
private void OnGetInteractionVerbs(EntityUid uid, ButcherableComponent component, GetVerbsEvent<InteractionVerb> args)
{
if (component.Type != ButcheringType.Knife || args.Hands == null)
if (component.Type != ButcheringType.Knife || args.Hands == null || !args.CanAccess || !args.CanInteract)
return;
bool disabled = false;
string? message = null;
if (args.Using is null || !HasComp<SharpComponent>(args.Using))
if (!HasComp<SharpComponent>(args.Using))
{
disabled = true;
message = Loc.GetString("butcherable-need-knife",

View File

@@ -33,6 +33,9 @@ using Content.Shared.DoAfter;
using Content.Shared.Implants.Components;
using Content.Shared.Lock;
using Content.Shared.Movement.Events;
using Content.Server.Ghost.Components;
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
namespace Content.Server.Storage.EntitySystems
{
@@ -41,6 +44,7 @@ namespace Content.Server.Storage.EntitySystems
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IAdminManager _admin = default!;
[Dependency] private readonly ContainerSystem _containerSystem = default!;
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly EntityLookupSystem _entityLookupSystem = default!;
@@ -94,8 +98,17 @@ namespace Content.Server.Storage.EntitySystems
private void AddOpenUiVerb(EntityUid uid, ServerStorageComponent component, GetVerbsEvent<ActivationVerb> args)
{
bool silent = false;
if (!args.CanAccess || !args.CanInteract || TryComp<LockComponent>(uid, out var lockComponent) && lockComponent.Locked)
return;
{
// we allow admins to open the storage anyways
if (!_admin.HasAdminFlag(args.User, AdminFlags.Admin))
return;
silent = true;
}
silent |= HasComp<GhostComponent>(args.User);
// Get the session for the user
if (!TryComp<ActorComponent>(args.User, out var actor))
@@ -106,7 +119,7 @@ namespace Content.Server.Storage.EntitySystems
ActivationVerb verb = new()
{
Act = () => OpenStorageUI(uid, args.User, component)
Act = () => OpenStorageUI(uid, args.User, component, silent)
};
if (uiOpen)
{
@@ -583,13 +596,13 @@ namespace Content.Server.Storage.EntitySystems
/// Opens the storage UI for an entity
/// </summary>
/// <param name="entity">The entity to open the UI for</param>
public void OpenStorageUI(EntityUid uid, EntityUid entity, ServerStorageComponent? storageComp = null)
public void OpenStorageUI(EntityUid uid, EntityUid entity, ServerStorageComponent? storageComp = null, bool silent = false)
{
if (!Resolve(uid, ref storageComp) || !TryComp(entity, out ActorComponent? player))
return;
if (storageComp.StorageOpenSound is not null)
_audio.Play(storageComp.StorageOpenSound, Filter.Pvs(uid, entityManager: EntityManager), uid, true, storageComp.StorageOpenSound.Params);
if (!silent)
_audio.PlayPvs(storageComp.StorageOpenSound, uid);
Logger.DebugS(storageComp.LoggerName, $"Storage (UID {uid}) \"used\" by player session (UID {player.PlayerSession.AttachedEntity}).");

View File

@@ -163,9 +163,10 @@ namespace Content.Server.Strip
if (args.Target == args.User)
return;
if (!TryComp<ActorComponent>(args.User, out var actor))
if (!HasComp<ActorComponent>(args.User))
return;
args.Handled = true;
StartOpeningStripper(args.User, component);
}
@@ -214,12 +215,9 @@ namespace Content.Server.Strip
return;
}
var userEv = new BeforeStripEvent(slotDef.StripTime);
RaiseLocalEvent(user, userEv);
var ev = new BeforeGettingStrippedEvent(userEv.Time, userEv.Stealth);
RaiseLocalEvent(component.Owner, ev);
var (time, stealth) = GetStripTimeModifiers(user, component.Owner, slotDef.StripTime);
var doAfterArgs = new DoAfterEventArgs(user, ev.Time, CancellationToken.None, component.Owner)
var doAfterArgs = new DoAfterEventArgs(user, time, CancellationToken.None, component.Owner)
{
ExtraCheck = Check,
BreakOnStun = true,
@@ -229,7 +227,7 @@ namespace Content.Server.Strip
NeedHand = true,
};
if (!ev.Stealth && Check() && userHands.ActiveHandEntity != null)
if (!stealth && Check() && userHands.ActiveHandEntity != null)
{
var message = Loc.GetString("strippable-component-alert-owner-insert",
("user", Identity.Entity(user, EntityManager)), ("item", userHands.ActiveHandEntity));
@@ -246,8 +244,6 @@ namespace Content.Server.Strip
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has placed the item {ToPrettyString(held):item} in {ToPrettyString(component.Owner):target}'s {slot} slot");
}
}
/// <summary>
@@ -282,12 +278,9 @@ namespace Content.Server.Strip
return true;
}
var userEv = new BeforeStripEvent(component.HandStripDelay);
RaiseLocalEvent(user, userEv);
var ev = new BeforeGettingStrippedEvent(userEv.Time, userEv.Stealth);
RaiseLocalEvent(component.Owner, ev);
var (time, stealth) = GetStripTimeModifiers(user, component.Owner, component.HandStripDelay);
var doAfterArgs = new DoAfterEventArgs(user, ev.Time, CancellationToken.None, component.Owner)
var doAfterArgs = new DoAfterEventArgs(user, time, CancellationToken.None, component.Owner)
{
ExtraCheck = Check,
BreakOnStun = true,
@@ -297,13 +290,16 @@ namespace Content.Server.Strip
NeedHand = true,
};
if (Check() && userHands.Hands.TryGetValue(handName, out var handSlot))
if (!stealth
&& Check()
&& userHands.Hands.TryGetValue(handName, out var handSlot)
&& handSlot.HeldEntity != null)
{
if (handSlot.HeldEntity != null)
{
_popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner-insert", ("user", Identity.Entity(user, EntityManager)), ("item", handSlot.HeldEntity)), component.Owner,
component.Owner, PopupType.Large);
}
_popupSystem.PopupEntity(
Loc.GetString("strippable-component-alert-owner-insert",
("user", Identity.Entity(user, EntityManager)),
("item", handSlot.HeldEntity)),
component.Owner, component.Owner, PopupType.Large);
}
var result = await _doAfterSystem.WaitDoAfter(doAfterArgs);
@@ -313,7 +309,7 @@ namespace Content.Server.Strip
return;
_handsSystem.TryDrop(user, checkActionBlocker: false, handsComp: userHands);
_handsSystem.TryPickup(component.Owner, held, handName, checkActionBlocker: false, animateUser: true, handsComp: hands);
_handsSystem.TryPickup(component.Owner, held, handName, checkActionBlocker: false, animateUser: true, animate: !stealth, handsComp: hands);
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has placed the item {ToPrettyString(held):item} in {ToPrettyString(component.Owner):target}'s hands");
// hand update will trigger strippable update
}
@@ -349,12 +345,9 @@ namespace Content.Server.Strip
return;
}
var userEv = new BeforeStripEvent(slotDef.StripTime);
RaiseLocalEvent(user, userEv);
var ev = new BeforeGettingStrippedEvent(userEv.Time, userEv.Stealth);
RaiseLocalEvent(component.Owner, ev);
var (time, stealth) = GetStripTimeModifiers(user, component.Owner, slotDef.StripTime);
var doAfterArgs = new DoAfterEventArgs(user, ev.Time, CancellationToken.None, component.Owner)
var doAfterArgs = new DoAfterEventArgs(user, time, CancellationToken.None, component.Owner)
{
ExtraCheck = Check,
BreakOnStun = true,
@@ -363,7 +356,7 @@ namespace Content.Server.Strip
BreakOnUserMove = true,
};
if (!ev.Stealth && Check())
if (!stealth && Check())
{
if (slotDef.StripHidden)
{
@@ -385,7 +378,7 @@ namespace Content.Server.Strip
// Raise a dropped event, so that things like gas tank internals properly deactivate when stripping
RaiseLocalEvent(item.Value, new DroppedEvent(user), true);
_handsSystem.PickupOrDrop(user, item.Value);
_handsSystem.PickupOrDrop(user, item.Value, animate: !stealth);
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has stripped the item {ToPrettyString(item.Value):item} from {ToPrettyString(component.Owner):target}");
}
}
@@ -418,12 +411,9 @@ namespace Content.Server.Strip
return true;
}
var userEv = new BeforeStripEvent(component.HandStripDelay);
RaiseLocalEvent(user, userEv);
var ev = new BeforeGettingStrippedEvent(userEv.Time, userEv.Stealth);
RaiseLocalEvent(component.Owner, ev);
var (time, stealth) = GetStripTimeModifiers(user, component.Owner, component.HandStripDelay);
var doAfterArgs = new DoAfterEventArgs(user, ev.Time, CancellationToken.None, component.Owner)
var doAfterArgs = new DoAfterEventArgs(user, time, CancellationToken.None, component.Owner)
{
ExtraCheck = Check,
BreakOnStun = true,
@@ -432,12 +422,16 @@ namespace Content.Server.Strip
BreakOnUserMove = true,
};
if (Check() && hands.Hands.TryGetValue(handName, out var handSlot))
if (!stealth
&& Check()
&& hands.Hands.TryGetValue(handName, out var handSlot)
&& handSlot.HeldEntity != null)
{
if (handSlot.HeldEntity != null)
{
_popupSystem.PopupEntity(Loc.GetString("strippable-component-alert-owner", ("user", Identity.Entity(user, EntityManager)), ("item", handSlot.HeldEntity)), component.Owner, component.Owner);
}
_popupSystem.PopupEntity(
Loc.GetString("strippable-component-alert-owner",
("user", Identity.Entity(user, EntityManager)),
("item", handSlot.HeldEntity)),
component.Owner, component.Owner);
}
var result = await _doAfterSystem.WaitDoAfter(doAfterArgs);
@@ -447,7 +441,7 @@ namespace Content.Server.Strip
return;
_handsSystem.TryDrop(component.Owner, hand, checkActionBlocker: false, handsComp: hands);
_handsSystem.PickupOrDrop(user, held, handsComp: userHands);
_handsSystem.PickupOrDrop(user, held, handsComp: userHands, animate: !stealth);
// hand update will trigger strippable update
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has stripped the item {ToPrettyString(held):item} from {ToPrettyString(component.Owner):target}");
}