public void TestInt()
        {
            var value = 21;
            var bytes = BitConverter.GetBytes(value);
            var queue = new ByteQueue();

            // Enqueue first two bytes of int
            var buffer = new byte[2];

            Array.Copy(bytes, 0, buffer, 0, 2);
            queue.Enqueue(buffer);

            Assert.IsTrue(queue.HasBytes(2));
            Assert.IsFalse(queue.HasBytes(3));

            Assert.IsNull(queue.Dequeue());

            // Enqueue last two bytes of int
            buffer = new byte[2];
            Array.Copy(bytes, 2, buffer, 0, 2);
            queue.Enqueue(buffer);

            Assert.IsTrue(queue.HasBytes(4));
            Assert.IsFalse(queue.HasBytes(5));

            var dequeuedValue = queue.Dequeue();

            Assert.AreEqual(value, dequeuedValue.Value);
            Assert.IsFalse(queue.HasBytes(1));
        }
예제 #2
0
        public void TestReadAfterCapacityChanged()
        {
            ByteQueue queue    = new ByteQueue(20);
            int       capacity = queue.Capacity;

            byte[] input = Encoding.ASCII.GetBytes("hello world!");

            // Write then read so the read head != 0.

            queue.Enqueue(input, 0, input.Length);

            byte[] output = new byte[input.Length];
            queue.Dequeue(output, 0, output.Length);

            // Write until the capacity changes.

            while (queue.Capacity == capacity)
            {
                queue.Enqueue(input, 0, input.Length);
            }

            queue.Dequeue(output, 0, output.Length);

            Assert.AreEqual(Encoding.ASCII.GetString(input), Encoding.ASCII.GetString(output));
        }
예제 #3
0
        public RecordLayer.Record FromByteQueue(ByteQueue queue)
        {
            if (queue.Length == 0)
            {
                return(null);
            }
            else
            {
                if (queue.Length >= 5)
                {
                    byte[] recordHeader = queue.Peek(5);

                    ProtoType       recordType = (ProtoType)recordHeader[0];
                    ProtocolVersion version    = new ProtocolVersion(recordHeader[1], recordHeader[2]);
                    /* TODO: Check for the right version */

                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(recordHeader, 3, 2);
                    }
                    int payloadLength = BitConverter.ToUInt16(recordHeader, 3);

                    if (queue.Length < payloadLength)
                    {
                        throw new SslInsufficientReceiveException();
                    }
                    queue.Dequeue(5); // discard header
                    return(new RecordLayer.Record(queue.Dequeue(payloadLength), recordType, version));
                }
                else
                {
                    throw new SslInsufficientReceiveException();
                }
            }
        }
예제 #4
0
        public int RecvPartial(byte[] buffer, int offset, int length, bool waitForSomeData)
        {
            if (!Connected)
            {
                return(-1);
            }
            if (StreamDataEvent != null)
            {
                throw new UserFriendlyException("Tried to RecvPartial() data from IGE.Net.RawClient while it has a StreamDataEvent attached. You cannot use both blocking and asynchronous receiving at the same time.", "Connection error");
            }
            if (Thread.CurrentThread == m_ReceiverThread)
            {
                throw new UserFriendlyException("Tried to use RecvPartial() within receiver thread. This would lock the thread.", "Connection error");
            }
            int received = 0;

            lock (SyncRecv) {
                while (length > 0)
                {
                    if (waitForSomeData)
                    {
                        try { WaitRecvReady(); }
                        catch {
                            Log(LogLevel.Debug, "RecvPartial interrupted");
                            return(-1);
                        }
                    }

                    lock (m_Input) {
                        received = Math.Min(length, m_Input.Length);
                        if (received > 0)
                        {
                            m_Input.Dequeue(buffer, offset, received);
                            if (m_Input.Length == 0)
                            {
                                m_InputReady.Reset();
                                m_InputEmpty.Set();
                                m_InputAccepts.Set();
                            }
                            else if (m_Input.Length < MaxRecvBufferSize)
                            {
                                m_InputAccepts.Set();
                            }
                            Log(LogLevel.Debug, "RecvPartial dequeued {0} bytes (total buffered {1} bytes)", received, m_Input.Length);
                            break;
                        }
                        if (!waitForSomeData)
                        {
                            break;
                        }
                    }
                }
            }
            return(received);
        }
예제 #5
0
        private byte[] GetBufferToBeRead(int length)
        {
            int availableData = _fragPackets.Size + _readingBufferQueue.Size;

            if (length > availableData)
            {
                return(null);
            }

            int fromFrag;

            byte[] data = new byte[length];

            if (length >= _fragPackets.Size)
            {
                fromFrag = _fragPackets.Size;
            }
            else
            {
                fromFrag = length;
            }

            _fragPackets.Dequeue(data, 0, fromFrag);

            int fromProcessed = length - fromFrag;

            _readingBufferQueue.Dequeue(data, fromFrag, fromProcessed);

            return(data);
        }
예제 #6
0
        /// <summary>
        /// Read a byte.
        /// </summary>
        /// <returns>-1 if no data, else the first byte available.</returns>
        public int read()
        {
            Thread.Yield();

            int result = -1;

            byte[] buffer = new byte[1];
            if (_receiveQueue.Length > 0)
            {
                if (_receiveQueue.Dequeue(buffer, 0, 1) == 1)
                {
                    result = buffer[0];
                }
            }

            return(result);
        }
