Makes AccessReaderComponent support containers (#17927)

This commit is contained in:
c4llv07e
2023-07-26 05:34:08 +00:00
committed by GitHub
parent 13da6841b1
commit edb33cacc4
2 changed files with 49 additions and 5 deletions

View File

@@ -37,6 +37,14 @@ public sealed class AccessReaderComponent : Component
/// </summary> /// </summary>
[DataField("accessKeys")] [DataField("accessKeys")]
public HashSet<StationRecordKey> AccessKeys = new(); public HashSet<StationRecordKey> AccessKeys = new();
/// <summary>
/// The name of the container in which additional
/// AccessReaderComponents may be found.
/// </summary>
[DataField("containerAccessProvider")]
public string? ContainerAccessProvider = null;
} }
[Serializable, NetSerializable] [Serializable, NetSerializable]

View File

@@ -6,6 +6,7 @@ using Content.Shared.Emag.Systems;
using Content.Shared.PDA; using Content.Shared.PDA;
using Content.Shared.Access.Components; using Content.Shared.Access.Components;
using Content.Shared.DeviceLinking.Events; using Content.Shared.DeviceLinking.Events;
using Robust.Shared.Containers;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.StationRecords; using Content.Shared.StationRecords;
@@ -17,6 +18,7 @@ public sealed class AccessReaderSystem : EntitySystem
{ {
[Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -60,20 +62,54 @@ public sealed class AccessReaderSystem : EntitySystem
Dirty(reader); Dirty(reader);
} }
/// <summary>
/// Finds all AccessReaderComponents in the container of the
/// required entity.
/// </summary>
/// <param name="target">The entity to search for a container</param>
private bool FindAccessReadersInContainer(EntityUid target, AccessReaderComponent accessReader, out List<AccessReaderComponent> result)
{
result = new();
if (accessReader.ContainerAccessProvider == null)
return false;
if (!_containerSystem.TryGetContainer(target, accessReader.ContainerAccessProvider, out var container))
return false;
foreach (var entity in container.ContainedEntities)
{
if (TryComp<AccessReaderComponent>(entity, out var entityAccessReader))
result.Add(entityAccessReader);
}
return result.Any();
}
/// <summary> /// <summary>
/// Searches the source for access tags /// Searches the source for access tags
/// then compares it with the targets readers access list to see if it is allowed. /// then compares it with the all targets accesses to see if it is allowed.
/// </summary> /// </summary>
/// <param name="source">The entity that wants access.</param> /// <param name="source">The entity that wants access.</param>
/// <param name="target">The entity to search for an access reader</param> /// <param name="target">The entity to search for an access reader</param>
/// <param name="reader">Optional reader from the target entity</param> /// <param name="reader">Optional reader from the target entity</param>
public bool IsAllowed(EntityUid source, EntityUid target, AccessReaderComponent? reader = null) public bool IsAllowed(EntityUid source, EntityUid target, AccessReaderComponent? reader = null)
{ {
if (!Resolve(target, ref reader, false)) if (!Resolve(target, ref reader, false))
return true; return true;
return IsAllowed(source, reader);
}
if (FindAccessReadersInContainer(target, reader, out var accessReaderList))
{
foreach (var access in accessReaderList)
{
if (IsAllowed(source, access))
return true;
}
return false;
}
return IsAllowed(source, reader);
}
/// <summary> /// <summary>
/// Searches the given entity for access tags /// Searches the given entity for access tags
/// then compares it with the readers access list to see if it is allowed. /// then compares it with the readers access list to see if it is allowed.