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); }
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()); }