예제 #7
0
        public void TestWriteThenReadWithWrapAround()
        {
            ByteQueue queue = new ByteQueue(10);

            byte[] input = Encoding.ASCII.GetBytes("123456");
            queue.Enqueue(input, 0, input.Length);

            byte[] output = new byte[input.Length];
            queue.Dequeue(output, 0, output.Length);

            queue.Enqueue(input, 0, input.Length);

            Array.Clear(output, 0, output.Length);

            queue.Dequeue(output, 0, output.Length);

            Assert.AreEqual(Encoding.ASCII.GetString(input), Encoding.ASCII.GetString(output));
        }
예제 #8
0
        public void TestWriteThenRead()
        {
            ByteQueue queue = new ByteQueue();

            byte[] input = Encoding.ASCII.GetBytes("hello world!");
            queue.Enqueue(input, 0, input.Length);

            byte[] output = new byte[input.Length];
            queue.Dequeue(output, 0, output.Length);

            Assert.AreEqual(Encoding.ASCII.GetString(input), Encoding.ASCII.GetString(output));
        }
예제 #9
0
        /// <summary>
        /// Read a number of bytes and store in a buffer.
        /// </summary>
        /// <param name="buf">buffer to write to.</param>
        /// <param name="bytes">number of bytes to read.</param>
        /// <returns>-1 if no data or number of read bytes.</returns>
        public int read(ref byte[] buf, uint bytes)
        {
            Thread.Yield();

            int result = -1;
            int length = _receiveQueue.Length;

            length = bytes > length ? length : (int)bytes;
            if (length > 0)
            {
                result = _receiveQueue.Dequeue(buf, 0, length);
            }

            return(result);
        }
        public void TestBytes()
        {
            var value = "TestStringBytes";
            var bytes = Encoding.UTF8.GetBytes(value);
            var queue = new ByteQueue();

            queue.Enqueue(bytes);

            Assert.IsTrue(queue.HasBytes(bytes.Length));
            Assert.IsFalse(queue.HasBytes(bytes.Length + 1));

            var dequeuedBytes = queue.Dequeue(bytes.Length);
            var dequeuedValue = Encoding.UTF8.GetString(dequeuedBytes);

            Assert.AreEqual(value, dequeuedValue);
        }
예제 #11
0
        private void Send()
        {
            while (true)
            {
                if (ByteQueue.Any())
                {
                    try
                    {
                        string      strMsg = this.txt_Msg.Text.Trim();
                        byte[]      buffer = Encoding.Default.GetBytes(strMsg);
                        List <byte> list   = new List <byte>();
                        list.Add(0);
                        list.AddRange(buffer);
                        //将泛型集合转换为数组
                        byte[] newBuffer = list.ToArray();
                        //获得用户选择的IP地址

                        //var mess = new byte[] { 0xff, 0x08, 0x07 };
                        //= @"FF 08 07";
                        var mess = DivisionHEX(txt_Msg.Text).TrimEnd();

                        //var strings = mess.Split(' ');
                        //var bytes = Array.ConvertAll(strings, input => Convert.ToByte(input, 16));
                        var bytes = ByteQueue.Dequeue();
                        foreach (var ip in dicPCSocket.Keys)
                        {
                            try
                            {
                                dicPCSocket[ip].Send(bytes);
                            }
                            catch (Exception ex)
                            { };
                        }
                        txt_Log.Invoke(receiveCallBack, $"发送成功");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("给客户端发送消息出错:" + ex.Message);
                    }
                }
                else
                {
                    Thread.Sleep(1);
                }
            }
        }
        internal int CheckQueues(Bus bus)
        {
            ByteQueue sendQueue = bus.GetSendQueue();

            if (sendQueue.Length > 0)
            {
                byte[] dataToSend = sendQueue.Dequeue(sendQueue.Length);
                Send(m_SecureSocket.InternalSocket, dataToSend);
            }
            ByteQueue userQueue = bus.GetUserQueue();

            if (userQueue.Length > 0)
            {
                int    length = Math.Min(m_Count, userQueue.Length);
                byte[] data   = userQueue.Dequeue(length);
                System.Buffer.BlockCopy(data, 0, m_Buffer, m_Offset, length);
                return(length);
            }
            return(0);
        }
예제 #13
0
        /// <inheritdoc/>
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            var read = 0;

            while (read < count && !cancellationToken.IsCancellationRequested)
            {
                if (!EndOfStream)
                {
                    await _readerEvent.WaitAsync(cancellationToken);
                }

                var bytesDequeued = _reader.Dequeue(buffer, offset + read, count - read);
                read += bytesDequeued;

                if (bytesDequeued == 0 && EndOfStream)
                {
                    break;
                }
            }

            return(read);
        }
예제 #14
0
 public int endPacket()
 {
     byte[] buffer = new byte[_sendQueue.Length];
     _sendQueue.Dequeue(buffer, 0, _sendQueue.Length);
     return(_client.Send(buffer, buffer.Length, _packetEndpoint));
 }
