示例#1
0
        public IPacket ReadPacket(out byte[] rawPacket, out byte[] decryptedPacket)
        {
            /* Receive data from the socket, saves it a buffer,
             * then reads packet from the buffer.
             */

            var timeout = DateTime.Now.AddMilliseconds(500); // 500ms

            while (DataAvailable && DateTime.Now < timeout)
            {
                CoCStream.ReadToBuffer(); // reads data saves it a buffer

                //var packetBuffer = new PacketBuffer(CoCStream.ReadBuffer.ToArray());
                var enPacketReader = new PacketReader(CoCStream.ReadBuffer);

                // read header
                var packetID      = enPacketReader.ReadUInt16();
                var packetLength  = enPacketReader.ReadInt24();
                var packetVersion = enPacketReader.ReadUInt16();

                // read body
                if (packetLength > enPacketReader.BaseStream.Length) // check if data is enough data is avaliable in the buffer
                {
                    continue;
                }

                var encryptedData = GetPacketBody(packetLength);
                var decryptedData = (byte[])encryptedData.Clone(); // cloning just cause we want the encrypted data

                CoCCrypto.Decrypt(decryptedData);

                var dePacketReader = new PacketReader(new MemoryStream(decryptedData));

                var packet = CreatePacketInstance(packetID);
                if (packet is UnknownPacket)
                {
                    packet = new UnknownPacket
                    {
                        ID      = packetID,
                        Length  = packetLength,
                        Version = packetVersion
                    };
                    ((UnknownPacket)packet).EncryptedData = encryptedData;
                }

                decryptedPacket = decryptedData;
                rawPacket       = ExtractRawPacket(packetLength);
                //CoCStream.ReadBuffer = new MemoryStream(4096);
                //CoCStream.Write(packetBuffer.Buffer, 0, packetBuffer.Buffer.Length);
                try
                {
                    packet.ReadPacket(dePacketReader);
                }
                catch { }
                return(packet);
            }
            decryptedPacket = null;
            rawPacket       = null;
            return(null);
        }
