From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Fri, 3 May 2024 00:10:15 +0000 (+1200) Subject: Add EntityWhitelistSystem (#27632) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=f348e6aa306a3542b1ed75b021c45228250aca3c;p=space-station-14.git Add EntityWhitelistSystem (#27632) * Add EntityWhitelistSystem * Sandbox fix * update test --- diff --git a/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs b/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs index 6b47ec4d8e..19b25816fa 100644 --- a/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs +++ b/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs @@ -64,7 +64,8 @@ namespace Content.IntegrationTests.Tests.Utility var testMap = await pair.CreateTestMap(); var mapCoordinates = testMap.MapCoords; - var sEntities = server.ResolveDependency(); + var sEntities = server.EntMan; + var sys = server.System(); await server.WaitAssertion(() => { @@ -80,22 +81,14 @@ namespace Content.IntegrationTests.Tests.Utility Components = new[] { $"{ValidComponent}" }, Tags = new() { "WhitelistTestValidTag" } }; - whitelistInst.UpdateRegistrations(); - Assert.That(whitelistInst, Is.Not.Null); Assert.Multiple(() => { - Assert.That(whitelistInst.Components, Is.Not.Null); - Assert.That(whitelistInst.Tags, Is.Not.Null); - }); - - Assert.Multiple(() => - { - Assert.That(whitelistInst.IsValid(validComponent), Is.True); - Assert.That(whitelistInst.IsValid(WhitelistTestValidTag), Is.True); + Assert.That(sys.IsValid(whitelistInst, validComponent), Is.True); + Assert.That(sys.IsValid(whitelistInst, WhitelistTestValidTag), Is.True); - Assert.That(whitelistInst.IsValid(invalidComponent), Is.False); - Assert.That(whitelistInst.IsValid(WhitelistTestInvalidTag), Is.False); + Assert.That(sys.IsValid(whitelistInst, invalidComponent), Is.False); + Assert.That(sys.IsValid(whitelistInst, WhitelistTestInvalidTag), Is.False); }); // Test from serialized @@ -111,11 +104,11 @@ namespace Content.IntegrationTests.Tests.Utility Assert.Multiple(() => { - Assert.That(whitelistSer.IsValid(validComponent), Is.True); - Assert.That(whitelistSer.IsValid(WhitelistTestValidTag), Is.True); + Assert.That(sys.IsValid(whitelistSer, validComponent), Is.True); + Assert.That(sys.IsValid(whitelistSer, WhitelistTestValidTag), Is.True); - Assert.That(whitelistSer.IsValid(invalidComponent), Is.False); - Assert.That(whitelistSer.IsValid(WhitelistTestInvalidTag), Is.False); + Assert.That(sys.IsValid(whitelistSer, invalidComponent), Is.False); + Assert.That(sys.IsValid(whitelistSer, WhitelistTestInvalidTag), Is.False); }); }); await pair.CleanReturnAsync(); diff --git a/Content.Shared/Tag/TagSystem.cs b/Content.Shared/Tag/TagSystem.cs index fdb7de1f75..7bcb887a41 100644 --- a/Content.Shared/Tag/TagSystem.cs +++ b/Content.Shared/Tag/TagSystem.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Linq; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; @@ -185,6 +186,7 @@ public sealed class TagSystem : EntitySystem /// /// Checks if a tag has been added to an entity. /// + [Obsolete] public bool HasTag(EntityUid entity, string id, EntityQuery tagQuery) { return tagQuery.TryGetComponent(entity, out var component) && @@ -243,7 +245,7 @@ public sealed class TagSystem : EntitySystem /// public bool HasAllTags(EntityUid entity, List> ids) { - return TryComp(entity, out var component) && + return _tagQuery.TryComp(entity, out var component) && HasAllTags(component, ids); } @@ -521,16 +523,18 @@ public sealed class TagSystem : EntitySystem /// public bool HasAllTags(TagComponent component, List> ids) { - var stringIds = new List(); - foreach (var tag in ids) + foreach (var id in ids) { - stringIds.Add(tag.Id); + AssertValidTag(id); + + if (!component.Tags.Contains(id)) + return false; + } - return HasAllTags(component, stringIds); + return true; } - /// /// Checks if any of the given tags have been added. /// @@ -552,7 +556,6 @@ public sealed class TagSystem : EntitySystem return false; } - /// /// Checks if any of the given tags have been added. /// @@ -619,13 +622,15 @@ public sealed class TagSystem : EntitySystem /// public bool HasAnyTag(TagComponent comp, List> ids) { - var stringIds = new List(); - foreach (var tag in ids) + foreach (var id in ids) { - stringIds.Add(tag.Id); + AssertValidTag(id); + + if (comp.Tags.Contains(id)) + return true; } - return HasAnyTag(comp, stringIds); + return false; } /// diff --git a/Content.Shared/Whitelist/EntityWhitelist.cs b/Content.Shared/Whitelist/EntityWhitelist.cs index 7fa6ce7f82..895759be95 100644 --- a/Content.Shared/Whitelist/EntityWhitelist.cs +++ b/Content.Shared/Whitelist/EntityWhitelist.cs @@ -38,8 +38,8 @@ public sealed partial class EntityWhitelist [DataField] public List>? Sizes; - [NonSerialized] - private List? _registrations; + [NonSerialized, Access(typeof(EntityWhitelistSystem))] + public List? Registrations; /// /// Tags that are allowed in the whitelist. @@ -55,67 +55,13 @@ public sealed partial class EntityWhitelist [DataField] public bool RequireAll; - public void UpdateRegistrations() + [Obsolete("Use WhitelistSystem")] + public bool IsValid(EntityUid uid, IEntityManager? man = null) { + var sys = man?.System() ?? + IoCManager.Resolve().GetEntitySystem(); - if (Components == null) - return; + return sys.IsValid(this, uid); - 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) - { - _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(); - - IoCManager.Resolve(ref entityManager); - if (_registrations != null) - { - foreach (var reg in _registrations) - { - if (entityManager.HasComponent(uid, reg.Type)) - { - if (!RequireAll) - return true; - } - else if (RequireAll) - return false; - } - } - - if (Sizes != null && entityManager.TryGetComponent(uid, out ItemComponent? itemComp)) - { - if (Sizes.Contains(itemComp.Size)) - return true; - } - - 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; } } diff --git a/Content.Shared/Whitelist/EntityWhitelistSystem.cs b/Content.Shared/Whitelist/EntityWhitelistSystem.cs new file mode 100644 index 0000000000..d73646b7e9 --- /dev/null +++ b/Content.Shared/Whitelist/EntityWhitelistSystem.cs @@ -0,0 +1,84 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Item; +using Content.Shared.Tag; + +namespace Content.Shared.Whitelist; + +public sealed class EntityWhitelistSystem : EntitySystem +{ + [Dependency] private readonly IComponentFactory _factory = default!; + [Dependency] private readonly TagSystem _tag = default!; + + private EntityQuery _itemQuery; + + public override void Initialize() + { + base.Initialize(); + _itemQuery = GetEntityQuery(); + } + + /// + public bool IsValid(EntityWhitelist list, [NotNullWhen(true)] EntityUid? uid) + { + return uid != null && IsValid(list, uid.Value); + } + + /// + /// Checks whether a given entity satisfies a whitelist. + /// + public bool IsValid(EntityWhitelist list, EntityUid uid) + { + if (list.Components != null) + EnsureRegistrations(list); + + if (list.Registrations != null) + { + foreach (var reg in list.Registrations) + { + if (HasComp(uid, reg.Type)) + { + if (!list.RequireAll) + return true; + } + else if (list.RequireAll) + return false; + } + } + + if (list.Sizes != null && _itemQuery.TryComp(uid, out var itemComp)) + { + if (list.Sizes.Contains(itemComp.Size)) + return true; + } + + if (list.Tags != null) + { + return list.RequireAll + ? _tag.HasAllTags(uid, list.Tags) + : _tag.HasAnyTag(uid, list.Tags); + } + + return list.RequireAll; + } + + private void EnsureRegistrations(EntityWhitelist list) + { + if (list.Components == null) + return; + + list.Registrations = new List(); + foreach (var name in list.Components) + { + var availability = _factory.GetComponentAvailability(name); + if (_factory.TryGetRegistration(name, out var registration) + && availability == ComponentAvailability.Available) + { + list.Registrations.Add(registration); + } + else if (availability == ComponentAvailability.Unknown) + { + Log.Warning($"Unknown component name {name} passed to EntityWhitelist!"); + } + } + } +}