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 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 (Exception ex) { if (ExceptionLog != null) ExceptionLog.LogData(ex); } return packet; } decryptedPacket = null; rawPacket = null; return null; }
/// <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(); }