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); }
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); }
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); }
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; }
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); }
static void OnUnknownPacketReceived(UnknownPacket packet) { Console.Out.WriteLine("Packet with unknown opcode received from client, dropping it..."); }
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()); }