Prevent infinite loops in device linking (#16856)
This commit is contained in:
@@ -3,11 +3,9 @@ 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 Content.Shared.Examine;
|
||||
using static Content.Server.DeviceNetwork.Components.DeviceNetworkComponent;
|
||||
|
||||
namespace Content.Server.DeviceNetwork.Systems
|
||||
{
|
||||
@@ -23,21 +21,39 @@ namespace Content.Server.DeviceNetwork.Systems
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
|
||||
private readonly Dictionary<int, DeviceNet> _networks = new(4);
|
||||
private readonly Queue<DeviceNetworkPacketEvent> _packets = new();
|
||||
private readonly Queue<DeviceNetworkPacketEvent> _queueA = new();
|
||||
private readonly Queue<DeviceNetworkPacketEvent> _queueB = new();
|
||||
|
||||
/// <summary>
|
||||
/// The queue being processed in the current tick
|
||||
/// </summary>
|
||||
private Queue<DeviceNetworkPacketEvent> _activeQueue = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The queue that will be processed in the next tick
|
||||
/// </summary>
|
||||
private Queue<DeviceNetworkPacketEvent> _nextQueue = null!;
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<DeviceNetworkComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<DeviceNetworkComponent, ComponentShutdown>(OnNetworkShutdown);
|
||||
SubscribeLocalEvent<DeviceNetworkComponent, ExaminedEvent>(OnExamine);
|
||||
|
||||
_activeQueue = _queueA;
|
||||
_nextQueue = _queueB;
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
while (_packets.TryDequeue(out var packet))
|
||||
|
||||
while (_activeQueue.TryDequeue(out var packet))
|
||||
{
|
||||
SendPacket(packet);
|
||||
}
|
||||
|
||||
SwapQueues();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -62,10 +78,23 @@ namespace Content.Server.DeviceNetwork.Systems
|
||||
if (frequency == null)
|
||||
return false;
|
||||
|
||||
_packets.Enqueue(new DeviceNetworkPacketEvent(device.DeviceNetId, address, frequency.Value, device.Address, uid, data));
|
||||
_nextQueue.Enqueue(new DeviceNetworkPacketEvent(device.DeviceNetId, address, frequency.Value, device.Address, uid, data));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Swaps the active queue.
|
||||
/// Queues are swapped so that packets being sent in the current tick get processed in the next tick.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This prevents infinite loops while sending packets
|
||||
/// </remarks>
|
||||
private void SwapQueues()
|
||||
{
|
||||
_nextQueue = _activeQueue;
|
||||
_activeQueue = _activeQueue == _queueA ? _queueB : _queueA;
|
||||
}
|
||||
|
||||
private void OnExamine(EntityUid uid, DeviceNetworkComponent device, ExaminedEvent args)
|
||||
{
|
||||
if (device.ExaminableAddress)
|
||||
|
||||
Reference in New Issue
Block a user