mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 13:37:47 +03:00
## 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 <img src="https://avatars.githubusercontent.com/u/10567778?v=4" alt="space-wizards" width="22"/> [space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14) ###### `266cc85f57c883b3a604a66da91d94bb1e18ec5d` PR opened by <img src="https://avatars.githubusercontent.com/u/32041239?v=4" width="16"/><a href="https://github.com/nikthechampiongr"> nikthechampiongr</a> 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 --- <details open="true"><summary><h1>Original Body</h1></summary> > <!-- Please read these guidelines before opening your PR: https://docs.spacestation14.io/en/getting-started/pr-guideline --> > <!-- The text between the arrows are comments - they will not be visible on your PR. --> > > ## About the PR > <!-- What did you change in this 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 > <!-- Why was it changed? Link any discussions or issues here. Please discuss how this would affect game 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 > <!-- If this is a code change, summarize at high level how your new code works. This makes it easier to review. --> > > 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 > <!-- > PRs which make ingame changes (adding clothing, items, new features, etc) are required to have media attached that showcase the changes. > Small fixes/refactors are exempt. > Any media may be used in SS14 progress reports, with clear credit given. > > If you're unsure whether your PR will require media, ask a maintainer. > > Check the box below to confirm that you have in fact seen this (put an X in the brackets, like [X]): > --> > > - [x] I have added screenshots/videos to this PR showcasing its changes ingame, **or** this PR does not require an ingame showcase > > **Changelog** > <!-- > Make players aware of new features and changes that could affect how they play the game by adding a Changelog entry. Please read the Changelog guidelines located at: https://docs.spacestation14.io/en/getting-started/pr-guideline#changelog > --> > > <!-- > Make sure to take this Changelog template out of the comment block in order for it to show up. > 🆑 > - add: Added fun! > - remove: Removed fun! > - tweak: Changed fun! > - fix: Fixed fun! > --> > no cl no fun </details> Signed-off-by: VMSolidus <evilexecutive@gmail.com> Co-authored-by: SimpleStation14 <Unknown> Co-authored-by: VMSolidus <evilexecutive@gmail.com>
139 lines
5.1 KiB
C#
139 lines
5.1 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using Content.Server.DeviceNetwork.Components;
|
|
using Content.Server.Medical.CrewMonitoring;
|
|
using Content.Server.Power.Components;
|
|
using Content.Server.Station.Systems;
|
|
|
|
namespace Content.Server.DeviceNetwork.Systems;
|
|
|
|
/// <summary>
|
|
/// Keeps one active server entity per station. Activates another available one if the currently active server becomes unavailable
|
|
/// Server in this context means an entity that manages the devicenet packets like the <see cref="Content.Server.Medical.CrewMonitoring.CrewMonitoringServerSystem"/>
|
|
/// </summary>
|
|
public sealed class SingletonDeviceNetServerSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly DeviceNetworkSystem _deviceNetworkSystem = default!;
|
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
SubscribeLocalEvent<SingletonDeviceNetServerComponent, PowerChangedEvent>(OnPowerChanged);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns whether the given entity is an active server or not
|
|
/// </summary>
|
|
public bool IsActiveServer(EntityUid serverId, SingletonDeviceNetServerComponent? serverComponent = default)
|
|
{
|
|
return Resolve(serverId, ref serverComponent) && serverComponent.Active;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the address of the currently active server for the given station id if there is one.<br/>
|
|
/// What kind of server you're trying to get the active instance of is determined by the component type parameter TComp.<br/>
|
|
/// <br/>
|
|
/// Setting TComp to <see cref="CrewMonitoringServerComponent"/>, for example, gives you the address of an entity containing the crew monitoring server component.<br/>
|
|
/// </summary>
|
|
/// <param name="stationId">The entityUid of the station</param>
|
|
/// <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, [NotNullWhen(true)] out string? address) where TComp : IComponent
|
|
{
|
|
var servers = EntityQueryEnumerator<
|
|
SingletonDeviceNetServerComponent,
|
|
DeviceNetworkComponent,
|
|
TComp
|
|
>();
|
|
|
|
(EntityUid id, SingletonDeviceNetServerComponent server, DeviceNetworkComponent device)? last = default;
|
|
|
|
while (servers.MoveNext(out var uid, out var server, out var device, out _))
|
|
{
|
|
if (!_stationSystem.GetOwningStation(uid)?.Equals(stationId) ?? true)
|
|
continue;
|
|
|
|
if (!server.Available)
|
|
{
|
|
DisconnectServer(uid,server, device);
|
|
continue;
|
|
}
|
|
|
|
last = (uid, server, device);
|
|
|
|
if (!server.Active)
|
|
continue;
|
|
|
|
address = device.Address;
|
|
return true;
|
|
}
|
|
|
|
//If there was no active server for the station make the last available inactive one active
|
|
if (last.HasValue)
|
|
{
|
|
ConnectServer(last.Value.id, last.Value.server, last.Value.device);
|
|
address = last.Value.device.Address;
|
|
return true;
|
|
}
|
|
|
|
address = null;
|
|
return address != null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disconnects the server losing power
|
|
/// </summary>
|
|
private void OnPowerChanged(EntityUid uid, SingletonDeviceNetServerComponent component, ref PowerChangedEvent args)
|
|
{
|
|
component.Available = args.Powered;
|
|
|
|
if (!args.Powered && component.Active)
|
|
DisconnectServer(uid, component);
|
|
}
|
|
|
|
private void ConnectServer(EntityUid uid, SingletonDeviceNetServerComponent? server = null, DeviceNetworkComponent? device = null)
|
|
{
|
|
if (!Resolve(uid, ref server, ref device))
|
|
return;
|
|
|
|
server.Active = true;
|
|
|
|
var connectedEvent = new DeviceNetServerConnectedEvent();
|
|
RaiseLocalEvent(uid, ref connectedEvent);
|
|
|
|
if (_deviceNetworkSystem.IsDeviceConnected(uid, device))
|
|
return;
|
|
|
|
_deviceNetworkSystem.ConnectDevice(uid, device);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disconnects a server from the device network and clears the currently active server
|
|
/// </summary>
|
|
private void DisconnectServer(EntityUid uid, SingletonDeviceNetServerComponent? server = null, DeviceNetworkComponent? device = null)
|
|
{
|
|
if (!Resolve(uid, ref server, ref device))
|
|
return;
|
|
|
|
server.Active = false;
|
|
|
|
var disconnectedEvent = new DeviceNetServerDisconnectedEvent();
|
|
RaiseLocalEvent(uid, ref disconnectedEvent);
|
|
|
|
_deviceNetworkSystem.DisconnectDevice(uid, device, false);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Raised when a server gets activated and connected to the device net
|
|
/// </summary>
|
|
[ByRefEvent]
|
|
public record struct DeviceNetServerConnectedEvent;
|
|
|
|
/// <summary>
|
|
/// Raised when a server gets disconnected
|
|
/// </summary>
|
|
[ByRefEvent]
|
|
public record struct DeviceNetServerDisconnectedEvent;
|