Example #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);
        }
Example #2
0
        public static LifxPacket FromByteArray(byte[] data)
        {
            //			preambleFields = [
            //				{ name: "size"       , type:type.uint16_le },
            //				{ name: "protocol"   , type:type.uint16_le },
            //				{ name: "reserved1"  , type:type.byte4 }    ,
            //				{ name: "bulbAddress", type:type.byte6 }    ,
            //				{ name: "reserved2"  , type:type.byte2 }    ,
            //				{ name: "site"       , type:type.byte6 }    ,
            //				{ name: "reserved3"  , type:type.byte2 }    ,
            //				{ name: "timestamp"  , type:type.uint64 }   ,
            //				{ name: "packetType" , type:type.uint16_le },
            //				{ name: "reserved4"  , type:type.byte2 }    ,
            //			];
            MemoryStream ms = new MemoryStream(data);
            var          br = new BinaryReader(ms);
            //Header
            ushort len        = br.ReadUInt16();      //ReverseBytes(br.ReadUInt16()); //size uint16
            ushort protocol   = br.ReadUInt16();      // ReverseBytes(br.ReadUInt16()); //origin = 0
            var    identifier = br.ReadUInt32();

            byte[] bulbAddress = br.ReadBytes(6);
            byte[] reserved2   = br.ReadBytes(2);
            byte[] site        = br.ReadBytes(6);
            byte[] reserved3   = br.ReadBytes(2);
            ulong  timestamp   = br.ReadUInt64();
            ushort packetType  = br.ReadUInt16();            // ReverseBytes(br.ReadUInt16());

            byte[] reserved4 = br.ReadBytes(2);
            byte[] payload   = new byte[] { };
            if (len > 0)
            {
                payload = br.ReadBytes(len);
            }
            LifxPacket packet = new UnknownPacket(packetType, payload)
            {
                BulbAddress = bulbAddress,
                TimeStamp   = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(timestamp),
                Site        = site
            };

            //packet.Identifier = identifier;
            return(packet);
        }
Example #3
0
        public static IPacket Decode(short opcode, byte[] data)
        {
            IPacket packet = null;

            switch (opcode)
            {
            case (short)PacketCode.SensorData:
                packet = new SensorDataPacket();
                break;

            default:
                packet = new UnknownPacket();
                break;
            }

            packet.FromBytes(data);

            return(packet);
        }
Example #4
0
		public static LifxPacket FromByteArray(byte[] data)
		{
			//			preambleFields = [
			//				{ name: "size"       , type:type.uint16_le },
			//				{ name: "protocol"   , type:type.uint16_le },
			//				{ name: "reserved1"  , type:type.byte4 }    ,
			//				{ name: "bulbAddress", type:type.byte6 }    ,
			//				{ name: "reserved2"  , type:type.byte2 }    ,
			//				{ name: "site"       , type:type.byte6 }    ,
			//				{ name: "reserved3"  , type:type.byte2 }    ,
			//				{ name: "timestamp"  , type:type.uint64 }   ,
			//				{ name: "packetType" , type:type.uint16_le },
			//				{ name: "reserved4"  , type:type.byte2 }    ,
			//			];
			MemoryStream ms = new MemoryStream(data);
			var br = new BinaryReader(ms);
			//Header
			ushort len = br.ReadUInt16(); //ReverseBytes(br.ReadUInt16()); //size uint16
			ushort protocol = br.ReadUInt16(); // ReverseBytes(br.ReadUInt16()); //origin = 0
			var identifier = br.ReadUInt32();
			byte[] bulbAddress = br.ReadBytes(6);
			byte[] reserved2 = br.ReadBytes(2);
			byte[] site = br.ReadBytes(6);
			byte[] reserved3 = br.ReadBytes(2);
			ulong timestamp = br.ReadUInt64();
			ushort packetType = br.ReadUInt16(); // ReverseBytes(br.ReadUInt16());
			byte[] reserved4 = br.ReadBytes(2);
			byte[] payload = new byte[] { };
			if (len > 0)
			{
				payload = br.ReadBytes(len);
			}
			LifxPacket packet = new UnknownPacket(packetType, payload)
			{
				BulbAddress = bulbAddress,
				TimeStamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(timestamp),
				Site = site
			};
			//packet.Identifier = identifier;
			return packet;
		}
