diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/fragment/PacketReassembly.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/fragment/PacketReassembly.java index ed3189c..5214b74 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/fragment/PacketReassembly.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/fragment/PacketReassembly.java @@ -3,7 +3,6 @@ package com.github.manevolent.ts3j.protocol.packet.fragment; import com.github.manevolent.ts3j.protocol.Packet; import com.github.manevolent.ts3j.protocol.header.HeaderFlag; import com.github.manevolent.ts3j.util.QuickLZ; -import com.github.manevolent.ts3j.util.Ts3Debugging; import java.io.IOException; import java.nio.ByteBuffer; @@ -19,6 +18,8 @@ public class PacketReassembly { try { // Pull out all other packets in the queue before this one which would also be fragmented + List packetIds = new ArrayList<>(); + for (int packetId = lastFragment.getHeader().getPacketId(); ; packetId--) { if (packetId < 0) packetId = 65536 + packetId; @@ -27,9 +28,14 @@ public class PacketReassembly { if (olderPacket == null) break; // Chain breaks here else if (olderPacket.getHeader().getType() != lastFragment.getHeader().getType()) - continue; // skip + continue; // skip??? else { + packetIds.add(packetId); reassemblyList.add(olderPacket); + + if (lastFragment.getHeader().getPacketId() != packetId && + olderPacket.getHeader().getPacketFlag(HeaderFlag.FRAGMENTED)) + break; } } @@ -61,6 +67,9 @@ public class PacketReassembly { reassembledPacket.readBody(reassemblyBuffer); + // Remove read packets + for (Integer packetId : packetIds) queue.remove(packetId); + return reassembledPacket; } catch (Exception ex) { throw new IOException("Problem reassembling " + reassemblyList.size() + " packet(s): [" + diff --git a/src/test/java/com/github/manevolent/ts3j/FragmentTest.java b/src/test/java/com/github/manevolent/ts3j/FragmentTest.java index 12f312c..7cab3f3 100644 --- a/src/test/java/com/github/manevolent/ts3j/FragmentTest.java +++ b/src/test/java/com/github/manevolent/ts3j/FragmentTest.java @@ -9,7 +9,6 @@ import com.github.manevolent.ts3j.protocol.packet.fragment.Fragments; import com.github.manevolent.ts3j.protocol.packet.fragment.PacketReassembly; import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; import com.github.manevolent.ts3j.util.Pair; -import com.github.manevolent.ts3j.util.QuickLZ; import com.github.manevolent.ts3j.util.Ts3Debugging; import junit.framework.TestCase; import org.bouncycastle.util.encoders.Base64; diff --git a/src/test/java/com/github/manevolent/ts3j/FragmentTest2.java b/src/test/java/com/github/manevolent/ts3j/FragmentTest2.java new file mode 100644 index 0000000..4b94114 --- /dev/null +++ b/src/test/java/com/github/manevolent/ts3j/FragmentTest2.java @@ -0,0 +1,66 @@ +package com.github.manevolent.ts3j; + +import com.github.manevolent.ts3j.protocol.Packet; +import com.github.manevolent.ts3j.protocol.ProtocolRole; +import com.github.manevolent.ts3j.protocol.header.ClientPacketHeader; +import com.github.manevolent.ts3j.protocol.header.HeaderFlag; +import com.github.manevolent.ts3j.protocol.packet.PacketBody2Command; +import com.github.manevolent.ts3j.protocol.packet.PacketBodyType; +import com.github.manevolent.ts3j.protocol.packet.fragment.Fragments; +import com.github.manevolent.ts3j.protocol.packet.fragment.PacketBodyFragment; +import com.github.manevolent.ts3j.protocol.packet.fragment.PacketReassembly; +import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; +import com.github.manevolent.ts3j.util.Pair; +import com.github.manevolent.ts3j.util.Ts3Debugging; +import junit.framework.TestCase; +import org.bouncycastle.util.encoders.Base64; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +public class FragmentTest2 extends TestCase { + + public static void main(String[] args) throws Exception { + new FragmentTest2().testParser(); + } + + public void testParser() throws Exception { + Ts3Debugging.setEnabled(true); + + String[] packets = new String[] { + // Put diagnostic here + }; + + List pieces = new ArrayList<>(); + + for (int i = 0; i < packets.length; i ++) { + Packet packet = new Packet(ProtocolRole.SERVER); + ByteBuffer buffer = ByteBuffer.wrap(Base64.decode(packets[i])); + packet.readHeader(buffer); + packet.setBody(new PacketBodyFragment(packet.getHeader().getType(), ProtocolRole.SERVER)); + packet.readBody(buffer); + pieces.add(packet); + + Ts3Debugging.debug( + "Read type=" + packet.getHeader().getType() + + " id=" + packet.getHeader().getPacketId() + + " flags=" + packet.getHeader().getPacketFlags() + + " fragment=" + packet.getHeader().getPacketFlag(HeaderFlag.FRAGMENTED) + ); + } + + Ts3Debugging.debug("Loaded " + pieces.size() + " pieces."); + + PacketReassembly reassembly = new PacketReassembly(); + for (Packet piece : pieces) { + Packet out = reassembly.put(piece); + if (out != null) { + Ts3Debugging.debug(((PacketBody2Command)out.getBody()).getText()); + } + } + } + +}