99 lines
3.1 KiB
C#
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();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} |