Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Networking/Voip/VoipQueue.cs
Juan Pablo Arce 3f2c843247 Unstable v0.19.3.0
2022-09-02 15:10:56 -03:00

174 lines
4.9 KiB
C#

using System;
namespace Barotrauma.Networking
{
class VoipQueue : IDisposable
{
public const int BUFFER_COUNT = 8;
protected int[] bufferLengths;
protected byte[][] buffers;
protected int newestBufferInd;
protected bool firstRead;
public int EnqueuedTotalLength
{
get
{
int enqueuedTotalLength = 0;
for (int i = 0; i < BUFFER_COUNT; i++)
{
enqueuedTotalLength += bufferLengths[i];
}
return enqueuedTotalLength;
}
}
public byte[] BufferToQueue
{
get;
protected set;
}
public virtual byte QueueID
{
get;
protected set;
}
public UInt16 LatestBufferID
{
get;
protected set;
}
public bool CanSend
{
get;
protected set;
}
public bool CanReceive
{
get;
protected set;
}
public bool ForceLocal
{
get;
set;
}
public DateTime LastReadTime
{
get;
private set;
}
public VoipQueue(byte id, bool canSend, bool canReceive)
{
BufferToQueue = new byte[VoipConfig.MAX_COMPRESSED_SIZE];
newestBufferInd = BUFFER_COUNT - 1;
bufferLengths = new int[BUFFER_COUNT];
buffers = new byte[BUFFER_COUNT][];
for (int i = 0; i < BUFFER_COUNT; i++)
{
buffers[i] = new byte[VoipConfig.MAX_COMPRESSED_SIZE];
}
QueueID = id;
CanSend = canSend;
CanReceive = canReceive;
LatestBufferID = BUFFER_COUNT - 1;
firstRead = true;
LastReadTime = DateTime.Now;
}
public void EnqueueBuffer(int length)
{
if (length > byte.MaxValue) { return; }
newestBufferInd = (newestBufferInd + 1) % BUFFER_COUNT;
int enqueuedTotalLength = EnqueuedTotalLength;
bufferLengths[newestBufferInd] = length;
BufferToQueue.CopyTo(buffers[newestBufferInd], 0);
if ((enqueuedTotalLength + length) > 0) { LatestBufferID++; }
}
public void RetrieveBuffer(int id, out int outSize, out byte[] outBuf)
{
lock (buffers)
{
if (id >= LatestBufferID - (BUFFER_COUNT - 1) && id <= LatestBufferID)
{
int index = newestBufferInd - (LatestBufferID - id);
if (index < 0) { index += BUFFER_COUNT; }
outSize = bufferLengths[index];
outBuf = buffers[index];
return;
}
}
outSize = -1;
outBuf = null;
}
public virtual void Write(IWriteMessage msg)
{
if (!CanSend) { throw new Exception("Called Write on a VoipQueue not set up for sending"); }
msg.WriteUInt16((UInt16)LatestBufferID);
msg.WriteBoolean(ForceLocal); msg.WritePadBits();
lock (buffers)
{
for (int i = 0; i < BUFFER_COUNT; i++)
{
int index = (newestBufferInd + i + 1) % BUFFER_COUNT;
msg.WriteByte((byte)bufferLengths[index]);
msg.WriteBytes(buffers[index], 0, bufferLengths[index]);
}
}
}
public virtual bool Read(IReadMessage msg, bool discardData = false)
{
if (!CanReceive) { throw new Exception("Called Read on a VoipQueue not set up for receiving"); }
UInt16 incLatestBufferID = msg.ReadUInt16();
if ((firstRead || NetIdUtils.IdMoreRecent(incLatestBufferID, LatestBufferID)) && !discardData)
{
ForceLocal = msg.ReadBoolean(); msg.ReadPadBits();
firstRead = false;
lock (buffers)
{
for (int i = 0; i < BUFFER_COUNT; i++)
{
bufferLengths[i] = msg.ReadByte();
buffers[i] = msg.ReadBytes(bufferLengths[i]);
}
}
newestBufferInd = BUFFER_COUNT - 1;
LatestBufferID = incLatestBufferID;
LastReadTime = DateTime.Now;
return true;
}
else
{
msg.ReadBoolean(); msg.ReadPadBits();
for (int i = 0; i < BUFFER_COUNT; i++)
{
byte len = msg.ReadByte();
msg.BitPosition += len * 8;
}
return false;
}
}
public virtual void Dispose() { }
}
}