public NetworkStream(Connection Connection, Action <NetworkStream> StreamCallback)
 {
     this.connection     = Connection;
     this.Buffer         = new byte[0];
     this.StreamCallback = StreamCallback;
     this.NetworkPayload = new NetworkPayload(Connection, null);
 }
        internal SyncObject Receive(ReceiveCallback callback)
        {
            lock (Handle)
            {
                if (callback == null)
                {
                    throw new ArgumentNullException("callback");
                }

                if (!Connected)
                {
                    return(null);
                }

                SyncObject     syncObject     = new SyncObject(this);
                NetworkPayload networkPayload = new NetworkPayload(this, syncObject, callback);
                SocketError    error          = SocketError.AccessDenied;
                Handle.BeginReceive(networkPayload.Payload, 0, (int)networkPayload.PacketSize, SocketFlags.None, out error, ReceivePayloadCallback, networkPayload);
                return(syncObject);
            }
        }
        private void ReceivePayloadCallback(IAsyncResult ar)
        {
            NetworkPayload networkPayload = (NetworkPayload)ar.AsyncState;
            SocketError    error          = SocketError.AccessDenied;
            int            received       = 0;

            try
            {
                //even tho there is "out error" it can still throw a error
                received = Handle.EndReceive(ar, out error);
            }
            catch { }

            if (received <= 0 || error != SocketError.Success)
            {
                Client.Disconnect(DisconnectReason.UnexpectedlyDisconnected);
                return;
            }

            BytesIn          += (ulong)received;
            this.LastPacketSW = Stopwatch.StartNew();

            networkPayload.WriteOffset += (uint)received;
            if (networkPayload.WriteOffset == networkPayload.PacketSize && networkPayload.ReceivedHeader)
            {
                uint Offset = 0;
                uint length = (uint)networkPayload.Payload.Length;

                //let's check the payload hash
                if (networkPayload.Header.Hash != networkPayload.Header.HashPayload(networkPayload.Payload, (int)Offset, (int)length, HandshakeChecksum))
                {
                    Client.Disconnect(DisconnectReason.DataModificationDetected);
                    return;
                }

                //decrypt, decompress, de-cache the data we received
                networkPayload.Payload = protection.RemoveProtection(networkPayload.Payload, ref Offset, ref length, ref networkPayload.Header);

                IMessage message = null;

                try
                {
                    message = messageHandler.HandleMessage(new PayloadReader(networkPayload.Payload), networkPayload.Header.MessageId);
                }
                catch
                {
                }

                networkPayload.syncObject.Value = networkPayload.Callback(message);
                networkPayload.syncObject.Pulse();
                return; //no need to read futher
            }

            if (!networkPayload.ReceivedHeader && networkPayload.ReceivedPacket)
            {
                try
                {
                    networkPayload.ReceivedHeader = true;
                    //wopEncryption.Decrypt(networkPayload.Payload, 0, HEADER_SIZE);
                    networkPayload.Header = new PacketHeader(networkPayload.Payload, 0, this);

                    if (!DPI.Inspect(networkPayload.Header))
                    {
                        Client.Disconnect(DisconnectReason.DeepPacketInspectionDisconnection);
                        return;
                    }

                    networkPayload.PacketSize  = networkPayload.Header.PacketSize;
                    networkPayload.Payload     = new byte[networkPayload.Header.PacketSize];
                    networkPayload.WriteOffset = 0; //just reset offset for reading
                }
                catch
                {
                    Client.Disconnect(DisconnectReason.UnexpectedlyDisconnected);
                    return;
                }
            }

            if (networkPayload.WriteOffset != networkPayload.PacketSize)
            {
                Handle.BeginReceive(networkPayload.Payload, (int)networkPayload.WriteOffset, (int)(networkPayload.PacketSize - networkPayload.WriteOffset), SocketFlags.None, out error, ReceivePayloadCallback, networkPayload);
            }
        }
 public OptimizedNetworkStream(Connection Connection, Action <OptimizedNetworkStream> StreamCallback)
 {
     this.Buffer         = new byte[DefaultSize];
     this.StreamCallback = StreamCallback;
     this.NetworkPayload = new NetworkPayload(Connection, null);
 }