diff --git a/Content.Shared/Tag/TagSystem.cs b/Content.Shared/Tag/TagSystem.cs index 62197dc319ace6..c2ea28d4c3cbc3 100644 --- a/Content.Shared/Tag/TagSystem.cs +++ b/Content.Shared/Tag/TagSystem.cs @@ -234,6 +234,21 @@ public bool HasAllTags(EntityUid entity, IEnumerable ids) /// /// The entity to check. /// The tags to check for. + /// true if they all exist, false otherwise. + /// + /// Thrown if one of the ids represents an unregistered . + /// + public bool HasAllTags(EntityUid entity, List> ids) + { + return TryComp(entity, out var component) && + HasAllTags(component, ids); + } + + /// + /// Checks if any of the given tags have been added to an entity. + /// + /// The entity to check. + /// The tags to check for. /// true if any of them exist, false otherwise. /// /// Thrown if one of the ids represents an unregistered . @@ -245,7 +260,7 @@ public bool HasAnyTag(EntityUid entity, params string[] ids) } /// - /// Checks if all of the given tags have been added to an entity. + /// Checks if any of the given tags have been added to an entity. /// /// The entity to check. /// The tag to check for. @@ -256,7 +271,7 @@ public bool HasAnyTag(EntityUid entity, params string[] ids) public bool HasAnyTag(EntityUid entity, string id) => HasTag(entity, id); /// - /// Checks if all of the given tags have been added to an entity. + /// Checks if any of the given tags have been added to an entity. /// /// The entity to check. /// The tags to check for. @@ -271,7 +286,22 @@ public bool HasAnyTag(EntityUid entity, List ids) } /// - /// Checks if all of the given tags have been added to an entity. + /// Checks if any of the given tags have been added to an entity. + /// + /// The entity to check. + /// The tags to check for. + /// true if any of them exist, false otherwise. + /// + /// Thrown if one of the ids represents an unregistered . + /// + public bool HasAnyTag(EntityUid entity, List> ids) + { + return TryComp(entity, out var component) && + HasAnyTag(component, ids); + } + + /// + /// Checks if any of the given tags have been added to an entity. /// /// The entity to check. /// The tags to check for. @@ -478,6 +508,26 @@ public bool HasAllTags(TagComponent component, IEnumerable ids) return true; } + /// + /// Checks if all of the given tags have been added. + /// + /// The tags to check for. + /// true if they all exist, false otherwise. + /// + /// Thrown if one of the ids represents an unregistered . + /// + public bool HasAllTags(TagComponent component, List> ids) + { + var stringIds = new List(); + foreach (var tag in ids) + { + stringIds.Add(tag.Id); + } + + return HasAllTags(component, stringIds); + } + + /// /// Checks if any of the given tags have been added. /// @@ -548,6 +598,25 @@ public bool HasAnyTag(TagComponent component, IEnumerable ids) return false; } + /// + /// Checks if any of the given tags have been added. + /// + /// The tags to check for. + /// true if any of them exist, false otherwise. + /// + /// Thrown if one of the ids represents an unregistered . + /// + public bool HasAnyTag(TagComponent comp, List> ids) + { + var stringIds = new List(); + foreach (var tag in ids) + { + stringIds.Add(tag.Id); + } + + return HasAnyTag(comp, stringIds); + } + /// /// Tries to remove a tag if it exists. /// diff --git a/Content.Shared/Whitelist/EntityWhitelist.cs b/Content.Shared/Whitelist/EntityWhitelist.cs index b412a09b989acc..7fa6ce7f824f88 100644 --- a/Content.Shared/Whitelist/EntityWhitelist.cs +++ b/Content.Shared/Whitelist/EntityWhitelist.cs @@ -1,103 +1,121 @@ +using Content.Shared.Item; using Content.Shared.Tag; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; -namespace Content.Shared.Whitelist +namespace Content.Shared.Whitelist; + +/// +/// Used to determine whether an entity fits a certain whitelist. +/// Does not whitelist by prototypes, since that is undesirable; you're better off just adding a tag to all +/// entity prototypes that need to be whitelisted, and checking for that. +/// +/// +/// whitelist: +/// tags: +/// - Cigarette +/// - FirelockElectronics +/// components: +/// - Buckle +/// - AsteroidRock +/// sizes: +/// - Tiny +/// - Large +/// +[DataDefinition] +[Serializable, NetSerializable] +public sealed partial class EntityWhitelist { /// - /// Used to determine whether an entity fits a certain whitelist. - /// Does not whitelist by prototypes, since that is undesirable; you're better off just adding a tag to all - /// entity prototypes that need to be whitelisted, and checking for that. + /// Component names that are allowed in the whitelist. /// - /// - /// whitelist: - /// tags: - /// - Cigarette - /// - FirelockElectronics - /// components: - /// - Buckle - /// - AsteroidRock - /// - [DataDefinition] - [Serializable, NetSerializable] - public sealed partial class EntityWhitelist - { - /// - /// Component names that are allowed in the whitelist. - /// - [DataField("components")] public string[]? Components = null; - // TODO yaml validation + [DataField] public string[]? Components; + // TODO yaml validation - [NonSerialized] - private List? _registrations = null; + /// + /// Item sizes that are allowed in the whitelist. + /// + [DataField] + public List>? Sizes; - /// - /// Tags that are allowed in the whitelist. - /// - [DataField("tags", customTypeSerializer:typeof(PrototypeIdListSerializer))] - public List? Tags = null; + [NonSerialized] + private List? _registrations; - /// - /// 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; + /// + /// Tags that are allowed in the whitelist. + /// + [DataField] + public List>? Tags; - public void UpdateRegistrations() - { - if (Components == null) return; + /// + /// 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. + /// The "Sizes" criteria will ignores this, since an item can only have one size. + /// + [DataField] + public bool RequireAll; - var compfact = IoCManager.Resolve(); - _registrations = new List(); - foreach (var name in Components) + public void UpdateRegistrations() + { + + if (Components == null) + return; + + var compFact = IoCManager.Resolve(); + _registrations = new List(); + foreach (var name in Components) + { + var availability = compFact.GetComponentAvailability(name); + if (compFact.TryGetRegistration(name, out var registration) + && availability == ComponentAvailability.Available) { - var availability = compfact.GetComponentAvailability(name); - if (compfact.TryGetRegistration(name, out var registration) - && availability == ComponentAvailability.Available) - { - _registrations.Add(registration); - } - else if (availability == ComponentAvailability.Unknown) - { - Logger.Warning($"Unknown component name {name} passed to EntityWhitelist!"); - } + _registrations.Add(registration); + } + else if (availability == ComponentAvailability.Unknown) + { + Logger.Warning($"Unknown component name {name} passed to EntityWhitelist!"); } } + } - /// - /// Returns whether a given entity fits the whitelist. - /// - public bool IsValid(EntityUid uid, IEntityManager? entityManager = null) - { - if (Components != null && _registrations == null) - UpdateRegistrations(); + /// + /// Returns whether a given entity fits the whitelist. + /// + public bool IsValid(EntityUid uid, IEntityManager? entityManager = null) + { + if (Components != null && _registrations == null) + UpdateRegistrations(); - IoCManager.Resolve(ref entityManager); - if (_registrations != null) + IoCManager.Resolve(ref entityManager); + if (_registrations != null) + { + foreach (var reg in _registrations) { - foreach (var reg in _registrations) + if (entityManager.HasComponent(uid, reg.Type)) { - if (entityManager.HasComponent(uid, reg.Type)) - { - if (!RequireAll) - return true; - } - else if (RequireAll) - return false; + if (!RequireAll) + return true; } + else if (RequireAll) + return false; } + } - if (Tags != null && entityManager.TryGetComponent(uid, out TagComponent? tags)) - { - var tagSystem = entityManager.System(); - return RequireAll ? tagSystem.HasAllTags(tags, Tags) : tagSystem.HasAnyTag(tags, Tags); - } - - if (RequireAll) + if (Sizes != null && entityManager.TryGetComponent(uid, out ItemComponent? itemComp)) + { + if (Sizes.Contains(itemComp.Size)) return true; + } - return false; + if (Tags != null && entityManager.TryGetComponent(uid, out TagComponent? tags)) + { + var tagSystem = entityManager.System(); + return RequireAll ? tagSystem.HasAllTags(tags, Tags) : tagSystem.HasAnyTag(tags, Tags); } + + if (RequireAll) + return true; + + return false; } }