private void RemoteRead(IAsyncResult ar) { NetworkStream stream = (ar.AsyncState as Tuple <NetworkStream, PacketBuffer>).Item1; PacketBuffer buffer = (ar.AsyncState as Tuple <NetworkStream, PacketBuffer>).Item2; bool isClient = stream == _clientStream; RC4Cipher cipher = isClient ? _clientReceiveState : _serverReceiveState; bool success = PluginUtils.ProtectedInvoke(() => { if (!stream.CanRead) { return; } int read = stream.EndRead(ar); buffer.Advance(read); if (read == 0) { Dispose(); return; } else if (buffer.Index == 4) { // We have the first four bytes, resize the client buffer buffer.Resize(IPAddress.NetworkToHostOrder( BitConverter.ToInt32(buffer.Bytes, 0))); BeginRead(buffer.Index, buffer.BytesRemaining(), isClient); } else if (buffer.BytesRemaining() > 0) { // Awaiting the rest of the packet BeginRead(buffer.Index, buffer.BytesRemaining(), isClient); } else { // We have the full packet cipher.Cipher(buffer.Bytes); Packet packet = Packet.Create(buffer.Bytes); if (isClient) { _proxy.FireClientPacket(this, packet); } else { _proxy.FireServerPacket(this, packet); } if (packet.Send) { Send(packet, !isClient); } buffer.Reset(); BeginRead(0, 4, isClient); } }, "RemoteRead (isClient = " + isClient + ")", typeof(IOException)); if (!success) { Dispose(); } }