Example #5
0
        internal void HandlePacket(Packet message, PlayerNetworkSession playerSession)
        {
            //SignalTick();

            try
            {
                if (message == null)
                {
                    return;
                }

                if (typeof(UnknownPacket) == message.GetType())
                {
                    UnknownPacket packet = (UnknownPacket)message;
                    if (Log.IsDebugEnabled)
                    {
                        Log.Warn($"Received unknown packet 0x{message.Id:X2}\n{Packet.HexDump(packet.Message)}");
                    }

                    message.PutPool();
                    return;
                }

                if (typeof(McpeWrapper) == message.GetType())
                {
                    McpeWrapper batch    = (McpeWrapper)message;
                    var         messages = new List <Packet>();

                    // Get bytes
                    byte[] payload = batch.payload;
                    if (playerSession.CryptoContext != null && playerSession.CryptoContext.UseEncryption)
                    {
                        payload = CryptoUtils.Decrypt(payload, playerSession.CryptoContext);
                    }


                    // Decompress bytes

                    MemoryStream stream = new MemoryStream(payload);
                    if (stream.ReadByte() != 0x78)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Error($"Incorrect ZLib header. Expected 0x78 0x9C 0x{message.Id:X2}\n{Packet.HexDump(batch.payload)}");
                        }
                        if (Log.IsDebugEnabled)
                        {
                            Log.Error($"Incorrect ZLib header. Decrypted 0x{message.Id:X2}\n{Packet.HexDump(payload)}");
                        }
                        throw new InvalidDataException("Incorrect ZLib header. Expected 0x78 0x9C");
                    }
                    stream.ReadByte();
                    using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress, false))
                    {
                        // Get actual packet out of bytes
                        using (MemoryStream destination = MiNetServer.MemoryStreamManager.GetStream())
                        {
                            deflateStream.CopyTo(destination);
                            destination.Position = 0;

                            while (destination.Position < destination.Length)
                            {
                                int  len = (int)VarInt.ReadUInt32(destination);
                                long pos = destination.Position;
                                int  id  = (int)VarInt.ReadUInt32(destination);
                                len = (int)(len - (destination.Position - pos));                                  // calculate len of buffer after varint
                                byte[] internalBuffer = new byte[len];
                                destination.Read(internalBuffer, 0, len);

                                //if (Log.IsDebugEnabled)
                                //	Log.Debug($"0x{internalBuffer[0]:x2}\n{Packet.HexDump(internalBuffer)}");

                                try
                                {
                                    messages.Add(PacketFactory.Create((byte)id, internalBuffer, "mcpe") ??
                                                 new UnknownPacket((byte)id, internalBuffer));
                                }
                                catch (Exception e)
                                {
                                    if (Log.IsDebugEnabled)
                                    {
                                        Log.Warn($"Error parsing packet 0x{message.Id:X2}\n{Packet.HexDump(internalBuffer)}");
                                    }

                                    throw;
                                }
                            }

                            if (destination.Length > destination.Position)
                            {
                                throw new Exception("Have more data");
                            }
                        }
                    }
                    foreach (var msg in messages)
                    {
                        // Temp fix for performance, take 1.
                        var interact = msg as McpeInteract;
                        if (interact?.actionId == 4 && interact.targetRuntimeEntityId == 0)
                        {
                            continue;
                        }

                        msg.DatagramSequenceNumber = batch.DatagramSequenceNumber;
                        msg.Reliability            = batch.Reliability;
                        msg.ReliableMessageNumber  = batch.ReliableMessageNumber;
                        msg.OrderingChannel        = batch.OrderingChannel;
                        msg.OrderingIndex          = batch.OrderingIndex;
                        HandlePacket(msg, playerSession);
                    }

                    message.PutPool();
                    return;
                }

                MiNetServer.TraceReceive(message);

                if (CryptoContext != null && CryptoContext.UseEncryption)
                {
                    MiNetServer.FastThreadPool.QueueUserWorkItem(() =>
                    {
                        HandlePacket(MessageHandler, message as Packet);
                        message.PutPool();
                    });
                }
                else
                {
                    HandlePacket(MessageHandler, message);
                    message.PutPool();
                }
            }
            catch (Exception e)
            {
                Log.Error("Packet handling", e);
                throw;
            }
        }
        public static ClientBasePacket HandlePacket(byte[] data, int offset, GameSession client)
        {
            // Calculate message size
            var size = (short)((data[offset + 1] << 8) + data[offset]);

            // Copy the packet to a new byte array
            // Skipping the header
            var packet = new byte[size];

            Array.Copy(data, offset, packet, 0, size);

            ClientBasePacket msg;

            // Get the id
            var id = packet[2];

            // Handle the packet
            // TODO: Can we group these into login / game / etc?
            switch (id)
            {
            case 0x00:
                msg = new ProtocolVersion(packet, client);
                break;

            case 0x01:
                msg = new ValidateClient(packet, client);
                break;

            case 0x03:
                msg = new ConnectClient(packet, client);
                break;

            case 0x04:
                msg = new ConnectSwitch(packet, client);
                break;

            case 0x05:
                msg = new SwitchServer(packet, client);
                break;

            case 0x06:
                msg = new ServerTime(packet, client);
                break;

            case 0x07:
                msg = new Message(packet, client);
                break;

            case 0x0d:
                msg = new Log(packet, client);
                break;

            case 0x0c:
                msg = new SyncMoney(packet, client);
                break;

            case 0x11:
                msg = new FactoryModifyUnit(packet, client);
                break;

            case 0x12:
                msg = new FactoryModifyEnd(packet, client);
                break;

            case 0x16:
                msg = new IsValidName(packet, client);
                break;

            case 0x17:
                msg = new FactoryChangeUnitName(packet, client);
                break;

            case 0x18:
                msg = new RequestInventory(packet, client);
                break;

            case 0x19:
                msg = new RequestSearchGame(packet, client);
                break;

            case 0x1b:
                msg = new CreateGame(packet, client);
                break;

            case 0x1c:
                msg = new EnterGame(packet, client);
                break;

            case 0x1f:
                msg = new ListUser(packet, client);
                break;

            case 0x20:
                msg = new Ready(packet, client);
                break;

            case 0x21:
                msg = new Exit(packet, client);
                break;

            case 0x22:
                msg = new StartGame(packet, client);
                break;

            case 0x2b:
                msg = new SelectBase(packet, client);
                break;

            case 0x2c:
                msg = new ReadyGame(packet, client);
                break;

            case 0x2e:
                msg = new RequestPalette(packet, client);
                break;

            case 0x2f:
                msg = new MoveUnit(packet, client);
                break;

            case 0x30:
                msg = new AimUnit(packet, client);
                break;

            case 0x31:
                msg = new StartAttack(packet, client);
                break;

            case 0x32:
                msg = new StopAttack(packet, client);
                break;

            case 0x35:
                msg = new RequestRegain(packet, client);
                break;

            case 0x38:
                msg = new ModeSniper(packet, client);
                break;

            case 0x3a:
                msg = new RequestChangeWeaponset(packet, client);
                break;

            case 0x3b:
                msg = new RequestQuitBattle(packet, client);
                break;

            case 0x3f:
                msg = new BuyList(packet, client);
                break;

            case 0x40:
                msg = new RequestGoodsData(packet, client);
                break;

            case 0x46:
                msg = new RequestAvatarInfo(packet, client);
                break;

            case 0x47:
            case 0x48:
            case 0x49:
            case 0x4a:
            case 0x4b:
            case 0x4c:
            case 0x4d:
                msg = new RequestStatsInfo(packet, client);
                break;

            case 0x4e:
                msg = new RequestBestInfo(packet, client);
                break;

            case 0x57:
                msg = new TutorialSelect(packet, client);
                break;

            case 0x5a:
                msg = new UnAimUnit(packet, client);
                break;

            case 0x63:
                msg = new MsgConnect(packet, client);
                break;

            case 0x64:
                msg = new MsgUserStateInfo(packet, client);
                break;

            case 0x66:
                msg = new MsgUserClanInfo(packet, client);
                break;

            case 0x67:
                msg = new MsgGetBuddyList(packet, client);
                break;

            case 0x69:
                msg = new MsgGetChannelList(packet, client);
                break;

            case 0x6a:
                msg = new MsgJoinChannel(packet, client);
                break;

            case 0x6b:
                msg = new MsgLeaveChannel(packet, client);
                break;

            case 0x6c:
                msg = new MsgChannelChatting(packet, client);
                break;

            case 0x71:
                msg = new RequestOperator(packet, client);
                break;

            case 0x72:
                msg = new SelectOperator(packet, client);
                break;

            default:
                msg = new UnknownPacket(packet, client);
                //Console.WriteLine("Unknown packet id [{0}] from user {1}", id, client.GetUserName());
                break;
            }

            return(msg);
        }
