Example #1
0
        public void SendPacket(ushort type, byte[] data)
        {
            if (_connected == 0)
            {
                throw new Exception();
            }

            _sendLock.Wait(); try {
                if (_sent == 0 && _encrypted && _sending == 0 /* if sending we've already done this */)
                {
                    Random random = new Random();

                    _sendBuffer[_sendOffset++] = 0x0B;

                    int prefix = random.Next() % 64;
                    for (int i = 0; i < prefix; i++)
                    {
                        _sendBuffer[_sendOffset++] = (byte)(random.Next() % 256);
                    }
                    _sendBuffer[_sendOffset++] = 0xFF;

                    for (int i = 0; i < 16; i++)
                    {
                        _sendBuffer[_sendOffset++] = (byte)(random.Next() % 256);
                    }

                    byte[] seed = new byte[16];
                    Array.Copy(_sendBuffer, _sendOffset - 16, seed, 0, 16);

                    Console.WriteLine("send seed {0} for {1} --> {2}", Formatter.FormatKey(seed), _socket.LocalEndPoint, _socket.RemoteEndPoint);

                    int length = prefix + 1 + 16;
                    _sendCrypt.Process(_sendBuffer, _sendOffset - length, length);

                    _sendCrypt.SetSeed(seed);
                }

                if (_sendBuffer.Length - _sendOffset < 4 + data.Length)
                {
                    throw new Exception();                                                              // TODO: fix me
                }
                _sendCrypt.Process(BitConverter.GetBytes(type), 0, _sendBuffer, _sendOffset, sizeof(ushort));
                _sendOffset += 2;
                _sendCrypt.Process(BitConverter.GetBytes((ushort)data.Length), 0, _sendBuffer, _sendOffset, sizeof(ushort));
                _sendOffset += 2;
                _sendCrypt.Process(data, 0, _sendBuffer, _sendOffset, data.Length);
                _sendOffset += data.Length;

                if (Interlocked.CompareExchange(ref _sending, 1, 0) == 0)
                {
                    _sendArgs.SetBuffer(_sendBuffer, 0, _sendOffset);
                    if (!_socket.SendAsync(_sendArgs))
                    {
                        Task.Run(() => { ProcessSend(_socket, _sendArgs); });
                    }
                }
            } finally { _sendLock.Release(); }
        }
Example #2
0
        void ProcessReceive(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError != SocketError.Success || e.BytesTransferred <= 0)
            {
                Disconnect(); return;
            }

            int received = e.BytesTransferred;
            int offset   = _recvOffset;

            _recvOffset += received;

            if (_received == 0 && _recvBuffer[offset] == 0x0B)
            {
                if (!_encrypted)
                {
                    _encrypted = true;
                    InitializeCrypts();
                }

                offset++;
            }

            if (_encrypted && _recvCryptSeedCount < 16)
            {
                while (_recvCryptSeedCount == -1 && offset < _recvOffset)
                {
                    _recvCrypt.Process(_recvBuffer, offset, 1);
                    if (_recvBuffer[offset++] == 0xFF)
                    {
                        _recvCryptSeedCount = 0;
                    }
                }

                if (_recvCryptSeedCount < 16 && offset < _recvOffset)
                {
                    int count = Math.Min(_recvOffset - offset, 16 - _recvCryptSeedCount);
                    _recvCrypt.Process(_recvBuffer, offset, count);
                    _recvCryptSeedCount += count; offset += count;
                }

                if (_recvCryptSeedCount < 16)
                {
                    _received += received;
                    e.SetBuffer(_recvOffset, _recvBuffer.Length - _recvOffset);
                    if (!_socket.ReceiveAsync(_recvArgs))
                    {
                        Task.Run(() => { ProcessReceive(_socket, _recvArgs); });
                    }
                    return;
                }

                Console.WriteLine("recv seed {0} for {1} <-- {2}", Formatter.FormatKey(_recvBuffer, offset - 16, 16), _socket.LocalEndPoint, _socket.RemoteEndPoint);

                _recvCrypt.SetSeed(_recvBuffer, offset - 16);
                _recvOffset -= offset;
                Array.Copy(_recvBuffer, offset, _recvBuffer, 0, _recvOffset);
                offset = 0;
            }

            _recvCrypt.Process(_recvBuffer, offset, _recvOffset - offset);
            offset = 0;

            while (_recvOffset - offset >= 4)
            {
                ushort packetType   = BitConverter.ToUInt16(_recvBuffer, offset);
                ushort packetLength = BitConverter.ToUInt16(_recvBuffer, offset + 2);
                if (_recvOffset - offset < 4 + packetLength)
                {
                    break;
                }
                OnPacket(new PacketEventArgs(_recvBuffer, offset, 4 + packetLength));
                offset += 4 + packetLength;
            }

            _recvOffset -= offset;
            Array.Copy(_recvBuffer, offset, _recvBuffer, 0, _recvOffset);

            _received += received;
            e.SetBuffer(_recvOffset, _recvBuffer.Length - _recvOffset);
            if (!_socket.ReceiveAsync(_recvArgs))
            {
                Task.Run(() => { ProcessReceive(_socket, _recvArgs); });
            }
        }