예제 #15
0
        private void SenderThread(object param)
        {
            Socket       socket = (Socket)param;
            IAsyncResult async;

            byte[] buffer;
            int    sent, offset, length;
            bool   keepRunning = true;

            Log(LogLevel.Debug, "SenderThread: started");
            try {
                while (socket.Connected)
                {
                    keepRunning = keepRunning && KeepRunning;
                    try {
                        if (keepRunning)
                        {
                            Log(LogLevel.Debug, "SenderThread: waiting for data");
                            m_OutputReady.WaitOne();
                        }
                    }
                    catch (ThreadInterruptedException) {
                        Log(LogLevel.Debug, "SenderThread: interrupted while waiting for data");
                        keepRunning = false;
                    }

                    if (!socket.Connected)
                    {
                        Log(LogLevel.Debug, "SenderThread: socket was closed while waiting for data");
                        break;
                    }

                    lock (m_Output) {
                        if (m_Output.Length == 0)
                        {
                            Log(LogLevel.Debug, "SenderThread: seems i was interrupted");
                            if (keepRunning)
                            {
                                continue;
                            }
                            Log(LogLevel.Debug, "SenderThread: got signal to stop so quitting");
                            break;
                        }
                        buffer = m_Output.Dequeue(m_Output.Length);
                        m_OutputReady.Reset();
                        m_OutputEmpty.Set();
                        m_OutputAccepts.Set();
                        Log(LogLevel.Debug, "SenderThread: read {0} bytes from the queue", buffer.Length);
                    }

                    length = buffer.Length;
                    offset = 0;
                    while (offset < length && socket.Connected)
                    {
                        Log(LogLevel.Debug, "SenderThread: beginning to send");
                        async = socket.BeginSend(buffer, offset, length - offset, SocketFlags.None, null, null);
                        try {
                            async.AsyncWaitHandle.WaitOne(1000);
                        }
                        catch (ThreadInterruptedException) {
                            Log(LogLevel.Debug, "SenderThread: interrupted while sending");
                            keepRunning = false;
                        }
                        sent = socket.EndSend(async);
                        Log(LogLevel.Debug, "SenderThread: sent {0} bytes", sent);
                        //sent = socket.Send(buffer, offset, length - offset, SocketFlags.None);
                        if (sent > 0)
                        {
                            offset += sent;
                        }
                    }
                    buffer = null;
                }
                Log(LogLevel.Debug, "SenderThread: end loop");
            }
            catch (Exception ex) {
                Log(LogLevel.Debug, "SenderThread exception: {0}", ex);
            }
            if (KeepRunning)
            {
                Log(LogLevel.Debug, "SenderThread: doing internal disconnect");
                DisconnectInternal(m_SenderThread);
            }
            Log(LogLevel.Debug, "SenderThread: ended");
        }