示例#2
0
        private IPacket[] ProcessReceive(SocketAsyncEventArgs args)
        {
            var packetList     = new List <IPacket>();
            var packetToken    = args.UserToken as PacketToken;
            var bytesToProcess = args.BytesTransferred;

            if (bytesToProcess == 0)
            {
                //TODO: Fire event
                Disconnected = true;
                return(null);
            }

ReadPacket:

            // read header
            if (packetToken.HeaderReceiveOffset != PacketBuffer.HeaderSize) // we do not have the header
            {
                if (PacketBuffer.HeaderSize > bytesToProcess)               // we got less that 7 bytes, some parts of the header
                {
                    Console.WriteLine("[Net:ID {0}] Not enough bytes to read header.", packetToken.TokenID);

                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Header, packetToken.HeaderReceiveOffset, bytesToProcess);
                    packetToken.HeaderReceiveOffset += bytesToProcess;
                    packetToken.ReceiveOffset        = 0;
                    StartReceive(args);
                    return(packetList.ToArray());
                }
                else // if we got more than enough data for the header
                {
                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Header, packetToken.HeaderReceiveOffset, PacketBuffer.HeaderSize);
                    packetToken.HeaderReceiveOffset += PacketBuffer.HeaderSize;
                    packetToken.ReceiveOffset       += PacketBuffer.HeaderSize; // probs here?
                    bytesToProcess -= PacketBuffer.HeaderSize;
                    ReadHeader(packetToken);
                }
            }

            // read body
            if (packetToken.BodyReceiveOffset != packetToken.Length)
            {
                if (packetToken.Length - packetToken.BodyReceiveOffset > bytesToProcess) // if we dont have enough to read body
                {
                    Console.WriteLine("[Net:ID {0}] Not enough bytes to read body.", packetToken.TokenID);

                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Body, packetToken.BodyReceiveOffset, bytesToProcess);
                    packetToken.BodyReceiveOffset += bytesToProcess;
                    packetToken.ReceiveOffset      = 0;
                    StartReceive(args);
                    return(packetList.ToArray());
                }
                else // if we got more than enough data for the body
                {
                    Buffer.BlockCopy(args.Buffer, packetToken.ReceiveOffset, packetToken.Body, packetToken.BodyReceiveOffset, packetToken.Length - packetToken.BodyReceiveOffset);
                    bytesToProcess                -= packetToken.Length - packetToken.BodyReceiveOffset;
                    packetToken.ReceiveOffset     += packetToken.Length - packetToken.BodyReceiveOffset;
                    packetToken.BodyReceiveOffset += packetToken.Length;
                }
            }

            var packet       = CreatePacketInstance(packetToken.ID);
            var packetDeData = (byte[])packetToken.Body.Clone();

            CoCCrypto.Decrypt(packetDeData);

            if (packet is UnknownPacket)
            {
                packet = new UnknownPacket()
                {
                    ID            = packetToken.ID,
                    Length        = packetToken.Length,
                    Version       = packetToken.Version,
                    EncryptedData = packetToken.Body,
                    DecryptedData = packetDeData
                };
            }

            using (var reader = new PacketReader(new MemoryStream(packetDeData)))
            {
                try
                {
                    if (!(packet is UnknownPacket))
                    {
                        packet.ReadPacket(reader);
                    }
                }
                catch (Exception ex)
                {
                    if (PacketReceivedFailed != null)
                    {
                        PacketReceivedFailed(args, ex);
                    }
                    packetToken.Reset();
                    goto ReadPacket;
                }
            }

            if (packet is UpdateKeyPacket)
            {
                UpdateCiphers(Seed, ((UpdateKeyPacket)packet).Key);
            }

            packetList.Add(packet);
            packetToken.Reset();
            if (bytesToProcess != 0)
            {
                goto ReadPacket;
            }

            packetToken.ReceiveOffset = 0;
            ReceiveEventPool.Push(args);
            StartReceive(ReceiveEventPool.Pop());
            return(packetList.ToArray());
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public IPacket[] ReadPackets(SocketAsyncEventArgs args)
        {
            var list = new List <IPacket>();
            var numBytesToProcess = args.BytesTransferred;

            if (numBytesToProcess == 0)
            {
                return(null);
            }

            while (true)
            {
                if (numBytesToProcess == 0)
                {
                    break;
                }

                var packet       = (IPacket)null;
                var packetBuffer = args.UserToken as PacketBuffer;
                try
                {
                    using (var enPacketReader = new PacketReader(new MemoryStream(packetBuffer.Buffer)))
                    {
                        if (PacketBuffer.HeaderSize > numBytesToProcess) // check if there is a header
                        {
                            break;
                        }

                        // read header
                        var packetID      = enPacketReader.ReadUInt16();
                        var packetLength  = enPacketReader.ReadInt24();
                        var packetVersion = enPacketReader.ReadUInt16(); // the unknown

                        // read body
                        if (packetLength > numBytesToProcess) // check if data is enough data is avaliable in the buffer
                        {
                            break;
                        }

                        var encryptedData = packetBuffer.ExtractPacket(PacketExtractionFlags.Body |
                                                                       PacketExtractionFlags.Remove,
                                                                       packetLength);
                        var decryptedData = (byte[])encryptedData.Clone(); // cloning just cause we want the encrypted data
                        CoCCrypto.Decrypt(decryptedData);
                        numBytesToProcess -= packetLength + PacketBuffer.HeaderSize;

                        using (var dePacketReader = new PacketReader(new MemoryStream(decryptedData)))
                        {
                            packet = CreatePacketInstance(packetID);
                            if (packet is UnknownPacket)
                            {
                                packet = new UnknownPacket
                                {
                                    ID            = packetID,
                                    Length        = packetLength,
                                    Version       = packetVersion,
                                    EncryptedData = encryptedData,
                                    DecryptedData = decryptedData
                                };
                            }
                            packet.ReadPacket(dePacketReader);
                        }
                    }
                    if (packet is UpdateKeyPacket)
                    {
                        UpdateCiphers(Seed, ((UpdateKeyPacket)packet).Key); // handle update key packet
                    }
                    list.Add(packet);
                }
                catch (Exception ex)
                {
                    if (PacketReceivedFailed != null)
                    {
                        PacketReceivedFailed(args, ex);
                    }
                }
            }
            return(list.ToArray());
        }