diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 1904ff9b18..dbe6531c1c 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -155,19 +155,11 @@ namespace Content.Client.Actions act.CopyFrom(serverAct); serverActions.Remove(serverAct); - - if (act is EntityTargetAction entAct) - { - entAct.Whitelist?.UpdateRegistrations(); - } } // Anything that remains is a new action foreach (var newAct in serverActions) { - if (newAct is EntityTargetAction entAct) - entAct.Whitelist?.UpdateRegistrations(); - // We create a new action, not just sorting a reference to the state's action. component.Actions.Add((ActionType) newAct.Clone()); } diff --git a/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs b/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs index cf0fd58f13..f774caab9a 100644 --- a/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs +++ b/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs @@ -81,8 +81,8 @@ namespace Content.IntegrationTests.Tests.Utility // Test instantiated on its own var whitelistInst = new EntityWhitelist { - Components = new[] {$"{ValidComponent}"}, - Tags = new[] {"ValidTag"} + Components = new[] { $"{ValidComponent}"}, + Tags = new() {"ValidTag"} }; whitelistInst.UpdateRegistrations(); Assert.That(whitelistInst, Is.Not.Null); diff --git a/Content.Server/Storage/EntitySystems/ItemMapperSystem.cs b/Content.Server/Storage/EntitySystems/ItemMapperSystem.cs index 088870719c..46d17fca1b 100644 --- a/Content.Server/Storage/EntitySystems/ItemMapperSystem.cs +++ b/Content.Server/Storage/EntitySystems/ItemMapperSystem.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Content.Server.Storage.Components; using Content.Shared.Storage.Components; using Content.Shared.Storage.EntitySystems; @@ -24,7 +24,7 @@ namespace Content.Server.Storage.EntitySystems { foreach (var entity in containedLayers) { - if (mapLayerData.Whitelist.IsValid(entity)) + if (mapLayerData.ServerWhitelist.IsValid(entity)) { list.Add(mapLayerData.Layer); break; diff --git a/Content.Shared/Storage/Components/SharedMapLayerData.cs b/Content.Shared/Storage/Components/SharedMapLayerData.cs index 7ce1be7541..048e0b02ce 100644 --- a/Content.Shared/Storage/Components/SharedMapLayerData.cs +++ b/Content.Shared/Storage/Components/SharedMapLayerData.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Content.Shared.Whitelist; using Robust.Shared.Serialization; @@ -19,8 +19,8 @@ namespace Content.Shared.Storage.Components { public string Layer = string.Empty; - [DataField("whitelist", required: true)] - public EntityWhitelist Whitelist { get; set; } = new(); + [DataField("whitelist", required: true, serverOnly: true)] + public EntityWhitelist ServerWhitelist { get; set; } = new(); } [Serializable, NetSerializable] diff --git a/Content.Shared/Whitelist/EntityWhitelist.cs b/Content.Shared/Whitelist/EntityWhitelist.cs index e3ee4adcc8..3ac08679c7 100644 --- a/Content.Shared/Whitelist/EntityWhitelist.cs +++ b/Content.Shared/Whitelist/EntityWhitelist.cs @@ -1,11 +1,5 @@ -using System.Collections.Generic; -using Content.Shared.Tag; -using Content.Shared.Wires; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Log; +using Content.Shared.Tag; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared.Whitelist @@ -26,7 +20,7 @@ namespace Content.Shared.Whitelist /// [DataDefinition] [Serializable, NetSerializable] - public sealed class EntityWhitelist : ISerializationHooks + public sealed class EntityWhitelist { /// /// Component names that are allowed in the whitelist. @@ -39,13 +33,15 @@ namespace Content.Shared.Whitelist /// /// Tags that are allowed in the whitelist. /// - [DataField("tags")] - public string[]? Tags = null; + [DataField("tags", customTypeSerializer:typeof(PrototypeIdListSerializer))] + public List? Tags = null; - void ISerializationHooks.AfterDeserialization() - { - UpdateRegistrations(); - } + /// + /// If false, an entity only requires one of these components or tags to pass the whitelist. If true, an + /// entity requires to have ALL of these components and tags to pass. + /// + [DataField("requireAll")] + public bool RequireAll = false; public void UpdateRegistrations() { @@ -73,23 +69,30 @@ namespace Content.Shared.Whitelist /// public bool IsValid(EntityUid uid, IEntityManager? entityManager = null) { + if (Components != null && _registrations == null) + UpdateRegistrations(); + entityManager ??= IoCManager.Resolve(); - var tagSystem = EntitySystem.Get(); - - if (Tags != null && entityManager.TryGetComponent(uid, out TagComponent? tags)) - { - if (tagSystem.HasAnyTag(tags, Tags)) - return true; - } - if (_registrations != null) { foreach (var reg in _registrations) { if (entityManager.HasComponent(uid, reg.Type)) - return true; + { + if (!RequireAll) + return true; + } + else if (RequireAll) + return false; } } + + if (Tags != null && entityManager.TryGetComponent(uid, out TagComponent? tags)) + { + var tagSystem = EntitySystem.Get(); + return RequireAll ? tagSystem.HasAllTags(tags, Tags) : tagSystem.HasAnyTag(tags, Tags); + } + return false; } }