protected void ReadNextP2PMessageChunk(PacketStream stream, TransactionNode parentNode) { TransactionNode p2pNode = new TransactionNode(parentNode, "MSNP2PMessageChunk"); // Headers TransactionNode p2pHeaders = new TransactionNode(p2pNode, "Headers"); List<PacketSlice> slices = new List<PacketSlice>(); UInt32 sessionID = stream.ReadU32LE(slices); p2pHeaders.AddField("SessionID", sessionID, "Session ID.", slices); UInt32 messageID = stream.ReadU32LE(slices); p2pHeaders.AddField("MessageID", messageID, "Message ID.", slices); UInt64 dataOffset = stream.ReadU64LE(slices); p2pHeaders.AddField("DataOffset", dataOffset, "Data offset.", slices); UInt64 dataSize = stream.ReadU64LE(slices); p2pHeaders.AddField("DataSize", dataSize, "Data size.", slices); UInt32 chunkSize = stream.ReadU32LE(slices); p2pHeaders.AddField("ChunkSize", chunkSize, "Chunk size.", slices); UInt32 flags = stream.ReadU32LE(slices); p2pHeaders.AddField("Flags", flags, StaticUtils.FormatFlags(flags), "Flags.", slices); UInt32 ackedMsgID = stream.ReadU32LE(slices); p2pHeaders.AddField("AckedMsgID", ackedMsgID, "MessageID of the message to be acknowledged.", slices); UInt32 prevAckedMsgID = stream.ReadU32LE(slices); p2pHeaders.AddField("PrevAckedMsgID", prevAckedMsgID, "AckedMsgID of the last chunk to ack.", slices); UInt64 ackedDataSize = stream.ReadU64LE(slices); p2pHeaders.AddField("AckedDataSize", ackedDataSize, "Acknowledged data size.", slices); // Body TransactionNode p2pContent = null; if (chunkSize > 0) { p2pContent = new TransactionNode(p2pNode, "Content"); byte[] bytes = stream.ReadBytes((int)chunkSize, slices); if (sessionID != 0) { p2pContent.AddField("Raw", bytes, StaticUtils.FormatByteArray(bytes), "Raw content.", slices); } else { p2pContent.AddTextField("MSNSLP", bytes, StaticUtils.DecodeUTF8(bytes), "MSNSLP data.", slices); } } }