using FishNet.Serializing; using System; using UnityEngine; namespace FishNet.Managing.Transporting { internal class SplitReader { #region Private. /// /// Tick split is for. /// Tick must be a negative value so that it's impossible for the first tick to align. /// private long _tick = -1; /// /// Expected number of splits. /// private int _expectedMessages; /// /// Number of splits received so far. /// private ushort _receivedMessages; /// /// Writer containing split packet combined. /// private PooledWriter _writer = WriterPool.GetWriter(); #endregion internal SplitReader() { //Increase capacity to reduce the chance of resizing. _writer.EnsureBufferCapacity(20000); } /// /// Gets split header values. /// internal void GetHeader(PooledReader reader, out int expectedMessages) { expectedMessages = reader.ReadInt32(); } /// /// Combines split data. /// 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 data = reader.ReadArraySegment(reader.Remaining); _writer.WriteArraySegment(data); _receivedMessages++; } /// /// Returns if all split messages have been received. /// /// internal ArraySegment GetFullMessage() { if (_receivedMessages < _expectedMessages) { return default(ArraySegment); } else { ArraySegment segment = _writer.GetArraySegment(); Reset(); return segment; } } private void Reset(uint tick = 0, int expectedMessages = 0) { _tick = tick; _receivedMessages = 0; _expectedMessages = expectedMessages; _writer.Reset(); } } }