Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/Source/Networking/Voip/VoipQueue.cs
Joonas Rikkonen 044fd3344b 2f107db...5202af9
2019-03-18 21:42:26 +02:00

162 lines
4.5 KiB
C#

using Lidgren.Network;
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace Barotrauma.Networking
{
public 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 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(NetBuffer msg)
{
if (!CanSend) throw new Exception("Called Write on a VoipQueue not set up for sending");
msg.Write((UInt16)LatestBufferID);
for (int i = 0; i < BUFFER_COUNT; i++)
{
int index = (newestBufferInd + i + 1) % BUFFER_COUNT;
msg.Write((byte)bufferLengths[index]);
msg.Write(buffers[index], 0, bufferLengths[index]);
}
}
public virtual bool Read(NetBuffer msg)
{
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))
{
firstRead = false;
for (int i = 0; i < BUFFER_COUNT; i++)
{
bufferLengths[i] = msg.ReadByte();
msg.ReadBytes(buffers[i], 0, bufferLengths[i]);
}
newestBufferInd = BUFFER_COUNT - 1;
LatestBufferID = incLatestBufferID;
LastReadTime = DateTime.Now;
return true;
}
else
{
for (int i = 0; i < BUFFER_COUNT; i++)
{
byte len = msg.ReadByte();
msg.Position += len * 8;
}
return false;
}
}
public virtual void Dispose() { }
}
}