Mic packet ID was wrongly generated, changed some tests and increased verbosity of the reassembly exceptions
This commit is contained in:
@@ -136,4 +136,10 @@ public final class Packet {
|
||||
public long getCreatedNanotime() {
|
||||
return creationNanotime;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(getSize());
|
||||
write(buffer);
|
||||
return buffer.array();
|
||||
}
|
||||
}
|
||||
|
||||
+51
-40
@@ -8,57 +8,68 @@ import com.github.manevolent.ts3j.util.Ts3Debugging;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PacketReassembly {
|
||||
private final Map<Integer, Packet> queue = new LinkedHashMap<>();
|
||||
private boolean state = false;
|
||||
|
||||
public Packet reassemble(Packet lastFragment) throws IOException {
|
||||
// Pull out all other packets in the queue before this one which would also be fragmented
|
||||
List<Packet> reassemblyList = new ArrayList<>();
|
||||
for (int packetId = lastFragment.getHeader().getPacketId();; packetId--) {
|
||||
if (packetId < 0) packetId = 65536 + packetId;
|
||||
|
||||
Packet olderPacket = queue.get(packetId);
|
||||
try {
|
||||
// Pull out all other packets in the queue before this one which would also be fragmented
|
||||
for (int packetId = lastFragment.getHeader().getPacketId(); ; packetId--) {
|
||||
if (packetId < 0) packetId = 65536 + packetId;
|
||||
|
||||
if (olderPacket == null)
|
||||
break; // Chain breaks here
|
||||
else if (olderPacket.getHeader().getType() != lastFragment.getHeader().getType())
|
||||
continue; // skip
|
||||
else {
|
||||
reassemblyList.add(olderPacket);
|
||||
Packet olderPacket = queue.get(packetId);
|
||||
|
||||
if (olderPacket == null)
|
||||
break; // Chain breaks here
|
||||
else if (olderPacket.getHeader().getType() != lastFragment.getHeader().getType())
|
||||
continue; // skip
|
||||
else {
|
||||
reassemblyList.add(olderPacket);
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse the collection
|
||||
Collections.reverse(reassemblyList);
|
||||
|
||||
// Rebuild a master packet from the contents of all previous packet fragments
|
||||
int totalLength =
|
||||
reassemblyList
|
||||
.stream()
|
||||
.mapToInt(x -> x.getBody().getSize())
|
||||
.sum();
|
||||
|
||||
if (totalLength < 0) throw new IllegalArgumentException("reassembly too small: " + totalLength);
|
||||
|
||||
Packet firstPacket = reassemblyList.get(0);
|
||||
Packet reassembledPacket = new Packet(firstPacket.getRole());
|
||||
reassembledPacket.setHeader(firstPacket.getHeader());
|
||||
|
||||
ByteBuffer reassemblyBuffer = ByteBuffer.allocate(totalLength);
|
||||
|
||||
reassembledPacket.getHeader().setPacketFlag(HeaderFlag.FRAGMENTED, false);
|
||||
|
||||
for (Packet old : reassemblyList)
|
||||
old.writeBody(reassemblyBuffer);
|
||||
|
||||
if (firstPacket.getHeader().getPacketFlag(HeaderFlag.COMPRESSED))
|
||||
reassemblyBuffer = ByteBuffer.wrap(QuickLZ.decompress(reassemblyBuffer.array()));
|
||||
|
||||
reassembledPacket.readBody(reassemblyBuffer);
|
||||
|
||||
return reassembledPacket;
|
||||
} catch (Exception ex) {
|
||||
throw new IOException("Problem reassembling " + reassemblyList.size() + " packet(s): [" +
|
||||
String.join(",",
|
||||
reassemblyList.stream().map(x -> "{" +
|
||||
Base64.getEncoder().encodeToString(x.toByteArray())
|
||||
+ "}").collect(Collectors.toList())) + "]",
|
||||
ex);
|
||||
}
|
||||
|
||||
// Reverse the collection
|
||||
Collections.reverse(reassemblyList);
|
||||
|
||||
// Rebuild a master packet from the contents of all previous packet fragments
|
||||
int totalLength =
|
||||
reassemblyList
|
||||
.stream()
|
||||
.mapToInt(x -> x.getBody().getSize())
|
||||
.sum();
|
||||
|
||||
if (totalLength < 0) throw new IllegalArgumentException("reassembly too small: " + totalLength);
|
||||
|
||||
Packet firstPacket = reassemblyList.get(0);
|
||||
Packet reassembledPacket = new Packet(firstPacket.getRole());
|
||||
reassembledPacket.setHeader(firstPacket.getHeader());
|
||||
|
||||
ByteBuffer reassemblyBuffer = ByteBuffer.allocate(totalLength);
|
||||
|
||||
reassembledPacket.getHeader().setPacketFlag(HeaderFlag.FRAGMENTED, false);
|
||||
|
||||
for (Packet old : reassemblyList)
|
||||
old.writeBody(reassemblyBuffer);
|
||||
|
||||
if (firstPacket.getHeader().getPacketFlag(HeaderFlag.COMPRESSED))
|
||||
reassemblyBuffer = ByteBuffer.wrap(QuickLZ.decompress(reassemblyBuffer.array()));
|
||||
|
||||
reassembledPacket.readBody(reassemblyBuffer);
|
||||
|
||||
return reassembledPacket;
|
||||
}
|
||||
|
||||
public Packet put(Packet packet) throws IOException {
|
||||
|
||||
+6
-5
@@ -291,11 +291,6 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
case COMMAND_LOW:
|
||||
header.setPacketFlag(HeaderFlag.NEW_PROTOCOL, true);
|
||||
break;
|
||||
case VOICE:
|
||||
// > X is a ushort in H2N order of an own audio packet counter
|
||||
// it seems it can be the same as the packet counter so we will let the packethandler do it.
|
||||
((PacketBody0Voice)body).setPacketId(header.getPacketId());
|
||||
break;
|
||||
}
|
||||
|
||||
// Assign header pointer
|
||||
@@ -383,6 +378,12 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
break;
|
||||
}
|
||||
|
||||
if (header.getType() == PacketBodyType.VOICE) {
|
||||
// > X is a ushort in H2N order of an own audio packet counter
|
||||
// it seems it can be the same as the packet counter so we will let the packethandler do it.
|
||||
((PacketBody0Voice)packet.getBody()).setPacketId(header.getPacketId());
|
||||
}
|
||||
|
||||
// Use the counters determined above to generate a packet id and generation id
|
||||
header.setPacketId(counter.getKey());
|
||||
header.setGeneration(counter.getValue());
|
||||
|
||||
Reference in New Issue
Block a user