예제 #16
0
        // Try to decrypt incoming data.
        public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length)
        {
            #region m_Encryption != null
            if (m_Encryption != null)
            {
                // If we're decrypting using LoginCrypt and we've already been relayed,
                // only decrypt a single packet using logincrypt and then disable it
                if (m_AlreadyRelayed && m_Encryption is LoginEncryption)
                {
                    uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2);

                    // Swap the seed
                    newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000);

                    // XOR it with the old seed
                    newSeed ^= m_Seed;

                    IClientEncryption newEncryption = new GameEncryption(newSeed);

                    // Game Encryption comes first
                    newEncryption.clientDecrypt(ref buffer, length);

                    // The login encryption is still used for this one packet
                    m_Encryption.clientDecrypt(ref buffer, length);

                    // Swap the encryption schemes
                    m_Encryption = newEncryption;
                    m_Seed       = newSeed;

                    return;
                }

                m_Encryption.clientDecrypt(ref buffer, length);
                return;
            }
            #endregion

            #region Port Scan
            //11JUN2008 RunUO SVN fix ** START ***
            // If the client did not connect on the game server port,
            // it's not our business to handle encryption for it
            //if (((IPEndPoint)from.Socket.LocalEndPoint).Port != Listener.Port)
            //{
            //    m_Encryption = new NoEncryption();
            //    return;
            //}
            bool handle = false;

            for (int i = 0; i < Listener.EndPoints.Length; i++)
            {
                IPEndPoint ipep = (IPEndPoint)Listener.EndPoints[i];

                if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port)
                {
                    handle = true;
                }
            }

            if (!handle)
            {
                m_Encryption = new NoEncryption();
                return;
            }
            //11JUN2008 RunUO SVN fix ** END ***
            #endregion

            #region !m_Seeded
            // For simplicities sake, enqueue what we just received as long as we're not initialized
            m_Buffer.Enqueue(buffer, 0, length);
            // Clear the array
            length = 0;

            // If we didn't receive the seed yet, queue data until we can read the seed
            //if (!m_Seeded)
            //{
            //    // Now check if we have at least 4 bytes to get the seed
            //    if (m_Buffer.Length >= 4)
            //    {
            //        byte[] m_Peek = new byte[m_Buffer.Length];
            //        m_Buffer.Dequeue( m_Peek, 0, m_Buffer.Length ); // Dequeue everything
            //        m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
            //        m_Seeded = true;

            //        Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4);
            //        length = 4;
            //    }
            //    else
            //    {
            //        return;
            //    }
            //}
            //http://uodev.de/viewtopic.php?t=5097&postdays=0&postorder=asc&start=15&sid=dfb8e6c73b9e3eb95c1634ca3586e8a7
            //if (!m_Seeded)
            //{
            //    int seed_length = m_Buffer.GetSeedLength();

            //    if (m_Buffer.Length >= seed_length)
            //    {
            //        byte[] m_Peek = new byte[m_Buffer.Length];
            //        m_Buffer.Dequeue(m_Peek, 0, seed_length);

            //        if (seed_length == 4)
            //            m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
            //        else if (seed_length == 21)
            //            m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);

            //        m_Seeded = true;

            //        Buffer.BlockCopy(m_Peek, 0, buffer, 0, seed_length);
            //        length = seed_length;
            //    }
            //    else
            //    {
            //        return;
            //    }
            //}

            //11JUN2008 My Version

            if (!m_Seeded)
            {
                if (m_Buffer.Length <= 3) //Short Length, try again.
                {
                    Console.WriteLine("Encryption: Failed - Short Lenght");
                    return;
                }
                //else if ((m_Buffer.Length == 83) && (m_Buffer.GetPacketID() == 239)) //New Client
                //{
                //    byte[] m_Peek = new byte[21];
                //    m_Buffer.Dequeue(m_Peek, 0, 21);

                //    m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);
                //    m_Seeded = true;

                //    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21);
                //    length = 21;

                //    Console.WriteLine("Encryption: Passed - New Client");
                //}

                //05MAR2009 Smjert's fix for double log in.  *** START ***
                else if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239)) //New Client
                {
                    length = m_Buffer.Length;
                    byte[] m_Peek = new byte[21];
                    m_Buffer.Dequeue(m_Peek, 0, 21);

                    m_Seed   = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21);


                    Console.WriteLine("Encryption: Passed - New Client");

                    // We need to wait the next packet
                    if (length == 21)
                    {
                        return;
                    }

                    length = 21;
                }

                else if (m_Buffer.Length >= 4) //Old Client
                //05MAR2009 Smjert's fix for double log in.  *** END ***
                {
                    byte[] m_Peek = new byte[4];
                    m_Buffer.Dequeue(m_Peek, 0, 4);

                    m_Seed   = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4);
                    length = 4;

                    Console.WriteLine("Encryption: Passed - Old Client");
                }
                else //It should never reach here.
                {
                    Console.WriteLine("Encryption: Failed - It should never reach here");
                    return;
                }
            }
            #endregion

            // If the context isn't initialized yet, that means we haven't decided on an encryption method yet
            #region m_Encryption == null
            if (m_Encryption == null)
            {
                int packetLength = m_Buffer.Length;
                int packetOffset = length;
                m_Buffer.Dequeue(buffer, length, packetLength); // Dequeue everything
                length += packetLength;

                // This is special handling for the "special" UOG packet
                if (packetLength >= 3)
                {
                    if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF))
                    {
                        m_Encryption = new NoEncryption();
                        return;
                    }
                }

                // Check if the current buffer contains a valid login packet (62 byte + 4 byte header)
                // Please note that the client sends these in two chunks. One 4 byte and one 62 byte.
                if (packetLength == 62)
                {
                    Console.WriteLine("Checking packetLength 62 == " + packetLength);
                    // Check certain indices in the array to see if the given data is unencrypted
                    if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00)
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                            return;
                        }
                    }
                    else
                    {
                        LoginEncryption encryption = new LoginEncryption();
                        if (encryption.init(m_Seed, buffer, packetOffset, packetLength))
                        {
                            Console.WriteLine("Client: {0}: Encrypted client detected, using keys of client {1}", from, encryption.Name);
                            m_Encryption = encryption;
                            Console.WriteLine("Encryption: Check 1");
                            byte[] packet = new byte[packetLength];
                            Console.WriteLine("Encryption: Check 2");
                            Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                            Console.WriteLine("Encryption: Check 3");
                            encryption.clientDecrypt(ref packet, packet.Length);
                            Console.WriteLine("Encryption: Check 4");
                            Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                            Console.WriteLine("Encryption: Check 5");
                            //return; //Just throwing this in.
                        }
                        else
                        {
                            Console.WriteLine("Detected an unknown client.");
                        }
                    }
                }
                else if (packetLength == 65)
                {
                    Console.WriteLine("Checking packetLength 65 == " + packetLength);
                    // If its unencrypted, use the NoEncryption class
                    if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF))
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                        }
                    }
                    else
                    {
                        // If it's not an unencrypted packet, simply assume it's encrypted with the seed
                        m_Encryption = new GameEncryption(m_Seed);

                        byte[] packet = new byte[packetLength];
                        Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                        m_Encryption.clientDecrypt(ref packet, packet.Length);
                        Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                    }
                }

                // If it's still not initialized, copy the data back to the queue and wait for more
                if (m_Encryption == null)
                {
                    Console.WriteLine("Encryption: Check - Waiting");
                    m_Buffer.Enqueue(buffer, packetOffset, packetLength);
                    length -= packetLength;
                    return;
                }
            }
            #endregion
        }
