Skip to content

Commit

Permalink
Create DeviceNetworkJammerComponent & System as a general way for ent…
Browse files Browse the repository at this point in the history
…ities to act as jammers (#26342)

* Add DeviceNetworkJammerComponent & System

Allows for entities to "jam" DeviceNetwork packets.

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.

* Make JammerSystem for the radio jammer use the DeviceNetworkJammer. Remove redundant event.

* Replace calls to TryDistance with InRange
  • Loading branch information
nikthechampiongr authored Mar 25, 2024
1 parent 49dbead commit 266cc85
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 25 deletions.
38 changes: 38 additions & 0 deletions Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs
Original file line number Diff line number Diff line change
@@ -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<TransformComponent, BeforePacketSentEvent>(BeforePacketSent);
}

private void BeforePacketSent(EntityUid uid, TransformComponent xform, BeforePacketSentEvent ev)
{
if (ev.Cancelled)
return;

var query = EntityQueryEnumerator<DeviceNetworkJammerComponent, TransformComponent>();

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;
}
}
}

}
11 changes: 9 additions & 2 deletions Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,13 +351,14 @@ private void SendToConnections(ReadOnlySpan<DeviceNetworkComponent> 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)
Expand Down Expand Up @@ -386,11 +387,17 @@ public sealed class BeforePacketSentEvent : CancellableEntityEventArgs
/// </summary>
public readonly Vector2 SenderPosition;

public BeforePacketSentEvent(EntityUid sender, TransformComponent xform, Vector2 senderPosition)
/// <summary>
/// The network the packet will be sent to.
/// </summary>
public readonly string NetworkId;

public BeforePacketSentEvent(EntityUid sender, TransformComponent xform, Vector2 senderPosition, string networkId)
{
Sender = sender;
SenderTransform = xform;
SenderPosition = senderPosition;
NetworkId = networkId;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -38,7 +39,7 @@ public bool IsActiveServer(EntityUid serverId, SingletonDeviceNetServerComponent
/// <param name="address">The address of the active server if it exists</param>
/// <typeparam name="TComp">The component type that determines what type of server you're getting the address of</typeparam>
/// <returns>True if there is an active serve. False otherwise</returns>
public bool TryGetActiveServerAddress<TComp>(EntityUid stationId, out string? address) where TComp : IComponent
public bool TryGetActiveServerAddress<TComp>(EntityUid stationId, [NotNullWhen(true)] out string? address) where TComp : IComponent
{
var servers = EntityQueryEnumerator<
SingletonDeviceNetServerComponent,
Expand Down
6 changes: 0 additions & 6 deletions Content.Server/Medical/SuitSensors/SuitSensorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,3 @@ public sealed partial class SuitSensorComponent : Component
[DataField, ViewVariables]
public bool PreviousControlsLocked = false;
}

[ByRefEvent]
public record struct SuitSensorsSendAttemptEvent
{
public bool Cancelled;
};
5 changes: 0 additions & 5 deletions Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ public override void Update(float frameTime)
// TODO: This would cause imprecision at different tick rates.
sensor.NextUpdate = curTime + sensor.UpdateRate;

var canEv = new SuitSensorsSendAttemptEvent();
RaiseLocalEvent(uid, ref canEv);
if (canEv.Cancelled)
continue;

// get sensor status
var status = GetSensorState(uid, sensor);
if (status == null)
Expand Down
27 changes: 17 additions & 10 deletions Content.Server/Radio/EntitySystems/JammerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using Content.Server.Medical.SuitSensors;
using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.Medical.CrewMonitoring;
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;
Expand All @@ -15,6 +19,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()
{
Expand All @@ -24,7 +30,6 @@ public override void Initialize()
SubscribeLocalEvent<ActiveRadioJammerComponent, PowerCellChangedEvent>(OnPowerCellChanged);
SubscribeLocalEvent<RadioJammerComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<RadioSendAttemptEvent>(OnRadioSendAttempt);
SubscribeLocalEvent<SuitSensorComponent, SuitSensorsSendAttemptEvent>(OnSensorSendAttempt);
}

public override void Update(float frameTime)
Expand All @@ -36,6 +41,7 @@ public override void Update(float frameTime)
!_battery.TryUseCharge(batteryUid.Value, jam.Wattage * frameTime, battery))
{
RemComp<ActiveRadioJammerComponent>(uid);
RemComp<DeviceNetworkJammerComponent>(uid);
}
}
}
Expand All @@ -48,10 +54,19 @@ private void OnActivate(EntityUid uid, RadioJammerComponent comp, ActivateInWorl
if (activated)
{
EnsureComp<ActiveRadioJammerComponent>(uid);
var stationId = _stationSystem.GetOwningStation(uid);
if (stationId != null && _singletonServerSystem.TryGetActiveServerAddress<CrewMonitoringServerComponent>(stationId.Value, out var netId))
{
EnsureComp<DeviceNetworkJammerComponent>(uid, out var jammingComp);
jammingComp.Range = comp.Range;
jammingComp.JammableNetworks.Add(netId);
Dirty(uid, jammingComp);
}
}
else
{
RemComp<ActiveRadioJammerComponent>(uid);
RemComp<DeviceNetworkJammerComponent>(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));
Expand Down Expand Up @@ -84,14 +99,6 @@ private void OnRadioSendAttempt(ref RadioSendAttemptEvent args)
}
}

private void OnSensorSendAttempt(EntityUid uid, SuitSensorComponent comp, ref SuitSensorsSendAttemptEvent args)
{
if (ShouldCancelSend(uid))
{
args.Cancelled = true;
}
}

private bool ShouldCancelSend(EntityUid sourceUid)
{
var source = Transform(sourceUid).Coordinates;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Robust.Shared.GameStates;

namespace Content.Shared.DeviceNetwork.Components;

/// <summary>
/// Allow entities to jam DeviceNetwork packets.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class DeviceNetworkJammerComponent : Component
{
/// <summary>
/// Range where packets will be jammed. This is checked both against the sender and receiver.
/// </summary>
[DataField, AutoNetworkedField]
public float Range = 5.0f;

/// <summary>
/// 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.
/// </summary>
[DataField, AutoNetworkedField]
public HashSet<string> JammableNetworks = [];

}

0 comments on commit 266cc85

Please sign in to comment.