using System; using System.Collections.Generic; namespace UnityEngine.Networking { // Token: 0x02000002 RID: 2 internal class ChannelBuffer : IDisposable { // Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250 public ChannelBuffer(NetworkConnection conn, int bufferSize, byte cid, bool isReliable, bool isSequenced) { this.m_Connection = conn; this.m_MaxPacketSize = bufferSize - 100; this.m_CurrentPacket = new ChannelPacket(this.m_MaxPacketSize, isReliable); this.m_ChannelId = cid; this.m_MaxPendingPacketCount = 16; this.m_IsReliable = isReliable; this.m_AllowFragmentation = isReliable && isSequenced; if (isReliable) { this.m_PendingPackets = new Queue(); if (ChannelBuffer.s_FreePackets == null) { ChannelBuffer.s_FreePackets = new List(); } } } // Token: 0x17000001 RID: 1 // (get) Token: 0x06000002 RID: 2 RVA: 0x00002104 File Offset: 0x00000304 // (set) Token: 0x06000003 RID: 3 RVA: 0x0000211E File Offset: 0x0000031E public int numMsgsOut { get; private set; } // Token: 0x17000002 RID: 2 // (get) Token: 0x06000004 RID: 4 RVA: 0x00002128 File Offset: 0x00000328 // (set) Token: 0x06000005 RID: 5 RVA: 0x00002142 File Offset: 0x00000342 public int numBufferedMsgsOut { get; private set; } // Token: 0x17000003 RID: 3 // (get) Token: 0x06000006 RID: 6 RVA: 0x0000214C File Offset: 0x0000034C // (set) Token: 0x06000007 RID: 7 RVA: 0x00002166 File Offset: 0x00000366 public int numBytesOut { get; private set; } // Token: 0x17000004 RID: 4 // (get) Token: 0x06000008 RID: 8 RVA: 0x00002170 File Offset: 0x00000370 // (set) Token: 0x06000009 RID: 9 RVA: 0x0000218A File Offset: 0x0000038A public int numMsgsIn { get; private set; } // Token: 0x17000005 RID: 5 // (get) Token: 0x0600000A RID: 10 RVA: 0x00002194 File Offset: 0x00000394 // (set) Token: 0x0600000B RID: 11 RVA: 0x000021AE File Offset: 0x000003AE public int numBytesIn { get; private set; } // Token: 0x17000006 RID: 6 // (get) Token: 0x0600000C RID: 12 RVA: 0x000021B8 File Offset: 0x000003B8 // (set) Token: 0x0600000D RID: 13 RVA: 0x000021D2 File Offset: 0x000003D2 public int numBufferedPerSecond { get; private set; } // Token: 0x17000007 RID: 7 // (get) Token: 0x0600000E RID: 14 RVA: 0x000021DC File Offset: 0x000003DC // (set) Token: 0x0600000F RID: 15 RVA: 0x000021F6 File Offset: 0x000003F6 public int lastBufferedPerSecond { get; private set; } // Token: 0x06000010 RID: 16 RVA: 0x000021FF File Offset: 0x000003FF public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } // Token: 0x06000011 RID: 17 RVA: 0x00002210 File Offset: 0x00000410 protected virtual void Dispose(bool disposing) { if (!this.m_Disposed) { if (disposing) { if (this.m_PendingPackets != null) { while (this.m_PendingPackets.Count > 0) { ChannelBuffer.pendingPacketCount--; ChannelPacket channelPacket = this.m_PendingPackets.Dequeue(); if (ChannelBuffer.s_FreePackets.Count < 512) { ChannelBuffer.s_FreePackets.Add(channelPacket); } } this.m_PendingPackets.Clear(); } } } this.m_Disposed = true; } // Token: 0x06000012 RID: 18 RVA: 0x000022A4 File Offset: 0x000004A4 public bool SetOption(ChannelOption option, int value) { bool flag; if (option != ChannelOption.MaxPendingBuffers) { if (option != ChannelOption.AllowFragmentation) { if (option != ChannelOption.MaxPacketSize) { flag = false; } else if (!this.m_CurrentPacket.IsEmpty() || this.m_PendingPackets.Count > 0) { if (LogFilter.logError) { Debug.LogError("Cannot set MaxPacketSize after sending data."); } flag = false; } else if (value <= 0) { if (LogFilter.logError) { Debug.LogError("Cannot set MaxPacketSize less than one."); } flag = false; } else if (value > this.m_MaxPacketSize) { if (LogFilter.logError) { Debug.LogError("Cannot set MaxPacketSize to greater than the existing maximum (" + this.m_MaxPacketSize + ")."); } flag = false; } else { this.m_CurrentPacket = new ChannelPacket(value, this.m_IsReliable); this.m_MaxPacketSize = value; flag = true; } } else { this.m_AllowFragmentation = value != 0; flag = true; } } else if (!this.m_IsReliable) { flag = false; } else if (value < 0 || value >= 512) { if (LogFilter.logError) { Debug.LogError(string.Concat(new object[] { "Invalid MaxPendingBuffers for channel ", this.m_ChannelId, ". Must be greater than zero and less than ", 512 })); } flag = false; } else { this.m_MaxPendingPacketCount = value; flag = true; } return flag; } // Token: 0x06000013 RID: 19 RVA: 0x00002430 File Offset: 0x00000630 public void CheckInternalBuffer() { if (Time.realtimeSinceStartup - this.m_LastFlushTime > this.maxDelay && !this.m_CurrentPacket.IsEmpty()) { this.SendInternalBuffer(); this.m_LastFlushTime = Time.realtimeSinceStartup; } if (Time.realtimeSinceStartup - this.m_LastBufferedMessageCountTimer > 1f) { this.lastBufferedPerSecond = this.numBufferedPerSecond; this.numBufferedPerSecond = 0; this.m_LastBufferedMessageCountTimer = Time.realtimeSinceStartup; } } // Token: 0x06000014 RID: 20 RVA: 0x000024B0 File Offset: 0x000006B0 public bool SendWriter(NetworkWriter writer) { return this.SendBytes(writer.AsArraySegment().Array, writer.AsArraySegment().Count); } // Token: 0x06000015 RID: 21 RVA: 0x000024E8 File Offset: 0x000006E8 public bool Send(short msgType, MessageBase msg) { ChannelBuffer.s_SendWriter.StartMessage(msgType); msg.Serialize(ChannelBuffer.s_SendWriter); ChannelBuffer.s_SendWriter.FinishMessage(); this.numMsgsOut++; return this.SendWriter(ChannelBuffer.s_SendWriter); } // Token: 0x06000016 RID: 22 RVA: 0x00002538 File Offset: 0x00000738 internal bool HandleFragment(NetworkReader reader) { bool flag; if (reader.ReadByte() == 0) { if (!this.readingFragment) { this.fragmentBuffer.SeekZero(); this.readingFragment = true; } byte[] array = reader.ReadBytesAndSize(); this.fragmentBuffer.WriteBytes(array, (ushort)array.Length); flag = false; } else { this.readingFragment = false; flag = true; } return flag; } // Token: 0x06000017 RID: 23 RVA: 0x000025A4 File Offset: 0x000007A4 internal bool SendFragmentBytes(byte[] bytes, int bytesToSend) { int num = 0; while (bytesToSend > 0) { int num2 = Math.Min(bytesToSend, this.m_MaxPacketSize - 32); byte[] array = new byte[num2]; Array.Copy(bytes, num, array, 0, num2); ChannelBuffer.s_FragmentWriter.StartMessage(17); ChannelBuffer.s_FragmentWriter.Write(0); ChannelBuffer.s_FragmentWriter.WriteBytesFull(array); ChannelBuffer.s_FragmentWriter.FinishMessage(); this.SendWriter(ChannelBuffer.s_FragmentWriter); num += num2; bytesToSend -= num2; } ChannelBuffer.s_FragmentWriter.StartMessage(17); ChannelBuffer.s_FragmentWriter.Write(1); ChannelBuffer.s_FragmentWriter.FinishMessage(); this.SendWriter(ChannelBuffer.s_FragmentWriter); return true; } // Token: 0x06000018 RID: 24 RVA: 0x0000265C File Offset: 0x0000085C internal bool SendBytes(byte[] bytes, int bytesToSend) { bool flag; if (bytesToSend >= 65535) { if (LogFilter.logError) { Debug.LogError("ChannelBuffer:SendBytes cannot send packet larger than " + ushort.MaxValue + " bytes"); } flag = false; } else if (bytesToSend <= 0) { if (LogFilter.logError) { Debug.LogError("ChannelBuffer:SendBytes cannot send zero bytes"); } flag = false; } else if (bytesToSend > this.m_MaxPacketSize) { if (this.m_AllowFragmentation) { flag = this.SendFragmentBytes(bytes, bytesToSend); } else { if (LogFilter.logError) { Debug.LogError(string.Concat(new object[] { "Failed to send big message of ", bytesToSend, " bytes. The maximum is ", this.m_MaxPacketSize, " bytes on channel:", this.m_ChannelId })); } flag = false; } } else if (!this.m_CurrentPacket.HasSpace(bytesToSend)) { if (this.m_IsReliable) { if (this.m_PendingPackets.Count == 0) { if (!this.m_CurrentPacket.SendToTransport(this.m_Connection, (int)this.m_ChannelId)) { this.QueuePacket(); } this.m_CurrentPacket.Write(bytes, bytesToSend); flag = true; } else if (this.m_PendingPackets.Count >= this.m_MaxPendingPacketCount) { if (!this.m_IsBroken) { if (LogFilter.logError) { Debug.LogError("ChannelBuffer buffer limit of " + this.m_PendingPackets.Count + " packets reached."); } } this.m_IsBroken = true; flag = false; } else { this.QueuePacket(); this.m_CurrentPacket.Write(bytes, bytesToSend); flag = true; } } else if (!this.m_CurrentPacket.SendToTransport(this.m_Connection, (int)this.m_ChannelId)) { if (LogFilter.logError) { Debug.Log("ChannelBuffer SendBytes no space on unreliable channel " + this.m_ChannelId); } flag = false; } else { this.m_CurrentPacket.Write(bytes, bytesToSend); flag = true; } } else { this.m_CurrentPacket.Write(bytes, bytesToSend); flag = this.maxDelay != 0f || this.SendInternalBuffer(); } return flag; } // Token: 0x06000019 RID: 25 RVA: 0x000028C7 File Offset: 0x00000AC7 private void QueuePacket() { ChannelBuffer.pendingPacketCount++; this.m_PendingPackets.Enqueue(this.m_CurrentPacket); this.m_CurrentPacket = this.AllocPacket(); } // Token: 0x0600001A RID: 26 RVA: 0x000028F4 File Offset: 0x00000AF4 private ChannelPacket AllocPacket() { ChannelPacket channelPacket; if (ChannelBuffer.s_FreePackets.Count == 0) { channelPacket = new ChannelPacket(this.m_MaxPacketSize, this.m_IsReliable); } else { ChannelPacket channelPacket2 = ChannelBuffer.s_FreePackets[ChannelBuffer.s_FreePackets.Count - 1]; ChannelBuffer.s_FreePackets.RemoveAt(ChannelBuffer.s_FreePackets.Count - 1); channelPacket2.Reset(); channelPacket = channelPacket2; } return channelPacket; } // Token: 0x0600001B RID: 27 RVA: 0x00002965 File Offset: 0x00000B65 private static void FreePacket(ChannelPacket packet) { if (ChannelBuffer.s_FreePackets.Count < 512) { ChannelBuffer.s_FreePackets.Add(packet); } } // Token: 0x0600001C RID: 28 RVA: 0x00002990 File Offset: 0x00000B90 public bool SendInternalBuffer() { bool flag; if (this.m_IsReliable && this.m_PendingPackets.Count > 0) { while (this.m_PendingPackets.Count > 0) { ChannelPacket channelPacket = this.m_PendingPackets.Dequeue(); if (!channelPacket.SendToTransport(this.m_Connection, (int)this.m_ChannelId)) { this.m_PendingPackets.Enqueue(channelPacket); break; } ChannelBuffer.pendingPacketCount--; ChannelBuffer.FreePacket(channelPacket); if (this.m_IsBroken && this.m_PendingPackets.Count < this.m_MaxPendingPacketCount / 2) { if (LogFilter.logWarn) { Debug.LogWarning("ChannelBuffer recovered from overflow but data was lost."); } this.m_IsBroken = false; } } flag = true; } else { flag = this.m_CurrentPacket.SendToTransport(this.m_Connection, (int)this.m_ChannelId); } return flag; } // Token: 0x04000001 RID: 1 private NetworkConnection m_Connection; // Token: 0x04000002 RID: 2 private ChannelPacket m_CurrentPacket; // Token: 0x04000003 RID: 3 private float m_LastFlushTime; // Token: 0x04000004 RID: 4 private byte m_ChannelId; // Token: 0x04000005 RID: 5 private int m_MaxPacketSize; // Token: 0x04000006 RID: 6 private bool m_IsReliable; // Token: 0x04000007 RID: 7 private bool m_AllowFragmentation; // Token: 0x04000008 RID: 8 private bool m_IsBroken; // Token: 0x04000009 RID: 9 private int m_MaxPendingPacketCount; // Token: 0x0400000A RID: 10 private const int k_MaxFreePacketCount = 512; // Token: 0x0400000B RID: 11 public const int MaxPendingPacketCount = 16; // Token: 0x0400000C RID: 12 public const int MaxBufferedPackets = 512; // Token: 0x0400000D RID: 13 private Queue m_PendingPackets; // Token: 0x0400000E RID: 14 private static List s_FreePackets; // Token: 0x0400000F RID: 15 internal static int pendingPacketCount; // Token: 0x04000010 RID: 16 public float maxDelay = 0.01f; // Token: 0x04000011 RID: 17 private float m_LastBufferedMessageCountTimer = Time.realtimeSinceStartup; // Token: 0x04000019 RID: 25 private static NetworkWriter s_SendWriter = new NetworkWriter(); // Token: 0x0400001A RID: 26 private static NetworkWriter s_FragmentWriter = new NetworkWriter(); // Token: 0x0400001B RID: 27 private const int k_PacketHeaderReserveSize = 100; // Token: 0x0400001C RID: 28 private bool m_Disposed; // Token: 0x0400001D RID: 29 internal NetBuffer fragmentBuffer = new NetBuffer(); // Token: 0x0400001E RID: 30 private bool readingFragment = false; } }