Cleaning device net system (#8153)

This commit is contained in:
wrexbe
2022-05-16 16:52:37 -07:00
committed by GitHub
parent b0e4fc4b8c
commit a91aed082f

View File

@@ -3,6 +3,8 @@ using Content.Shared.DeviceNetwork;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using static Content.Server.DeviceNetwork.Components.DeviceNetworkComponent;
@@ -19,7 +21,7 @@ namespace Content.Server.DeviceNetwork.Systems
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
private readonly Dictionary<ConnectionType, DeviceNet> _networks = new();
private readonly DeviceNet[] _networks = new DeviceNet[4]; // Number of ConnectionType enum values
private readonly Queue<DeviceNetworkPacketEvent> _packets = new();
public override void Initialize()
@@ -28,16 +30,17 @@ namespace Content.Server.DeviceNetwork.Systems
SubscribeLocalEvent<DeviceNetworkComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<DeviceNetworkComponent, ComponentShutdown>(OnNetworkShutdown);
InitNetwork(ConnectionType.Private);
InitNetwork(ConnectionType.Wired);
InitNetwork(ConnectionType.Wireless);
InitNetwork(ConnectionType.Apc);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
while (_packets.Count > 0)
while (_packets.TryDequeue(out var packet))
{
var packet = _packets.Dequeue();
SendPacket(packet);
}
}
@@ -64,6 +67,9 @@ namespace Content.Server.DeviceNetwork.Systems
_packets.Enqueue(new DeviceNetworkPacketEvent(device.DeviceNetId, address, frequency.Value, device.Address, uid, data));
}
private void InitNetwork(ConnectionType connectionType) =>
_networks[(int) connectionType] = new(connectionType, _random);
/// <summary>
/// Automatically attempt to connect some devices when a map starts.
/// </summary>
@@ -87,12 +93,15 @@ namespace Content.Server.DeviceNetwork.Systems
ConnectDevice(uid, device);
}
private DeviceNet GetNetwork(ConnectionType connectionType) =>
_networks[(int) connectionType];
/// <summary>
/// Automatically disconnect when an entity with a DeviceNetworkComponent shuts down.
/// </summary>
private void OnNetworkShutdown(EntityUid uid, DeviceNetworkComponent component, ComponentShutdown args)
{
DisconnectDevice(uid, component, false);
GetNetwork(component.DeviceNetId).Remove(component);
}
/// <summary>
@@ -104,13 +113,7 @@ namespace Content.Server.DeviceNetwork.Systems
if (!Resolve(uid, ref device, false))
return false;
if (!_networks.TryGetValue(device.DeviceNetId, out var network))
{
network = new(device.DeviceNetId, _random);
_networks[device.DeviceNetId] = network;
}
return network.Add(device);
return GetNetwork(device.DeviceNetId).Add(device);
}
/// <summary>
@@ -125,82 +128,115 @@ namespace Content.Server.DeviceNetwork.Systems
if (preventAutoConnect)
device.AutoConnect = false;
if (!_networks.TryGetValue(device.DeviceNetId, out var network))
{
return false;
}
if (!network.Remove(device))
return false;
if (network.Devices.Count == 0)
_networks.Remove(device.DeviceNetId);
return true;
return GetNetwork(device.DeviceNetId).Remove(device);
}
#region Get Device
/// <summary>
/// Get a list of devices listening on a given frequency on some network.
/// </summary>
private HashSet<DeviceNetworkComponent> GetListeningDevices(ConnectionType netId, uint frequency)
public void SetReceiveFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null)
{
if (_networks.TryGetValue(netId, out var network) && network.ListeningDevices.TryGetValue(frequency, out var devices))
return devices;
if (!Resolve(uid, ref device, false))
return;
return new();
if (device.ReceiveFrequency == frequency) return;
var deviceNet = GetNetwork(device.DeviceNetId);
deviceNet.Remove(device);
device.ReceiveFrequency = frequency;
deviceNet.Add(device);
}
/// <summary>
/// Get a list of devices listening for ANY transmission on a given frequency, rather than just broadcast & addressed events.
/// </summary>
private HashSet<DeviceNetworkComponent> GetRecieveAllDevices(ConnectionType netId, uint frequency)
public void SetTransmitFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null)
{
if (_networks.TryGetValue(netId, out var network) && network.ReceiveAllDevices.TryGetValue(frequency, out var devices))
return devices;
if (Resolve(uid, ref device, false))
device.TransmitFrequency = frequency;
}
return new();
public void SetReceiveAll(EntityUid uid, bool receiveAll, DeviceNetworkComponent? device = null)
{
if (!Resolve(uid, ref device, false))
return;
if (device.ReceiveAll == receiveAll) return;
var deviceNet = GetNetwork(device.DeviceNetId);
deviceNet.Remove(device);
device.ReceiveAll = receiveAll;
deviceNet.Add(device);
}
public void SetAddress(EntityUid uid, string address, DeviceNetworkComponent? device = null)
{
if (!Resolve(uid, ref device, false))
return;
if (device.Address == address && device.CustomAddress == true) return;
var deviceNet = GetNetwork(device.DeviceNetId);
deviceNet.Remove(device);
device.CustomAddress = true;
device.Address = address;
deviceNet.Add(device);
}
public void RandomizeAddress(EntityUid uid, DeviceNetworkComponent? device = null)
{
if (!Resolve(uid, ref device, false))
return;
var deviceNet = GetNetwork(device.DeviceNetId);
deviceNet.Remove(device);
device.CustomAddress = false;
device.Address = "";
deviceNet.Add(device);
}
/// <summary>
/// Try to find a device on a network using its address.
/// </summary>
private bool TryGetDevice(ConnectionType netId, string address, [NotNullWhen(true)] out DeviceNetworkComponent? device)
{
if (!_networks.TryGetValue(netId, out var network))
{
device = null;
return false;
}
private bool TryGetDevice(ConnectionType netId, string address, [NotNullWhen(true)] out DeviceNetworkComponent? device) =>
GetNetwork(netId).Devices.TryGetValue(address, out device);
return network.Devices.TryGetValue(address, out device);
}
#endregion
#region Packet Sending
private void SendPacket(DeviceNetworkPacketEvent packet)
{
HashSet<DeviceNetworkComponent> recipients;
var network = GetNetwork(packet.NetId);
if (packet.Address == null)
{
// Broadcast to all listening devices
recipients = GetListeningDevices(packet.NetId, packet.Frequency);
if (network.ListeningDevices.TryGetValue(packet.Frequency, out var devices))
{
var deviceCopy = ArrayPool<DeviceNetworkComponent>.Shared.Rent(devices.Count);
devices.CopyTo(deviceCopy);
SendToConnections(deviceCopy.AsSpan(0, devices.Count), packet);
ArrayPool<DeviceNetworkComponent>.Shared.Return(deviceCopy);
}
}
else
{
// Add devices listening to all messages
recipients = new(GetRecieveAllDevices(packet.NetId, packet.Frequency));
// add the intended recipient (if they are even listening).
if (TryGetDevice(packet.NetId, packet.Address, out var device) && device.ReceiveFrequency == packet.Frequency)
recipients.Add(device);
var totalDevices = 0;
var hasTargetedDevice = false;
if (network.ReceiveAllDevices.TryGetValue(packet.Frequency, out var devices))
{
totalDevices += devices.Count;
}
if (TryGetDevice(packet.NetId, packet.Address, out var device) &&
!device.ReceiveAll &&
device.ReceiveFrequency == packet.Frequency)
{
totalDevices += 1;
hasTargetedDevice = true;
}
var deviceCopy = ArrayPool<DeviceNetworkComponent>.Shared.Rent(totalDevices);
if (devices != null)
{
devices.CopyTo(deviceCopy);
}
if (hasTargetedDevice)
{
deviceCopy[totalDevices - 1] = device!;
}
SendToConnections(deviceCopy.AsSpan(0, totalDevices), packet);
ArrayPool<DeviceNetworkComponent>.Shared.Return(deviceCopy);
}
SendToConnections(recipients, packet);
}
private void SendToConnections(HashSet<DeviceNetworkComponent> connections, DeviceNetworkPacketEvent packet)
private void SendToConnections(ReadOnlySpan<DeviceNetworkComponent> connections, DeviceNetworkPacketEvent packet)
{
var xform = Transform(packet.Sender);
@@ -219,70 +255,6 @@ namespace Content.Server.DeviceNetwork.Systems
beforeEv.Uncancel();
}
}
#endregion
#region Component Setter Functions
public void SetReceiveFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null)
{
if (!Resolve(uid, ref device, false))
return;
if (device.ReceiveFrequency == frequency)
return;
if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.UpdateReceiveFrequency(device.Address, frequency))
device.ReceiveFrequency = frequency;
}
public void SetTransmitFrequency(EntityUid uid, uint? frequency, DeviceNetworkComponent? device = null)
{
if (Resolve(uid, ref device, false))
device.TransmitFrequency = frequency;
}
public void SetReceiveAll(EntityUid uid, bool receiveAll, DeviceNetworkComponent? device = null)
{
if (!Resolve(uid, ref device, false))
return;
if (device.ReceiveAll == receiveAll)
return;
if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.UpdateReceiveAll(device.Address, receiveAll))
device.ReceiveAll = receiveAll;
}
public void SetAddress(EntityUid uid, string address, DeviceNetworkComponent? device = null)
{
if (!Resolve(uid, ref device, false))
return;
if (device.Address == address)
{
device.CustomAddress = true;
return;
}
if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.UpdateAddress(device.Address, address))
{
device.Address = address;
device.CustomAddress = true;
}
}
public void RandomizeAddress(EntityUid uid, string address, DeviceNetworkComponent? device = null)
{
if (!Resolve(uid, ref device, false))
return;
if (!_networks.TryGetValue(device.DeviceNetId, out var deviceNet) || !deviceNet.RandomizeAddress(device.Address, address))
{
var prefix = string.IsNullOrWhiteSpace(device.Prefix) ? null : Loc.GetString(device.Prefix);
device.Address = $"{prefix}{_random.Next():x}";
device.CustomAddress = false;
}
}
#endregion
}
/// <summary>