예제 #17
0
        internal void Send_Start()
        {
            if (!Running || !_socket.Connected)
            {
                DisposeSendSystem();
                return;
            }

            Packet packet = null;
            try
            {
                ByteQueue byteQueue = new ByteQueue();
                int length = 0;
                    while (!PacketsToBeSent.IsEmpty && length <= 1024)
                    {
                        if (!PacketsToBeSent.TryDequeue(out packet))
                        {
                            Interlocked.Exchange(ref _TimesEnqueuedForSend, 0);
                            return;
                        }

                        if (!packet.Shared)
                            packet.Write();

                        byte[] packetBuffer = packet.GetBuffer();
                        length += packetBuffer.Length;

                        byteQueue.Enqueue(packetBuffer, 0, packetBuffer.Length);
                        packet.Release();

                    }

                if (byteQueue.Length > 0)
                {
                    byte[] data = new byte[length];
                    byteQueue.Dequeue(data, 0, data.Length);
                    Send_Async(data);
                }
                else
                {
                    Interlocked.Exchange(ref _TimesEnqueuedForSend, 0);

                    if (!PacketsToBeSent.IsEmpty)
                    {
                        int newValue = Interlocked.Increment(ref _TimesEnqueuedForSend);

                        if (newValue == 1)
                        {
                            Server.SendClientQueue.Enqueue(this);
                            Server.NetworkSignal.Set();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                MarkToDispose();
                DisposeSendSystem();
                if(packet != null)
                    Logger.Log(Logger.LogLevel.Error, "Sending packet: {0}", packet.ToString());
                Logger.Log(Logger.LogLevel.Error, e.ToString());

                // TODO: log something?
            }
        }
예제 #18
0
		private bool HandleSeed(NetState ns, ByteQueue buffer) {
			if (buffer.GetPacketID() == 0xEF) {
				// new packet in client	6.0.5.0	replaces the traditional seed method with a	seed packet
				// 0xEF	= 239 =	multicast IP, so this should never appear in a normal seed.	 So	this is	backwards compatible with older	clients.
				ns.Seeded = true;
				return true;
			} else if (buffer.Length >= 4) {
				byte[] m_Peek = new byte[4];

				buffer.Dequeue(m_Peek, 0, 4);

				int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3];

				if (seed == 0) {
					Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns);
					ns.Dispose();
					return false;
				}

				ns.m_Seed = seed;
				ns.Seeded = true;
				return true;
			} else {
				return false;
			}
		}
예제 #19
0
        public bool HandleReceive(NetState ns)
        {
            ByteQueue buffer = ns.Buffer;

            if (buffer == null || buffer.Length <= 0)
            {
                return(true);
            }

            CConsole.DebugLine("{0}: Incoming Data - {1} Bytes", ns, buffer.Length);

            /*
             * Packet Analyse/verify && Parsing
             */

            lock ( buffer ) {
                int length = buffer.Length;
                // debug Data
                while (length > 0 && ns.Running)
                {
                    short packetID = buffer.GetPacketID();

                    // debug log
                    using (TextWriter writer = File.CreateText(AppDomain.CurrentDomain.BaseDirectory + @"\packet_" + DateTime.Now.UnixTimestamp() + ".log")) {
                        using (MemoryStream ms = new MemoryStream(buffer.ByteBuffer))
                            Tools.FormatBuffer(writer, ms, (int)ms.Length);
                    }

                    CConsole.DebugLine("{0}: packetID {1}, {2} bytes", ns, packetID, length);

                    PacketHandler handler = PacketHandlers.GetHandler(packetID);
                    if (handler == null)
                    {
                        byte[] data = new byte[length];
                        length = buffer.Dequeue(data, 0, length);

                        CConsole.ErrorLine("{0}: no Handler found! Data dispose", ns);
                        break;
                    }

                    CConsole.StatusLine("{0}: Handler found ({1} bytes)! Trigger Callback...", ns, handler.Length);

                    byte[] packetBuffer;
                    if (mBufferSize >= handler.Length)
                    {
                        packetBuffer = mBuffers.AcquireBuffer();
                    }
                    else
                    {
                        packetBuffer = new byte[handler.Length];
                    }

                    buffer.Dequeue(packetBuffer, 0, handler.Length);

                    PacketReader r = new PacketReader(packetBuffer, handler.Length, 0);
                    handler.OnReceive(ns, r);
                    length = buffer.Length;

                    if (mBufferSize >= handler.Length)
                    {
                        mBuffers.ReleaseBuffer(packetBuffer);
                    }
                }         // end while()*/
            }             // end Lock()

            return(true);
        }
예제 #20
0
        public bool OnReceive(NetState ns)
        {
            ByteQueue buffer = ns.Buffer;

            if (buffer == null || buffer.Length <= 0)
            {
                return(true);
            }

            lock (buffer)
            {
                int length = buffer.Length;

                while (length > 0)
                {
                    int packetID = buffer.GetPacketID();

                    PacketHandler handler = ns.GetHandler(packetID);

                    if (handler == null)
                    {
                        byte[] data = new byte[length];
                        length = buffer.Dequeue(data, 0, length);

                        new PacketReader(data, length, false).Trace(ns);

                        break;
                    }

                    int packetLength = handler.Length;

                    if (packetLength <= 0)
                    {
                        if (length >= 3)
                        {
                            packetLength = buffer.GetPacketLength();

                            if (packetLength < 3)
                            {
                                ns.Dispose();
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (length < packetLength)
                    {
                        break;
                    }

                    byte[] packetBuffer = BufferSize >= packetLength?_buffers.AcquireBuffer() : new byte[packetLength];

                    packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);

                    PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);

                    handler.OnReceive(ns, r);

                    length = buffer.Length;

                    if (BufferSize >= packetLength)
                    {
                        _buffers.ReleaseBuffer(packetBuffer);
                    }
                }
            }

            return(true);
        }
예제 #21
0
        public bool HandleReceive(ByteQueue ns)
        {
            ByteQueue buffer = ns;

            if (buffer == null || buffer.Length <= 0)
            {
                return(true);
            }

            lock (buffer)
            {
                int length = buffer.Length;

                if (!ns.Sender.Seeded)
                {
                    if (buffer.GetPacketID() == 0xEF)
                    {
                        // new packet in client 6.0.5.0 replaces the traditional seed method with a seed packet
                        // 0xEF = 239 = multicast IP, so this should never appear in a normal seed.  So this is backwards compatible with older clients.
                        ns.Sender.Seeded = true;
                    }
                    else if (buffer.Length >= 4)
                    {
                        buffer.Dequeue(m_Peek, 0, 4);

                        int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3];

                        if (seed == 0)
                        {
                            Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns);
                            ns.Socket.Dispose();
                            return(false);
                        }

                        ns.Sender.Seed   = seed;
                        ns.Sender.Seeded = true;

                        length = buffer.Length;
                    }
                    else
                    {
                        return(true);
                    }
                }

                while (length > 0)
                {
                    int packetID = buffer.GetPacketID();

                    PacketHandler handler = m_PacketsHander.GetHandler(packetID);

                    if (handler == null)
                    {
                        return(false);
                    }

                    int packetLength = handler.Length;

                    if (packetLength <= 0)
                    {
                        if (length >= 3)
                        {
                            packetLength = buffer.GetPacketLength();

                            if (packetLength < 3)
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (length >= packetLength)
                    {
                        byte[] packetBuffer;

                        if (BufferSize >= packetLength)
                        {
                            packetBuffer = m_Buffers.AcquireBuffer();
                        }
                        else
                        {
                            packetBuffer = new byte[packetLength];
                        }

                        packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);

                        PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);

                        handler.OnReceive(ns, r, ns.Socket);
                        length = buffer.Length;

                        if (BufferSize >= packetLength)
                        {
                            m_Buffers.ReleaseBuffer(packetBuffer);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(true);
        }
예제 #22
0
        public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length)
        {
            if (m_Encryption != null)
            {
                if (m_AlreadyRelayed && m_Encryption is LoginEncryption)
                {
                    uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2);

                    newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000);

                    newSeed ^= m_Seed;

                    IClientEncryption newEncryption = new GameEncryption(newSeed);

                    newEncryption.clientDecrypt(ref buffer, length);

                    m_Encryption.clientDecrypt(ref buffer, length);

                    m_Encryption = newEncryption;
                    m_Seed       = newSeed;

                    return;
                }

                m_Encryption.clientDecrypt(ref buffer, length);
                return;
            }

            bool handle = false;

            for (int i = 0; i < Listener.EndPoints.Length; i++)
            {
                IPEndPoint ipep = (IPEndPoint)Listener.EndPoints[i];

                if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port)
                {
                    handle = true;
                }
            }

            if (!handle)
            {
                m_Encryption = new NoEncryption();
                return;
            }


            m_Buffer.Enqueue(buffer, 0, length);
            length = 0;


            if (!m_Seeded)
            {
                if (m_Buffer.Length <= 3)
                {
                    Console.WriteLine("Encryption: Failed - Short Lenght");
                    return;
                }
                else if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239)) //New Client
                {
                    length = m_Buffer.Length;
                    byte[] m_Peek = new byte[21];
                    m_Buffer.Dequeue(m_Peek, 0, 21);

                    m_Seed   = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21);


                    Console.WriteLine("Encryption: Passed - New Client");

                    if (length == 21)
                    {
                        return;
                    }

                    length = 21;
                }

                else if (m_Buffer.Length >= 4)
                {
                    byte[] m_Peek = new byte[4];
                    m_Buffer.Dequeue(m_Peek, 0, 4);

                    m_Seed   = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4);
                    length = 4;

                    Console.WriteLine("Encryption: Passed - Old Client");
                }
                else
                {
                    Console.WriteLine("Encryption: Failed - It should never reach here");
                    return;
                }
            }

            if (m_Encryption == null)
            {
                int packetLength = m_Buffer.Length;
                int packetOffset = length;
                m_Buffer.Dequeue(buffer, length, packetLength);
                length += packetLength;

                if (packetLength >= 3)
                {
                    if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF))
                    {
                        m_Encryption = new NoEncryption();
                        return;
                    }
                }

                if (packetLength == 62)
                {
                    if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00)
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                            return;
                        }
                    }
                    else
                    {
                        LoginEncryption encryption = new LoginEncryption();
                        if (encryption.init(m_Seed, buffer, packetOffset, packetLength))
                        {
                            Console.WriteLine("Client: {0}: Encrypted client detected, using keys of client {1}", from, encryption.Name);
                            m_Encryption = encryption;
                            byte[] packet = new byte[packetLength];
                            Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                            encryption.clientDecrypt(ref packet, packet.Length);
                            Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                        }
                        else
                        {
                            Console.WriteLine("Client: {0}: Detected an unknown client.", from);
                        }
                    }
                }
                else if (packetLength == 65)
                {
                    if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF))
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                        }
                    }
                    else
                    {
                        m_Encryption = new GameEncryption(m_Seed);

                        byte[] packet = new byte[packetLength];
                        Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                        m_Encryption.clientDecrypt(ref packet, packet.Length);
                        Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                    }
                }
                if (m_Encryption == null)
                {
                    Console.WriteLine("Encryption: Check - Waiting");
                    m_Buffer.Enqueue(buffer, packetOffset, packetLength);
                    length -= packetLength;
                    return;
                }
            }
        }
