mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-09-29 23:57:29 +00:00
Size-based entity whitelist (#26798)
* Size based whitelisting * namespace and misc refactor * modern datafields, what will they think of next Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> * the future is now Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> * Update TagSystem to work with ProtoId lists * I guess someone might run into these too, one day * copypaste moment * update to sawmill * Okay, but what if it just worked --------- Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
This commit is contained in:
@@ -234,6 +234,21 @@ public sealed class TagSystem : EntitySystem
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if they all exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAllTags(EntityUid entity, List<ProtoId<TagPrototype>> ids)
|
||||
{
|
||||
return TryComp<TagComponent>(entity, out var component) &&
|
||||
HasAllTags(component, ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the given tags have been added to an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if any of them exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
@@ -245,7 +260,7 @@ public sealed class TagSystem : EntitySystem
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="id">The tag to check for.</param>
|
||||
@@ -256,7 +271,7 @@ public sealed class TagSystem : EntitySystem
|
||||
public bool HasAnyTag(EntityUid entity, string id) => HasTag(entity, id);
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
@@ -271,7 +286,22 @@ public sealed class TagSystem : EntitySystem
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if any of them exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAnyTag(EntityUid entity, List<ProtoId<TagPrototype>> ids)
|
||||
{
|
||||
return TryComp<TagComponent>(entity, out var component) &&
|
||||
HasAnyTag(component, ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the given tags have been added to an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to check.</param>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
@@ -478,6 +508,26 @@ public sealed class TagSystem : EntitySystem
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if all of the given tags have been added.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if they all exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAllTags(TagComponent component, List<ProtoId<TagPrototype>> ids)
|
||||
{
|
||||
var stringIds = new List<string>();
|
||||
foreach (var tag in ids)
|
||||
{
|
||||
stringIds.Add(tag.Id);
|
||||
}
|
||||
|
||||
return HasAllTags(component, stringIds);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the given tags have been added.
|
||||
/// </summary>
|
||||
@@ -548,6 +598,25 @@ public sealed class TagSystem : EntitySystem
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the given tags have been added.
|
||||
/// </summary>
|
||||
/// <param name="ids">The tags to check for.</param>
|
||||
/// <returns>true if any of them exist, false otherwise.</returns>
|
||||
/// <exception cref="UnknownPrototypeException">
|
||||
/// Thrown if one of the ids represents an unregistered <see cref="TagPrototype"/>.
|
||||
/// </exception>
|
||||
public bool HasAnyTag(TagComponent comp, List<ProtoId<TagPrototype>> ids)
|
||||
{
|
||||
var stringIds = new List<string>();
|
||||
foreach (var tag in ids)
|
||||
{
|
||||
stringIds.Add(tag.Id);
|
||||
}
|
||||
|
||||
return HasAnyTag(comp, stringIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove a tag if it exists.
|
||||
/// </summary>
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <code>
|
||||
/// whitelist:
|
||||
/// tags:
|
||||
/// - Cigarette
|
||||
/// - FirelockElectronics
|
||||
/// components:
|
||||
/// - Buckle
|
||||
/// - AsteroidRock
|
||||
/// sizes:
|
||||
/// - Tiny
|
||||
/// - Large
|
||||
/// </code>
|
||||
[DataDefinition]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class EntityWhitelist
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <code>
|
||||
/// whitelist:
|
||||
/// tags:
|
||||
/// - Cigarette
|
||||
/// - FirelockElectronics
|
||||
/// components:
|
||||
/// - Buckle
|
||||
/// - AsteroidRock
|
||||
/// </code>
|
||||
[DataDefinition]
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class EntityWhitelist
|
||||
[DataField] public string[]? Components;
|
||||
// TODO yaml validation
|
||||
|
||||
/// <summary>
|
||||
/// Item sizes that are allowed in the whitelist.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<ProtoId<ItemSizePrototype>>? Sizes;
|
||||
|
||||
[NonSerialized]
|
||||
private List<ComponentRegistration>? _registrations;
|
||||
|
||||
/// <summary>
|
||||
/// Tags that are allowed in the whitelist.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<ProtoId<TagPrototype>>? Tags;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool RequireAll;
|
||||
|
||||
public void UpdateRegistrations()
|
||||
{
|
||||
/// <summary>
|
||||
/// Component names that are allowed in the whitelist.
|
||||
/// </summary>
|
||||
[DataField("components")] public string[]? Components = null;
|
||||
// TODO yaml validation
|
||||
|
||||
[NonSerialized]
|
||||
private List<ComponentRegistration>? _registrations = null;
|
||||
if (Components == null)
|
||||
return;
|
||||
|
||||
/// <summary>
|
||||
/// Tags that are allowed in the whitelist.
|
||||
/// </summary>
|
||||
[DataField("tags", customTypeSerializer:typeof(PrototypeIdListSerializer<TagPrototype>))]
|
||||
public List<string>? Tags = null;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[DataField("requireAll")]
|
||||
public bool RequireAll = false;
|
||||
|
||||
public void UpdateRegistrations()
|
||||
var compFact = IoCManager.Resolve<IComponentFactory>();
|
||||
_registrations = new List<ComponentRegistration>();
|
||||
foreach (var name in Components)
|
||||
{
|
||||
if (Components == null) return;
|
||||
|
||||
var compfact = IoCManager.Resolve<IComponentFactory>();
|
||||
_registrations = new List<ComponentRegistration>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a given entity fits the whitelist.
|
||||
/// </summary>
|
||||
public bool IsValid(EntityUid uid, IEntityManager? entityManager = null)
|
||||
{
|
||||
if (Components != null && _registrations == null)
|
||||
UpdateRegistrations();
|
||||
|
||||
IoCManager.Resolve(ref entityManager);
|
||||
if (_registrations != null)
|
||||
else if (availability == ComponentAvailability.Unknown)
|
||||
{
|
||||
foreach (var reg in _registrations)
|
||||
{
|
||||
if (entityManager.HasComponent(uid, reg.Type))
|
||||
{
|
||||
if (!RequireAll)
|
||||
return true;
|
||||
}
|
||||
else if (RequireAll)
|
||||
return false;
|
||||
}
|
||||
Logger.Warning($"Unknown component name {name} passed to EntityWhitelist!");
|
||||
}
|
||||
|
||||
if (Tags != null && entityManager.TryGetComponent(uid, out TagComponent? tags))
|
||||
{
|
||||
var tagSystem = entityManager.System<TagSystem>();
|
||||
return RequireAll ? tagSystem.HasAllTags(tags, Tags) : tagSystem.HasAnyTag(tags, Tags);
|
||||
}
|
||||
|
||||
if (RequireAll)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a given entity fits the whitelist.
|
||||
/// </summary>
|
||||
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<TagSystem>();
|
||||
return RequireAll ? tagSystem.HasAllTags(tags, Tags) : tagSystem.HasAnyTag(tags, Tags);
|
||||
}
|
||||
|
||||
if (RequireAll)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user