/// <summary>Used internally by the netcode to send unconnected messages.</summary> private async Task <int> SendAsync(PacketType type, IPEndPoint remote, IWritable message) { // Buffers allocated by the allocator byte[] compress = null; Writer writer = null; try { // Write message writer = new Writer(Allocator, 5); message?.Write(writer); ArraySegment <byte> packet = new ArraySegment <byte>(writer.Buffer, 5, writer.Position - 5); // Create flags PacketFlags flags = PacketFlags.None; // Compress if (Config.Compression) { int max = Compressor.MaxCompressedLength(packet.Count) + packet.Offset; compress = Allocator.CreateMessage(max); int len = Compressor.Compress(packet, compress, packet.Offset); if (len <= 0) { throw new InvalidOperationException(string.Format( "Compressing {0} bytes returned {1} bytes", packet.Count, len )); } else if (len < packet.Count) { packet = new ArraySegment <byte>(compress, packet.Offset, len); flags |= PacketFlags.Compressed; } } // Write CRC32 if (Config.CRC32) { uint crc32 = CRC32.Compute(packet.Array, packet.Offset, packet.Count); Serializer.Write32(packet.Array, packet.Offset - 4, crc32); packet = new ArraySegment <byte>(packet.Array, packet.Offset - 4, packet.Count + 4); flags |= PacketFlags.Verified; } // Write header packet.Array[packet.Offset - 1] = (byte)(((byte)type) | ((byte)flags)); packet = new ArraySegment <byte>(packet.Array, packet.Offset - 1, packet.Count + 1); // Send return(await SendSocketAsync(remote, packet.Array, packet.Offset, packet.Count)); } catch (Exception exception) { // Notify listener about the exception Listener.OnHostException(remote, exception); throw; } finally { // Return the allocated buffers back to the allocator writer?.Dispose(); Allocator.ReturnMessage(ref compress); } }