]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fingerprint Reader System (#35600)
authorScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Sat, 1 Mar 2025 18:41:37 +0000 (19:41 +0100)
committerGitHub <noreply@github.com>
Sat, 1 Mar 2025 18:41:37 +0000 (10:41 -0800)
* init

* public api

* stuff

* weh

Content.Shared/FingerprintReader/FingerprintReaderComponent.cs [new file with mode: 0644]
Content.Shared/FingerprintReader/FingerprintReaderSystem.cs [new file with mode: 0644]
Resources/Locale/en-US/fingerprint-reader/fingerprint-reader.ftl [new file with mode: 0644]

diff --git a/Content.Shared/FingerprintReader/FingerprintReaderComponent.cs b/Content.Shared/FingerprintReader/FingerprintReaderComponent.cs
new file mode 100644 (file)
index 0000000..166551c
--- /dev/null
@@ -0,0 +1,35 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.FingerprintReader;
+
+/// <summary>
+/// Component for checking if a user's fingerprint matches allowed fingerprints
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(FingerprintReaderSystem))]
+public sealed partial class FingerprintReaderComponent : Component
+{
+    /// <summary>
+    /// The fingerprints that are allowed to access this entity.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public HashSet<string> AllowedFingerprints = new();
+
+    /// <summary>
+    /// Whether to ignore gloves when checking fingerprints.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public bool IgnoreGloves;
+
+    /// <summary>
+    /// The popup to show when access is denied due to fingerprint mismatch.
+    /// </summary>
+    [DataField]
+    public LocId? FailPopup;
+
+    /// <summary>
+    /// The popup to show when access is denied due to wearing gloves.
+    /// </summary>
+    [DataField]
+    public LocId? FailGlovesPopup;
+}
diff --git a/Content.Shared/FingerprintReader/FingerprintReaderSystem.cs b/Content.Shared/FingerprintReader/FingerprintReaderSystem.cs
new file mode 100644 (file)
index 0000000..f3944be
--- /dev/null
@@ -0,0 +1,100 @@
+using System.Diagnostics.CodeAnalysis;
+using Content.Shared.Forensics.Components;
+using Content.Shared.Inventory;
+using Content.Shared.Popups;
+using JetBrains.Annotations;
+
+namespace Content.Shared.FingerprintReader;
+
+// TODO: This has a lot of overlap with the AccessReaderSystem, maybe merge them in the future?
+public sealed class FingerprintReaderSystem : EntitySystem
+{
+    [Dependency] private readonly InventorySystem _inventory = default!;
+    [Dependency] private readonly SharedPopupSystem _popup = default!;
+
+    /// <summary>
+    /// Checks if the given user has fingerprint access to the target entity.
+    /// </summary>
+    /// <param name="target">The target entity.</param>
+    /// <param name="user">User trying to gain access.</param>
+    /// <returns>True if access was granted, otherwise false.</returns>
+    [PublicAPI]
+    public bool IsAllowed(Entity<FingerprintReaderComponent?> target, EntityUid user)
+    {
+        if (!Resolve(target, ref target.Comp, false))
+            return true;
+
+        if (target.Comp.AllowedFingerprints.Count == 0)
+            return true;
+
+        // Check for gloves first
+        if (!target.Comp.IgnoreGloves && TryGetBlockingGloves(user, out var gloves))
+        {
+            if (target.Comp.FailGlovesPopup != null)
+                _popup.PopupEntity(Loc.GetString(target.Comp.FailGlovesPopup, ("blocker", gloves)), target, user);
+            return false;
+        }
+
+        // Check fingerprint match
+        if (!TryComp<FingerprintComponent>(user, out var fingerprint) || fingerprint.Fingerprint == null ||
+            !target.Comp.AllowedFingerprints.Contains(fingerprint.Fingerprint))
+        {
+            if (target.Comp.FailPopup != null)
+                _popup.PopupEntity(Loc.GetString(target.Comp.FailPopup), target, user);
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /// <summary>
+    /// Gets the blocking gloves of a user. Gloves count as blocking if they hide fingerprints.
+    /// </summary>
+    /// <param name="user">Entity wearing the gloves.</param>
+    /// <param name="blocker">The returned gloves, if they exist.</param>
+    /// <returns>True if blocking gloves were found, otherwise False.</returns>
+    [PublicAPI]
+    public bool TryGetBlockingGloves(EntityUid user, [NotNullWhen(true)] out EntityUid? blocker)
+    {
+        blocker = null;
+
+        if (_inventory.TryGetSlotEntity(user, "gloves", out var gloves) && HasComp<FingerprintMaskComponent>(gloves))
+        {
+            blocker = gloves;
+            return true;
+        }
+
+        return false;
+    }
+
+    /// <summary>
+    /// Sets the allowed fingerprints for a fingerprint reader
+    /// </summary>
+    [PublicAPI]
+    public void SetAllowedFingerprints(Entity<FingerprintReaderComponent> target, HashSet<string> fingerprints)
+    {
+        target.Comp.AllowedFingerprints = fingerprints;
+        Dirty(target);
+    }
+
+    /// <summary>
+    /// Adds an allowed fingerprint to a fingerprint reader
+    /// </summary>
+    [PublicAPI]
+    public void AddAllowedFingerprint(Entity<FingerprintReaderComponent> target, string fingerprint)
+    {
+        target.Comp.AllowedFingerprints.Add(fingerprint);
+        Dirty(target);
+    }
+
+    /// <summary>
+    /// Removes an allowed fingerprint from a fingerprint reader
+    /// </summary>
+    [PublicAPI]
+    public void RemoveAllowedFingerprint(Entity<FingerprintReaderComponent> target, string fingerprint)
+    {
+        target.Comp.AllowedFingerprints.Remove(fingerprint);
+        Dirty(target);
+    }
+}
diff --git a/Resources/Locale/en-US/fingerprint-reader/fingerprint-reader.ftl b/Resources/Locale/en-US/fingerprint-reader/fingerprint-reader.ftl
new file mode 100644 (file)
index 0000000..b8d7807
--- /dev/null
@@ -0,0 +1,2 @@
+fingerprint-reader-fail = Your fingerprint does not match!
+fingerprint-reader-fail-gloves = The fingerprint reader cannot read through your {$blocker}!