From 2fb4c5e79384877f9aa8f8373529ffcde55e5cbe Mon Sep 17 00:00:00 2001 From: SimpleStation14 <130339894+SimpleStation14@users.noreply.github.com> Date: Wed, 29 May 2024 00:03:15 -0400 Subject: [PATCH] Mirror: Create DeviceNetworkJammerComponent & System as a general way for entities to act as jammers (#382) ## Mirror of PR #26342: [Create DeviceNetworkJammerComponent & System as a general way for entities to act as jammers](https://github.com/space-wizards/space-station-14/pull/26342) from space-wizards [space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14) ###### `266cc85f57c883b3a604a66da91d94bb1e18ec5d` PR opened by nikthechampiongr at 2024-03-22 19:17:23 UTC --- PR changed 7 files with 91 additions and 25 deletions. The PR had the following labels: - Status: Needs Review ---

Original Body

> > > > ## About the PR > > This PR creates the DeviceNetworkJammerComponent & System as a general way for entities to act as jammers for the DeviceNetwork. > > Additionally it adjusts the JammerSystem for the radio jammer to use this, and rips out the previous special code for jamming suit sensors. > > As a result of this, the radio jammer can now additionally jam the suit sensor server itself from receiving DeviceNetwork packets. > > ## Why / Balance > > This pr was requested by a maintainer. > > Additionally a general jamming system can have some utility in the future. E.g. an artifact effect. > ## Technical details > > > Whenever a device attempts to send a packet, the > DeviceNetworkJammerSystem listens for the BeforePacketSentEvent. > From there if any entity with the jammer component is within range of > either the sender or receiver of the packet the event will be cancelled. > Additionally jammers can only block packets in certain networks. If a > packet is not being transmitted in one of the networks it can block then > even if the jammer is in range the event will not be cancelled. > > The range is stored in the jammer component along with the networks it > can jam. > > Jammable network ids are stored as strings which seems to be how custom > networks are stored (E.g. network ids for suit sensors). > > To allow for all of this, the BeforePacketSentEvent was modified to > provide the NetworkId. > > The JammerSystem now needs to get the networkid for suit sensors for use in the DeviceNetwork. The previous event subscription for jamming suit sensors have been removed along with the event. > > I wish I could use this to jam radios as well but radios are magic and do not use device networks. > > ## Media > > > - [x] I have added screenshots/videos to this PR showcasing its changes ingame, **or** this PR does not require an ingame showcase > > **Changelog** > > > > no cl no fun
Signed-off-by: VMSolidus Co-authored-by: SimpleStation14 Co-authored-by: VMSolidus --- .../Systems/DeviceNetworkJammerSystem.cs | 38 +++++++++++++++++++ .../Systems/DeviceNetworkSystem.cs | 11 +++++- .../Systems/SingletonDeviceNetServerSystem.cs | 5 ++- .../Radio/EntitySystems/JammerSystem.cs | 17 +++++++++ .../DeviceNetworkJammerComponent.cs | 24 ++++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs create mode 100644 Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs diff --git a/Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs b/Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs new file mode 100644 index 00000000000..3d3820562d6 --- /dev/null +++ b/Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs @@ -0,0 +1,38 @@ +using Content.Server.DeviceNetwork.Components; +using Content.Shared.DeviceNetwork.Components; +using Robust.Server.GameObjects; + +namespace Content.Server.DeviceNetwork.Systems; + +public sealed class DeviceNetworkJammerSystem : EntitySystem +{ + [Dependency] private TransformSystem _transform = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(BeforePacketSent); + } + + private void BeforePacketSent(EntityUid uid, TransformComponent xform, BeforePacketSentEvent ev) + { + if (ev.Cancelled) + return; + + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out _, out var jammerComp, out var jammerXform)) + { + if (!jammerComp.JammableNetworks.Contains(ev.NetworkId)) + continue; + + if (jammerXform.Coordinates.InRange(EntityManager, _transform, ev.SenderTransform.Coordinates, jammerComp.Range) + || jammerXform.Coordinates.InRange(EntityManager, _transform, xform.Coordinates, jammerComp.Range)) + { + ev.Cancel(); + return; + } + } + } + +} diff --git a/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs b/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs index 83967c9bbd4..20ee7a5dd1b 100644 --- a/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs @@ -351,13 +351,14 @@ private void SendToConnections(ReadOnlySpan connections, var xform = Transform(packet.Sender); - BeforePacketSentEvent beforeEv = new(packet.Sender, xform, _transformSystem.GetWorldPosition(xform)); + var senderPos = _transformSystem.GetWorldPosition(xform); foreach (var connection in connections) { if (connection.Owner == packet.Sender) continue; + BeforePacketSentEvent beforeEv = new(packet.Sender, xform, senderPos, connection.NetIdEnum.ToString()); RaiseLocalEvent(connection.Owner, beforeEv, false); if (!beforeEv.Cancelled) @@ -386,11 +387,17 @@ public sealed class BeforePacketSentEvent : CancellableEntityEventArgs /// public readonly Vector2 SenderPosition; - public BeforePacketSentEvent(EntityUid sender, TransformComponent xform, Vector2 senderPosition) + /// + /// The network the packet will be sent to. + /// + public readonly string NetworkId; + + public BeforePacketSentEvent(EntityUid sender, TransformComponent xform, Vector2 senderPosition, string networkId) { Sender = sender; SenderTransform = xform; SenderPosition = senderPosition; + NetworkId = networkId; } } diff --git a/Content.Server/DeviceNetwork/Systems/SingletonDeviceNetServerSystem.cs b/Content.Server/DeviceNetwork/Systems/SingletonDeviceNetServerSystem.cs index fd62514d006..cdc083feacd 100644 --- a/Content.Server/DeviceNetwork/Systems/SingletonDeviceNetServerSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/SingletonDeviceNetServerSystem.cs @@ -1,4 +1,5 @@ -using Content.Server.DeviceNetwork.Components; +using System.Diagnostics.CodeAnalysis; +using Content.Server.DeviceNetwork.Components; using Content.Server.Medical.CrewMonitoring; using Content.Server.Power.Components; using Content.Server.Station.Systems; @@ -38,7 +39,7 @@ public bool IsActiveServer(EntityUid serverId, SingletonDeviceNetServerComponent /// The address of the active server if it exists /// The component type that determines what type of server you're getting the address of /// True if there is an active serve. False otherwise - public bool TryGetActiveServerAddress(EntityUid stationId, out string? address) where TComp : IComponent + public bool TryGetActiveServerAddress(EntityUid stationId, [NotNullWhen(true)] out string? address) where TComp : IComponent { var servers = EntityQueryEnumerator< SingletonDeviceNetServerComponent, diff --git a/Content.Server/Radio/EntitySystems/JammerSystem.cs b/Content.Server/Radio/EntitySystems/JammerSystem.cs index fdf02f94df5..53e0409af06 100644 --- a/Content.Server/Radio/EntitySystems/JammerSystem.cs +++ b/Content.Server/Radio/EntitySystems/JammerSystem.cs @@ -1,8 +1,13 @@ +using Content.Server.DeviceNetwork.Components; +using Content.Server.DeviceNetwork.Systems; +using Content.Server.Medical.CrewMonitoring; using Content.Server.Medical.SuitSensors; using Content.Server.Popups; using Content.Server.Power.EntitySystems; using Content.Server.PowerCell; using Content.Server.Radio.Components; +using Content.Server.Station.Systems; +using Content.Shared.DeviceNetwork.Components; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.PowerCell.Components; @@ -15,6 +20,8 @@ public sealed class JammerSystem : EntitySystem [Dependency] private readonly BatterySystem _battery = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly StationSystem _stationSystem = default!; + [Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = default!; public override void Initialize() { @@ -36,6 +43,7 @@ public override void Update(float frameTime) !_battery.TryUseCharge(batteryUid.Value, jam.Wattage * frameTime, battery)) { RemComp(uid); + RemComp(uid); } } } @@ -48,10 +56,19 @@ private void OnActivate(EntityUid uid, RadioJammerComponent comp, ActivateInWorl if (activated) { EnsureComp(uid); + var stationId = _stationSystem.GetOwningStation(uid); + if (stationId != null && _singletonServerSystem.TryGetActiveServerAddress(stationId.Value, out var netId)) + { + EnsureComp(uid, out var jammingComp); + jammingComp.Range = comp.Range; + jammingComp.JammableNetworks.Add(netId); + Dirty(uid, jammingComp); + } } else { RemComp(uid); + RemComp(uid); } var state = Loc.GetString(activated ? "radio-jammer-component-on-state" : "radio-jammer-component-off-state"); var message = Loc.GetString("radio-jammer-component-on-use", ("state", state)); diff --git a/Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs b/Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs new file mode 100644 index 00000000000..75de0cb8a25 --- /dev/null +++ b/Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs @@ -0,0 +1,24 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.DeviceNetwork.Components; + +/// +/// Allow entities to jam DeviceNetwork packets. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class DeviceNetworkJammerComponent : Component +{ + /// + /// Range where packets will be jammed. This is checked both against the sender and receiver. + /// + [DataField, AutoNetworkedField] + public float Range = 5.0f; + + /// + /// Device networks that can be jammed. For a list of default NetworkIds see DeviceNetIdDefaults on Content.Server. + /// Network ids are not guaranteed to be limited to DeviceNetIdDefaults. + /// + [DataField, AutoNetworkedField] + public HashSet JammableNetworks = []; + +}