StationObscurum/Assets/FishNet/Runtime/Managing/Transporting/SplitReader.cs

99 lines
3.1 KiB
C#

using FishNet.Serializing;
using System;
using UnityEngine;
namespace FishNet.Managing.Transporting
{
internal class SplitReader
{
#region Private.
/// <summary>
/// Tick split is for.
/// Tick must be a negative value so that it's impossible for the first tick to align.
/// </summary>
private long _tick = -1;
/// <summary>
/// Expected number of splits.
/// </summary>
private int _expectedMessages;
/// <summary>
/// Number of splits received so far.
/// </summary>
private ushort _receivedMessages;
/// <summary>
/// Writer containing split packet combined.
/// </summary>
private PooledWriter _writer = WriterPool.GetWriter();
#endregion
internal SplitReader()
{
//Increase capacity to reduce the chance of resizing.
_writer.EnsureBufferCapacity(20000);
}
/// <summary>
/// Gets split header values.
/// </summary>
internal void GetHeader(PooledReader reader, out int expectedMessages)
{
expectedMessages = reader.ReadInt32();
}
/// <summary>
/// Combines split data.
/// </summary>
internal void Write(uint tick, PooledReader reader, int expectedMessages)
{
//New tick which means new split.
if (tick != _tick)
Reset(tick, expectedMessages);
/* This is just a guess as to how large the end
* message could be. If the writer is not the minimum
* of this length then resize it. */
int estimatedBufferSize = (expectedMessages * 1500);
if (_writer.Capacity < estimatedBufferSize)
_writer.EnsureBufferCapacity(estimatedBufferSize);
/* Empty remainder of reader into the writer.
* It does not matter if parts of the reader
* contain data added after the split because
* once the split is fully combined the data
* is parsed as though it came in as one message,
* which is how data is normally read. */
ArraySegment<byte> data = reader.ReadArraySegment(reader.Remaining);
_writer.WriteArraySegment(data);
_receivedMessages++;
}
/// <summary>
/// Returns if all split messages have been received.
/// </summary>
/// <returns></returns>
internal ArraySegment<byte> GetFullMessage()
{
if (_receivedMessages < _expectedMessages)
{
return default(ArraySegment<byte>);
}
else
{
ArraySegment<byte> segment = _writer.GetArraySegment();
Reset();
return segment;
}
}
private void Reset(uint tick = 0, int expectedMessages = 0)
{
_tick = tick;
_receivedMessages = 0;
_expectedMessages = expectedMessages;
_writer.Reset();
}
}
}