예제 #23
0
        private void handleClient(object obj)
        {
            NetworkStream clientStream = null;

            try
            {
                var client = obj as TcpClient;
                clientStream = client.GetStream();
                byte[] buffer = new byte[128];
                int    count;
                while (_treadActive)
                {
                    _socketConnected = isSocketConnected(client);

                    if (clientStream.DataAvailable)
                    {
                        int length = buffer.Length - _receiveQueue.Length;
                        count = clientStream.Read(buffer, 0, length);
                        if (count > 0)
                        {
                            _receiveQueue.Enqueue(buffer, 0, count);
                        }
                    }

                    count = _sendQueue.Length;
                    if (count > 0)
                    {
                        if (count > buffer.Length)
                        {
                            count = buffer.Length;
                        }
                        _sendQueue.Dequeue(buffer, 0, count);
                        clientStream.Write(buffer, 0, count);
                    }
                    // prevent high CPU usage
                    Thread.Sleep(10);
                }
            }
            catch (Exception e)
            {
                setExceptionMessage(e);
            }
            finally
            {
                _socketConnected = false;

                // One have to close the stream before closing the connection
                // see: https://stackoverflow.com/questions/425235/how-to-properly-and-completely-close-reset-a-tcpclient-connection
                if (clientStream != null)
                {
                    try
                    {
                        clientStream.Close();
                    }
                    catch (Exception e)
                    {
                        setExceptionMessage(e);
                    }
                }
                _mreHandleClient.Set();
            }
        }