Example #7
0
 static void OnUnknownPacketReceived(UnknownPacket packet)
 {
     Console.Out.WriteLine("Packet with unknown opcode received from client, dropping it...");
 }
Example #8
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());
        }
        public static ESPPacket getPacket(PacketId _id)
        {
            ESPPacket rc = null;

            if (_id != null)
            {
                switch (_id)
                {
                //basic data
                case PacketId.reqVersion:
                    rc = new RequestVersion(Devices.UNKNOWN, Devices.UNKNOWN);
                    break;

                case PacketId.respVersion:
                    rc = new ResponseVersion(Devices.UNKNOWN);
                    break;

                case PacketId.reqSerialNumber:
                    rc = new RequestSerialNumber(Devices.UNKNOWN, Devices.UNKNOWN);
                    break;

                case PacketId.respSerialNumber:
                    rc = new ResponseSerialNumber(Devices.UNKNOWN);
                    break;

                case PacketId.reqUserBytes:
                    rc = new RequestUserBytes(Devices.UNKNOWN);
                    break;

                case PacketId.respUserBytes:
                    rc = new ResponseUserBytes(Devices.UNKNOWN);
                    break;

                case PacketId.reqWriteUserBytes:
                    rc = new RequestWriteUserBytes(null, Devices.UNKNOWN);
                    break;

                case PacketId.reqFactoryDefault:
                    rc = new RequestFactoryDefault(Devices.UNKNOWN, Devices.UNKNOWN);
                    break;

                case PacketId.reqDefaultSweepDefinitions:
                    rc = new RequestDefaultSweepDefinitions(Devices.UNKNOWN);
                    break;

                case PacketId.respDefaultSweepDefinition:
                    rc = new ResponseDefaultSweepDefinitions(Devices.UNKNOWN);
                    break;

                //custom sweep data
                case PacketId.reqWriteSweepDefinition:
                    rc = new RequestWriteSweepDefinition(null, Devices.UNKNOWN);
                    break;

                case PacketId.reqAllSweepDefinitions:
                    rc = new RequestAllSweepDefinitions(Devices.UNKNOWN);
                    break;

                case PacketId.respSweepDefinition:
                    rc = new ResponseSweepDefinitions(Devices.UNKNOWN);
                    break;

                case PacketId.reqSetSweepsToDefault:
                    rc = new RequestSetSweepsToDefault(Devices.UNKNOWN);
                    break;

                case PacketId.reqMaxSweepIndex:
                    rc = new RequestMaxSweepIndex(Devices.UNKNOWN);
                    break;

                case PacketId.respMaxSweepIndex:
                    rc = new ResponseMaxSweepIndex(Devices.UNKNOWN);
                    break;

                case PacketId.respSweepWriteResult:
                    rc = new ResponseSweepWriteResult(Devices.UNKNOWN);
                    break;

                case PacketId.reqSweepSections:
                    rc = new RequestSweepSections(Devices.UNKNOWN);
                    break;

                case PacketId.respSweepSections:
                    rc = new ResponseSweepSections(Devices.UNKNOWN);
                    break;

                //informational packets
                case PacketId.infDisplayData:
                    rc = new InfDisplayData(Devices.UNKNOWN);
                    break;

                case PacketId.reqTurnOffMainDisplay:
                    rc = new RequestTurnOffMainDisplay(Devices.UNKNOWN);
                    break;

                case PacketId.reqTurnOnMainDisplay:
                    rc = new RequestTurnOnMainDisplay(Devices.UNKNOWN);
                    break;

                case PacketId.reqMuteOn:
                    rc = new RequestMuteOn(Devices.UNKNOWN);
                    break;

                case PacketId.reqMuteOff:
                    rc = new RequestMuteOff(Devices.UNKNOWN);
                    break;

                case PacketId.reqChangeMode:
                    rc = new RequestChangeMode((byte)0, Devices.UNKNOWN);
                    break;

                case PacketId.reqStartAlertData:
                    rc = new RequestStartAlertData(Devices.UNKNOWN);
                    break;

                case PacketId.reqStopAlertData:
                    rc = new RequestStopAlertData(Devices.UNKNOWN);
                    break;

                case PacketId.respAlertData:
                    rc = new ResponseAlertData(Devices.UNKNOWN);
                    break;

                case PacketId.respDataReceived:
                    rc = new ResponseDataReceived(Devices.UNKNOWN);
                    break;

                case PacketId.reqBatteryVoltage:
                    rc = new RequestBatteryVoltage(Devices.UNKNOWN);
                    break;

                case PacketId.respBatteryVoltage:
                    rc = new ResponseBatteryVoltage(Devices.UNKNOWN);
                    break;

                //unspported and error
                case PacketId.respUnsupportedPacket:
                    rc = new ResponseUnsupported(Devices.UNKNOWN);
                    break;

                case PacketId.respRequestNotProcessed:
                    rc = new ResponseRequestNotProcessed(Devices.UNKNOWN);
                    break;

                case PacketId.infV1Busy:
                    rc = new InfV1Busy(Devices.UNKNOWN);
                    break;

                case PacketId.respDataError:
                    rc = new ResponseDataError(Devices.UNKNOWN);
                    break;

                //Savvy
                case PacketId.reqSavvyStatus:
                    rc = new RequestSavvyStatus(Devices.UNKNOWN, Devices.UNKNOWN);
                    break;

                case PacketId.respSavvyStatus:
                    rc = new ResponseSavvyStatus(Devices.UNKNOWN);
                    break;

                case PacketId.reqVehicleSpeed:
                    rc = new RequestVehicleSpeed(Devices.UNKNOWN, Devices.UNKNOWN);
                    break;

                case PacketId.respVehicleSpeed:
                    rc = new ResponseVehicleSpeed(Devices.UNKNOWN);
                    break;

                case PacketId.reqOverrideThumbwheel:
                    rc = new RequestOverrideThumbwheel(Devices.UNKNOWN, (byte)0, Devices.UNKNOWN);
                    break;

                case PacketId.reqSetSavvyUnmuteEnable:
                    rc = new RequestSetSavvyUnmute(Devices.UNKNOWN, false, Devices.UNKNOWN);
                    break;

                default:
                    rc = new UnknownPacket(Devices.UNKNOWN);
                    break;
                }
            }
            return(rc);
        }
        /// <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());
        }