/// <summary> /// Send the specified packet. Marks the buffer as used. /// </summary> public void SendTcpPacket(Buffer buffer) { buffer.MarkAsUsed(); BinaryReader reader = buffer.BeginReading(); #if DEBUG_PACKETS && !STANDALONE Packet packet = (Packet)buffer.PeekByte(4); if (packet != Packet.RequestPing && packet != Packet.ResponsePing) { UnityEngine.Debug.Log("Sending: " + packet + " to " + name + " (" + (buffer.size - 5).ToString("N0") + " bytes)"); } #endif if (mSocket != null && mSocket.Connected) { lock (mOut) { mOut.Enqueue(buffer); // If it's the first packet, let's begin the send process if (mOut.Count == 1) { try { #if !UNITY_WINRT mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer); #endif } catch (System.Exception ex) { mOut.Clear(); buffer.Recycle(); RespondWithError(ex); CloseNotThreadSafe(false); } } } return; } if (sendQueue != null) { if (buffer.position != 0) { // Offline mode sends packets individually and they should not be reused #if UNITY_EDITOR Debug.LogWarning("Packet's position is " + buffer.position + " instead of 0. Potentially sending the same packet more than once. Ignoring..."); #endif return; } // Skip the packet's size int size = reader.ReadInt32(); if (size == buffer.size) { // Note that after this the buffer can no longer be used again as its offset is +4 lock (sendQueue) sendQueue.Enqueue(buffer); return; } // Multi-part packet -- split it up into separate ones lock (sendQueue) { for (;;) { byte[] bytes = reader.ReadBytes(size); Buffer temp = Buffer.Create(); BinaryWriter writer = temp.BeginWriting(); writer.Write(size); writer.Write(bytes); temp.BeginReading(4); temp.EndWriting(); sendQueue.Enqueue(temp); if (buffer.size > 0) { size = reader.ReadInt32(); } else { break; } } } } buffer.Recycle(); }
/// <summary> /// Send the specified packet. Marks the buffer as used. /// </summary> public void SendTcpPacket(Buffer buffer, bool instant = false) { #if !MODDING buffer.MarkAsUsed(); var reader = buffer.BeginReading(); if (buffer.size == 0) { #if UNITY_EDITOR Debug.LogError("Trying to send a zero packet! " + buffer.position + " " + buffer.isWriting + " " + id); #endif buffer.Recycle(); return; } #if DEBUG_PACKETS && !STANDALONE var packet = (Packet)buffer.PeekByte(4); if (packet != Packet.RequestPing && packet != Packet.ResponsePing) { UnityEngine.Debug.Log("Sending: " + packet + " to " + name + " (" + (buffer.size - 5).ToString("N0") + " bytes)"); } #endif if (custom != null) { if (!custom.SendPacket(buffer)) { buffer.Recycle(); Disconnect(); } else { buffer.Recycle(); } return; } if (mSocket != null && mSocket.Connected) { lock (mOut) { #if UNITY_WINRT mSocket.Send(buffer.buffer, buffer.size, SocketFlags.None); #else if (instant) { try { var before = mSocket.NoDelay; if (!before) { mSocket.NoDelay = true; } mSocket.Send(buffer.buffer, buffer.position, buffer.size, SocketFlags.None); if (!before) { mSocket.NoDelay = false; } buffer.Recycle(); return; } catch { } } if (mSending) { // Simply add this packet to the outgoing queue mOut.Enqueue(buffer); } else { // If it's the first packet, let's begin the send process mSending = true; try { mSocket.BeginSend(buffer.buffer, buffer.position, buffer.size, SocketFlags.None, OnSend, buffer); } catch (System.Exception ex) { mOut.Clear(); buffer.Recycle(); AddError(ex); CloseNotThreadSafe(false); mSending = false; } } #endif } return; } if (sendQueue != null) { if (buffer.position != 0) { // Offline mode sends packets individually and they should not be reused #if UNITY_EDITOR Debug.LogWarning("Packet's position is " + buffer.position + " instead of 0. Potentially sending the same packet more than once. Ignoring..."); #endif return; } // Skip the packet's size int size = reader.ReadInt32(); if (size == buffer.size) { lock (sendQueue) sendQueue.Enqueue(buffer); return; } // Multi-part packet -- split it up into separate ones lock (sendQueue) { for (;;) { var bytes = reader.ReadBytes(size); var temp = Buffer.Create(); var writer = temp.BeginWriting(); writer.Write(size); writer.Write(bytes); temp.BeginReading(4); sendQueue.Enqueue(temp); if (buffer.size > 0) { size = reader.ReadInt32(); } else { break; } } } } #endif buffer.Recycle(); }