예제 #24
0
        // Try to decrypt incoming data.
        public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length)
        {
            #region m_Encryption != null
            if (m_Encryption != null)
            {
                // If we're decrypting using LoginCrypt and we've already been relayed,
                // only decrypt a single packet using logincrypt and then disable it
                if (m_AlreadyRelayed && m_Encryption is LoginEncryption)
                {
                    uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2);

                    // Swap the seed
                    newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000);

                    // XOR it with the old seed
                    newSeed ^= m_Seed;

                    IClientEncryption newEncryption = new GameEncryption(newSeed);

                    // Game Encryption comes first
                    newEncryption.ClientDecrypt(ref buffer, length);

                    // The login encryption is still used for this one packet
                    m_Encryption.ClientDecrypt(ref buffer, length);

                    // Swap the encryption schemes
                    m_Encryption = newEncryption;
                    m_Seed       = newSeed;

                    return;
                }

                m_Encryption.ClientDecrypt(ref buffer, length);
                return;
            }
            #endregion

            #region Port Scan
            bool handle = false;

            for (int i = 0; i < Listener.EndPoints.Length; i++)
            {
                IPEndPoint ipep = Listener.EndPoints[i];

                if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port)
                {
                    handle = true;
                }
            }

            if (!handle)
            {
                m_Encryption = new NoEncryption();
                return;
            }
            #endregion

            #region !m_Seeded
            // For simplicities sake, enqueue what we just received as long as we're not initialized
            m_Buffer.Enqueue(buffer, 0, length);
            // Clear the array
            length = 0;

            if (!m_Seeded)
            {
                if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239))                       //New Client
                {
                    length = m_Buffer.Length;
                    byte[] m_Peek = new byte[21];
                    m_Buffer.Dequeue(m_Peek, 0, 21);

                    m_Seed   = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21);

                    // We need to wait the next packet
                    if (length == 21)
                    {
                        return;
                    }

                    length = 21;
                }
                else if (m_Buffer.Length >= 4)                   // Old Client
                {
                    byte[] m_Peek = new byte[4];
                    m_Buffer.Dequeue(m_Peek, 0, 4);

                    m_Seed   = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4);
                    length = 4;
                }
                else
                {
                    //Console.WriteLine("Encryption: Failed - Invalid Client.");
                    return;
                }
            }
            #endregion

            // If the context isn't initialized yet, that means we haven't decided on an encryption method yet
            #region m_Encryption == null
            if (m_Encryption == null)
            {
                int packetLength = m_Buffer.Length;
                int packetOffset = length;
                m_Buffer.Dequeue(buffer, length, packetLength);                 // Dequeue everything
                length += packetLength;

                // This is special handling for the "special" UOG packet
                if (packetLength >= 3)
                {
                    if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF))
                    {
                        m_Encryption = new NoEncryption();
                        return;
                    }
                }

                // Check if the current buffer contains a valid login packet (62 byte + 4 byte header)
                // Please note that the client sends these in two chunks. One 4 byte and one 62 byte.
                if (packetLength == 62)
                {
                    // Check certain indices in the array to see if the given data is unencrypted
                    if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00)
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                            return;
                        }
                    }
                    else
                    {
                        LoginEncryption encryption = new LoginEncryption();
                        if (encryption.Initialize(m_Seed, buffer, packetOffset, packetLength, from))
                        {
                            Console.WriteLine("Client: {0}: Encrypted client detected, using keys for client v{1}.", from, encryption.Name);
                            m_Encryption = encryption;
                            byte[] packet = new byte[packetLength];
                            Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                            encryption.ClientDecrypt(ref packet, packet.Length);
                            Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                        }
                        else
                        {
                            Console.WriteLine("Client: Unknown client detected, disconnecting.");
                            from.Dispose();
                        }
                    }
                }
                else if (packetLength == 65)
                {
                    // If its unencrypted, use the NoEncryption class
                    if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF))
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                        }
                    }
                    else
                    {
                        // If it's not an unencrypted packet, simply assume it's encrypted with the seed
                        m_Encryption = new GameEncryption(m_Seed);

                        byte[] packet = new byte[packetLength];
                        Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                        m_Encryption.ClientDecrypt(ref packet, packet.Length);
                        Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                    }
                }

                // If it's still not initialized, copy the data back to the queue and wait for more
                if (m_Encryption == null)
                {
                    m_Buffer.Enqueue(buffer, packetOffset, packetLength);
                    length -= packetLength;
                    return;
                }
            }
            #endregion
        }
예제 #25
0
        // Try to decrypt incoming data.
        public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length)
        {
            if (m_Encryption != null)
            {
                // If we're decrypting using LoginCrypt and we've already been relayed,
                // only decrypt a single packet using logincrypt and then disable it
                if (m_AlreadyRelayed && m_Encryption is LoginEncryption)
                {
                    uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2);

                    // Swap the seed
                    newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000);

                    // XOR it with the old seed
                    newSeed ^= m_Seed;

                    IClientEncryption newEncryption = new GameEncryption(newSeed);

                    // Game Encryption comes first
                    newEncryption.clientDecrypt(ref buffer, length);

                    // The login encryption is still used for this one packet
                    m_Encryption.clientDecrypt(ref buffer, length);

                    // Swap the encryption schemes
                    m_Encryption = newEncryption;
                    m_Seed       = newSeed;

                    return;
                }

                m_Encryption.clientDecrypt(ref buffer, length);
                return;
            }

            // If the client did not connect on the game server port,
            // it's not our business to handle encryption for it
            if (((IPEndPoint)from.Socket.LocalEndPoint).Port != Listener.Port)
            {
                m_Encryption = new NoEncryption();
                return;
            }

            // For simplicities sake, enqueue what we just received as long as we're not initialized
            m_Buffer.Enqueue(buffer, 0, length);
            // Clear the array
            length = 0;

            // If we didn't receive the seed yet, queue data until we can read the seed
            if (!m_Seeded)
            {
                // Now check if we have at least 4 bytes to get the seed
                if (m_Buffer.Length >= 4)
                {
                    byte[] m_Peek = new byte[m_Buffer.Length];
                    m_Buffer.Dequeue(m_Peek, 0, m_Buffer.Length);                       // Dequeue everything
                    m_Seed   = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4);
                    length = 4;
                }
                else
                {
                    return;
                }
            }

            // If the context isn't initialized yet, that means we haven't decided on an encryption method yet
            if (m_Encryption == null)
            {
                int packetLength = m_Buffer.Length;
                int packetOffset = length;
                m_Buffer.Dequeue(buffer, length, packetLength);                  // Dequeue everything
                length += packetLength;

                // This is special handling for the "special" UOG packet
                if (packetLength >= 3)
                {
                    if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF))
                    {
                        m_Encryption = new NoEncryption();
                        return;
                    }
                }

                // This is special handling for the "Emulator" packet
                if (packetLength >= 5)
                {
                    if (buffer[packetOffset] == 0xbf &&
                        buffer[packetOffset + 1] < 0x10 &&
                        buffer[packetOffset + 3] == 0x55 &&
                        buffer[packetOffset + 4] == 0x55)
                    {
                        m_Encryption = new NoEncryption();
                        return;
                    }
                }

                // Check if the current buffer contains a valid login packet (62 byte + 4 byte header)
                // Please note that the client sends these in two chunks. One 4 byte and one 62 byte.
                if (packetLength == 62)
                {
                    // Check certain indices in the array to see if the given data is unencrypted
                    if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00)
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                            return;
                        }
                    }
                    else
                    {
                        LoginEncryption encryption = new LoginEncryption();
                        if (encryption.init(m_Seed, buffer, packetOffset, packetLength))
                        {
                            log.InfoFormat("Client: {0}: Encrypted client detected, using keys of client {1}",
                                           from, encryption.Name);
                            m_Encryption = encryption;

                            byte[] packet = new byte[packetLength];
                            Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                            encryption.clientDecrypt(ref packet, packet.Length);
                            Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                        }
                        else
                        {
                            log.Warn("Detected an unknown client.");
                        }
                    }
                }
                else if (packetLength == 65)
                {
                    // If its unencrypted, use the NoEncryption class
                    if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF))
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                            return;
                        }
                    }
                    else
                    {
                        // If it's not an unencrypted packet, simply assume it's encrypted with the seed
                        m_Encryption = new GameEncryption(m_Seed);

                        byte[] packet = new byte[packetLength];
                        Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                        m_Encryption.clientDecrypt(ref packet, packet.Length);
                        Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                    }
                }

                // If it's still not initialized, copy the data back to the queue and wait for more
                if (m_Encryption == null)
                {
                    m_Buffer.Enqueue(buffer, packetOffset, packetLength);
                    length -= packetLength;
                    return;
                }
            }
        }
예제 #26
0
        public static void OpCode(Decode state, Client ed)
        {
            try
            {
                LogConsole.Show(LogType.DEBUG, "OpCode()");
                Systems sys = (Systems)state.Packet;
                sys.PacketInformation = state;

                ByteQueue queue = ed.queue;

                int length = queue.Length;
                LogConsole.Show(LogType.DEBUG, "OpCode() {0}", length);
                while ((length > 0))
                {
                    byte[] buffer;
                    int    packetID          = queue.GetPacketID();
                    int    packetLength      = queue.GetPacketLength();
                    int    packetControlCode = queue.GetPacketControlCode();

                    LogConsole.Show(LogType.DEBUG, "PacketControl: {0} PacketID: 0x{1:X2} Length: {2}", packetControlCode, packetID, packetLength);
                    LogConsole.HexDump(state.buffer, "", 16);

                    PacketHandler handler = PacketHandlers.GetHandler(packetID);
                    if (handler == null)
                    {
                        byte[] buffer2 = new byte[length];
                        length = queue.Dequeue(buffer2, 0, length);
                        LogConsole.Show(LogType.DEBUG, "Client: {0}: Unhandled packet 0x{1:X2}", new object[] { state, packetID });
                        break;
                    }

                    int size = handler.Length;
                    if (length >= 4)
                    {
                        size = packetLength;
                        if (packetLength >= 4)
                        {
                            if (length < size)
                            {
                                break;
                            }

                            if (0x400 >= size)
                            {
                                buffer = m_Buffers.AquireBuffer();
                            }
                            else
                            {
                                buffer = new byte[size];
                            }

                            size = queue.Dequeue(buffer, 0, size);

                            ushort packetid = ByteQueue.GetPacketID(buffer);

                            bool flag = IsCrypted(packetid);
                            if (flag)
                            {
                                LogConsole.Show(LogType.DEBUG, "Crypted Packet 0x{0:X4}", new object[] { packetid });
                            }

                            try
                            {
                                PacketReader2 pr = new PacketReader2(buffer, size);
                                handler.OnReceive(ed, pr);
                            }
                            catch { break; }

                            length = queue.Length;
                            if ((0x400 >= size) && !flag)
                            {
                                m_Buffers.ReleaseBuffer(buffer);
                                break;
                            }
                        }
                    }

                    length = 0;
                }
            }
            catch (Exception)
            {
            }
        }