Fragments which wrap around 65536 and cause the packet ID to ascend more than once will crash the code
This commit is contained in:
+26
-18
@@ -2,6 +2,8 @@ package com.github.manevolent.ts3j.protocol.packet.fragment;
|
|||||||
|
|
||||||
import com.github.manevolent.ts3j.protocol.Packet;
|
import com.github.manevolent.ts3j.protocol.Packet;
|
||||||
import com.github.manevolent.ts3j.protocol.header.HeaderFlag;
|
import com.github.manevolent.ts3j.protocol.header.HeaderFlag;
|
||||||
|
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.QuickLZ;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,20 +12,18 @@ import java.util.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PacketReassembly {
|
public class PacketReassembly {
|
||||||
|
private final AbstractTeamspeakClientSocket.LocalCounter counter =
|
||||||
|
new AbstractTeamspeakClientSocket.LocalCounterFull(65536, true);
|
||||||
|
|
||||||
private final Map<Integer, Packet> queue = new LinkedHashMap<>();
|
private final Map<Integer, Packet> queue = new LinkedHashMap<>();
|
||||||
private int currentPacketId = 0;
|
|
||||||
|
|
||||||
public void setPacketId(int currentPacketId) {
|
public void put(Packet packet) throws IOException {
|
||||||
this.currentPacketId = currentPacketId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean put(Packet packet) throws IOException {
|
|
||||||
queue.put(packet.getHeader().getPacketId(), packet);
|
queue.put(packet.getHeader().getPacketId(), packet);
|
||||||
|
|
||||||
return currentPacketId == packet.getHeader().getPacketId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Packet next() throws IOException {
|
public Packet next() throws IOException {
|
||||||
|
if (queue.size() <= 0) return null;
|
||||||
|
|
||||||
List<Packet> reassemblyList = new ArrayList<>();
|
List<Packet> reassemblyList = new ArrayList<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -32,33 +32,38 @@ public class PacketReassembly {
|
|||||||
|
|
||||||
boolean state = false;
|
boolean state = false;
|
||||||
|
|
||||||
for (int packetId = currentPacketId; ; packetId++) {
|
AbstractTeamspeakClientSocket.LocalCounter temporaryCounter =
|
||||||
if (packetId >= 65536) packetId = 0;
|
new AbstractTeamspeakClientSocket.LocalCounterFull(65536, true);
|
||||||
|
|
||||||
Packet packet = queue.get(packetId);
|
Pair<Integer, Integer> currentPacketId = counter.current();
|
||||||
|
|
||||||
|
temporaryCounter.setPacketId(currentPacketId.getKey());
|
||||||
|
temporaryCounter.setGeneration(currentPacketId.getValue());
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Pair<Integer, Integer> thisPacketId = temporaryCounter.current();
|
||||||
|
Packet packet = queue.get(thisPacketId.getKey());
|
||||||
|
|
||||||
if (packet == null)
|
if (packet == null)
|
||||||
break; // Chain breaks here
|
break; // Chain breaks here
|
||||||
else {
|
else {
|
||||||
packetIds.add(packetId);
|
packetIds.add(thisPacketId.getKey());
|
||||||
reassemblyList.add(packet);
|
reassemblyList.add(packet);
|
||||||
|
|
||||||
if (packet.getHeader().getPacketFlag(HeaderFlag.FRAGMENTED)) {
|
if (packet.getHeader().getPacketFlag(HeaderFlag.FRAGMENTED)) {
|
||||||
state = !state;
|
state = !state;
|
||||||
|
|
||||||
if (!state) {
|
if (!state) {
|
||||||
currentPacketId += packetIds.size();
|
|
||||||
break; // fragmentation stopped, we found the last packet
|
break; // fragmentation stopped, we found the last packet
|
||||||
} else
|
}
|
||||||
continue; // keep collecting fragments
|
|
||||||
} else if (!state) {
|
} else if (!state) {
|
||||||
currentPacketId ++;
|
|
||||||
break; // don't reassemble this packet, it's not a fragment
|
break; // don't reassemble this packet, it's not a fragment
|
||||||
} else if (state) {
|
} else if (state) {
|
||||||
// keep collecting fragments
|
// keep collecting fragments
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
temporaryCounter.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state) return null; // cannot reassemble yet because we don't have all fragments
|
if (state) return null; // cannot reassemble yet because we don't have all fragments
|
||||||
@@ -94,6 +99,9 @@ public class PacketReassembly {
|
|||||||
// Remove read packets
|
// Remove read packets
|
||||||
packetIds.forEach(queue::remove);
|
packetIds.forEach(queue::remove);
|
||||||
|
|
||||||
|
// Count
|
||||||
|
counter.next(packetIds.size());
|
||||||
|
|
||||||
return reassembledPacket;
|
return reassembledPacket;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IOException("Problem reassembling " + reassemblyList.size() + " packet(s): [" +
|
throw new IOException("Problem reassembling " + reassemblyList.size() + " packet(s): [" +
|
||||||
@@ -106,7 +114,7 @@ public class PacketReassembly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
currentPacketId = 0;
|
counter.reset();
|
||||||
queue.clear();
|
queue.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+10
-5
@@ -68,9 +68,7 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
|
|
||||||
private CommandProcessor commandProcessor;
|
private CommandProcessor commandProcessor;
|
||||||
|
|
||||||
private Consumer<Throwable> exceptionHandler = throwable -> {
|
private Consumer<Throwable> exceptionHandler = Throwable::printStackTrace;
|
||||||
throwable.printStackTrace();
|
|
||||||
};
|
|
||||||
|
|
||||||
private Identity identity = null;
|
private Identity identity = null;
|
||||||
private ClientConnectionState connectionState = null;
|
private ClientConnectionState connectionState = null;
|
||||||
@@ -929,7 +927,9 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
private int tries = 1, maxTries;
|
private int tries = 1, maxTries;
|
||||||
private boolean willResend;
|
private boolean willResend;
|
||||||
|
|
||||||
public PacketResponse(NetworkPacket sentPacket, Map<Integer, PacketResponse> responsibleQueue, int maxTries) {
|
public PacketResponse(NetworkPacket sentPacket,
|
||||||
|
Map<Integer, PacketResponse> responsibleQueue,
|
||||||
|
int maxTries) {
|
||||||
this.sentPacket = sentPacket;
|
this.sentPacket = sentPacket;
|
||||||
this.responsibleQueue = responsibleQueue;
|
this.responsibleQueue = responsibleQueue;
|
||||||
this.maxTries = maxTries;
|
this.maxTries = maxTries;
|
||||||
@@ -1248,6 +1248,12 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
public interface LocalCounter {
|
public interface LocalCounter {
|
||||||
Pair<Integer, Integer> next();
|
Pair<Integer, Integer> next();
|
||||||
|
|
||||||
|
default Pair<Integer, Integer> next(int n) {
|
||||||
|
Pair<Integer, Integer> last = current();
|
||||||
|
for (int i = 0; i < n; i ++) last = next();
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
int getPacketId();
|
int getPacketId();
|
||||||
boolean setPacketId(int packetId);
|
boolean setPacketId(int packetId);
|
||||||
|
|
||||||
@@ -1340,7 +1346,6 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
@Override
|
@Override
|
||||||
public void setGeneration(int i) {
|
public void setGeneration(int i) {
|
||||||
synchronized (sendLock) {
|
synchronized (sendLock) {
|
||||||
Ts3Debugging.debug("setGeneration: " + i);
|
|
||||||
this.generationId = i;
|
this.generationId = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-6
@@ -60,7 +60,6 @@ public class LocalTeamspeakClientSocket
|
|||||||
private List<TS3Listener> listeners = new LinkedList<>();
|
private List<TS3Listener> listeners = new LinkedList<>();
|
||||||
|
|
||||||
private int acceptingReturnCode = Integer.MAX_VALUE;
|
private int acceptingReturnCode = Integer.MAX_VALUE;
|
||||||
private int lastReturnCode = 0;
|
|
||||||
|
|
||||||
private Integer serverId = null;
|
private Integer serverId = null;
|
||||||
|
|
||||||
@@ -251,7 +250,7 @@ public class LocalTeamspeakClientSocket
|
|||||||
|
|
||||||
serverId = null;
|
serverId = null;
|
||||||
awaitingCommands.clear();
|
awaitingCommands.clear();
|
||||||
acceptingReturnCode = lastReturnCode = 0;
|
acceptingReturnCode = 0;
|
||||||
|
|
||||||
setOption("client.hostname", remote.getHostString());
|
setOption("client.hostname", remote.getHostString());
|
||||||
|
|
||||||
@@ -341,10 +340,10 @@ public class LocalTeamspeakClientSocket
|
|||||||
if (getState() != ClientConnectionState.CONNECTED)
|
if (getState() != ClientConnectionState.CONNECTED)
|
||||||
throw new IOException("not connected");
|
throw new IOException("not connected");
|
||||||
|
|
||||||
int returnCode;
|
int maxReturnCode = calculateAcceptingReturnCode();
|
||||||
|
if (maxReturnCode == Integer.MAX_VALUE) maxReturnCode = 0;
|
||||||
// sync may not be necessary here
|
else maxReturnCode = maxReturnCode + 1;
|
||||||
returnCode = lastReturnCode++;
|
int returnCode = maxReturnCode;
|
||||||
|
|
||||||
command.add(new CommandSingleParameter("return_code", Integer.toString(returnCode)));
|
command.add(new CommandSingleParameter("return_code", Integer.toString(returnCode)));
|
||||||
|
|
||||||
|
|||||||
@@ -25,40 +25,47 @@ public class FragmentTest extends TestCase {
|
|||||||
public void testParser() throws Exception {
|
public void testParser() throws Exception {
|
||||||
Ts3Debugging.setEnabled(true);
|
Ts3Debugging.setEnabled(true);
|
||||||
|
|
||||||
byte[] data = new byte[5003];
|
|
||||||
new Random(0x1234567).nextBytes(data);
|
|
||||||
|
|
||||||
ClientPacketHeader header = new ClientPacketHeader();
|
|
||||||
Packet largePacket = new Packet(ProtocolRole.CLIENT, header);
|
|
||||||
header.setType(PacketBodyType.COMMAND);
|
|
||||||
|
|
||||||
String text = Base64.toBase64String(data);
|
|
||||||
largePacket.setBody(new PacketBody2Command(ProtocolRole.CLIENT, text));
|
|
||||||
|
|
||||||
PacketReassembly reassembly = new PacketReassembly();
|
|
||||||
AbstractTeamspeakClientSocket.LocalCounterFull counter =
|
AbstractTeamspeakClientSocket.LocalCounterFull counter =
|
||||||
new AbstractTeamspeakClientSocket.LocalCounterFull(65536, true);
|
new AbstractTeamspeakClientSocket.LocalCounterFull(65536, true);
|
||||||
|
|
||||||
counter.setPacketId(65534); // Test wrapping around the generation at the same time :)
|
PacketReassembly reassembly = new PacketReassembly();
|
||||||
reassembly.setPacketId(65535);
|
|
||||||
|
|
||||||
List<Packet> pieces = Fragments.split(largePacket);
|
for (int i = 0; i < 10_000; i ++) {
|
||||||
Ts3Debugging.debug("Created " + pieces.size() + " pieces (total=" + data.length + ").");
|
byte[] data = new byte[5003];
|
||||||
|
new Random(0x1234567).nextBytes(data);
|
||||||
|
|
||||||
for (Packet piece : pieces) {
|
ClientPacketHeader header = new ClientPacketHeader();
|
||||||
Pair<Integer, Integer> packetId = counter.next();
|
Packet largePacket = new Packet(ProtocolRole.CLIENT, header);
|
||||||
piece.getHeader().setPacketId(packetId.getKey());
|
header.setType(PacketBodyType.COMMAND);
|
||||||
piece.getHeader().setGeneration(packetId.getValue());
|
|
||||||
|
|
||||||
reassembly.put(piece);
|
String text = Base64.toBase64String(data);
|
||||||
}
|
largePacket.setBody(new PacketBody2Command(ProtocolRole.CLIENT, text));
|
||||||
|
|
||||||
Packet reassembled;
|
List<Packet> pieces = Fragments.split(largePacket);
|
||||||
while (((reassembled = reassembly.next()) != null)) {
|
|
||||||
assertEquals(
|
for (Packet piece : pieces) {
|
||||||
((PacketBody2Command) largePacket.getBody()).getText(),
|
Pair<Integer, Integer> packetId = counter.current();
|
||||||
((PacketBody2Command) reassembled.getBody()).getText()
|
|
||||||
);
|
piece.getHeader().setPacketId(packetId.getKey());
|
||||||
|
piece.getHeader().setGeneration(packetId.getValue());
|
||||||
|
|
||||||
|
reassembly.put(piece);
|
||||||
|
|
||||||
|
counter.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
Packet reassembled;
|
||||||
|
boolean read = false;
|
||||||
|
while (((reassembled = reassembly.next()) != null)) {
|
||||||
|
assertEquals(
|
||||||
|
((PacketBody2Command) largePacket.getBody()).getText(),
|
||||||
|
((PacketBody2Command) reassembled.getBody()).getText()
|
||||||
|
);
|
||||||
|
|
||||||
|
read = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(true, read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
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.HeaderFlag;
|
|
||||||
import com.github.manevolent.ts3j.protocol.packet.fragment.PacketBodyFragment;
|
|
||||||
import com.github.manevolent.ts3j.protocol.packet.fragment.PacketReassembly;
|
|
||||||
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.List;
|
|
||||||
|
|
||||||
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[] {
|
|
||||||
"LvdqqRB1ozMABBJlaXY0e5iIcGFja2V0c4FQkRkjgz0zMnE7IFGYbmVjIviVXFI5Ag8P3F8kgzQ4Mzg5OSFgkIgSRjSFKjI0MjgxYJiIVOJNNDE2NTA0OXFgmYh7gl+iZYsxz/mBUFGYZIUqMTkzUlOQiB5taW4hIocqMTgBYJCIFEc0oGUSMjkRYJCIIrv4MjmhYJiIUZiCNQMHAIAxGST6MDI5MTI2QWCZiKPzX2lwPTc0LjIwOS4yLjg1",
|
|
||||||
"xX0QvWydOFsAAlJHhAQAAEoHAAAAAACgY2lkPTEgY2xpZW50X2lkbGVfdGltZT0xNjgyMjdmXnVgAACAbmlxdWWR8TGSaWZpZXI9SW9RY3NZMnYwcXpNMThOeGFsAAQCgFBQazBiTEpLQT1mXm5pY2tuYbFrbm90XHNhXHN3aG9yZQEAAIBmXnZlcnNpb249My4xLjEwXHNbQnVpbGQ6XHMxNTI4NUAAgIAzNzYxNV1mXnBsYXRmb3JtPVdpbmRvd3NmXmlucHV0X22IhgOWdXRleedvdXR4IzBmXoQib25seZWgJ2D0lmhhcmR3YXJh52xeX+BkEmRlAAACiGZhdWx0X2NoYW5uZWw9XC84Zl5tZXRhX2RhdGFmXmlzXwAMAIByZWNvcmRpbmc9J2AFJV9zaWduPStcL0JXdnVlaWtHZzQAAACAWWtPMXYydXVaQjV2dEpKZ1VaNWJMOGNSZnhBc3RmbgAAAIBDVmRybzJqYSs0YSs4ckdVekR4OFwvdnZUWk9VVkQ2AECAhFU5NWhuV2I2MzhNQ1E992BzZWN1cml0eZHkc2hmXmxvZ2kcGUiMbl+Ce2ZeImJiYXMCnz0yZl5V519ncm91cJHxPTVmXnNlcgElA0lzPTYhIlCgZl5jcmVhIzM1MzAhYTc1OGZebGE=",
|
|
||||||
"+hN1ybZO1gEAAwJzdGNvgYNjJTM0MDg5MDMnYHQwwoCQb3RhbFWY8ZhzPTV3YGF3YXnoI2IXX21lc3NhZ3dldHlwZegjZmwgAACAYWdfYXZhJ3I9ZmQwMjhjYzUzNmU3YmM3MWJiOWQ4MGGQQZOhZWFjYxEUNTNmXiF7a19wb3chGzd3YCN7cmVhMnN06CMqe19tc2dmXmSAAELgZXNjcmlwdPGYPW1hbmVcc2lzs1RnaWFuEbRuaWdnZXJmXuFpBwDggiJ7IRsnYG1vbnRoX2J5dGVzX3VwbG9hZDF7IGAVIYFupZcxNzI3Mg4PwYE0Zl4jg55cMzc4NldgKoMggRnhaXByaW9D43NwZWFrIRs3YIb1X3Bob25liAYM+nRpY2ZebmVlITJfVCVhMnJ5X3ZpZXePaiYwdG9rZW5mXmlRmJLxJ2DhadEAHORW52NvbbF4ZCEbJ2Bjb3VudHJ5PVVTZl5W5wNJX2luaGVB42Vkll2S8QHCgIA3YGJhZGdlcz1vASV3b2xm6CNCZTY0SGFzaEOj81VJRD1jY2kAAACAZWJtbGJpbmtwbmNrbW1tbmhtZGhiZ2tmZG1wamRlZ+AAAKBtbGNlazFllIjxmF9maWxldHJhbnNmZXJfYmFuZHdpZCHYc48BR/ExkuIjkIghQTQ=",
|
|
||||||
};
|
|
||||||
|
|
||||||
List<Packet> 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();
|
|
||||||
reassembly.setPacketId(2);
|
|
||||||
|
|
||||||
for (Packet piece : pieces) {
|
|
||||||
reassembly.put(piece);
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet reassembled;
|
|
||||||
while (((reassembled = reassembly.next()) != null)) {
|
|
||||||
Ts3Debugging.debug(reassembled.getHeader().getPacketId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -17,148 +17,149 @@ import static org.junit.Assert.assertEquals;
|
|||||||
|
|
||||||
public class ServerConnectionTest {
|
public class ServerConnectionTest {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
try {
|
while (true) {
|
||||||
Ts3Debugging.setEnabled(true);
|
try {
|
||||||
|
Ts3Debugging.setEnabled(true);
|
||||||
|
|
||||||
LocalIdentity identity = LocalIdentity.load(
|
LocalIdentity identity = LocalIdentity.load(
|
||||||
new BigInteger(Base64.getDecoder().decode("Tj6YXM3qyRv8n25L2pH+OEJnRUl4auQf8+znjYrOmWU="))
|
new BigInteger(Base64.getDecoder().decode("Tj6YXM3qyRv8n25L2pH+OEJnRUl4auQf8+znjYrOmWU="))
|
||||||
);
|
);
|
||||||
|
|
||||||
identity.improveSecurity(10);
|
identity.improveSecurity(10);
|
||||||
|
|
||||||
LocalTeamspeakClientSocket client = new LocalTeamspeakClientSocket();
|
LocalTeamspeakClientSocket client = new LocalTeamspeakClientSocket();
|
||||||
|
|
||||||
client.setIdentity(identity);
|
client.setIdentity(identity);
|
||||||
|
|
||||||
client.setNickname("Hello from Java");
|
client.setNickname("Hello from Java");
|
||||||
|
|
||||||
client.setOption("client.hwid", "JAVAJAVAJAVA");
|
client.setOption("client.hwid", "JAVAJAVAJAVA");
|
||||||
|
|
||||||
client.connect(
|
client.connect(
|
||||||
new InetSocketAddress(
|
new InetSocketAddress(
|
||||||
"ts.teamlixo.net",
|
"ts.teamlixo.net",
|
||||||
9987
|
9987
|
||||||
),
|
),
|
||||||
null,
|
null,
|
||||||
10000L
|
10000L
|
||||||
);
|
);
|
||||||
|
|
||||||
client.addListener(new TS3Listener() {
|
client.addListener(new TS3Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onTextMessage(TextMessageEvent e) {
|
public void onTextMessage(TextMessageEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientJoin(ClientJoinEvent e) {
|
public void onClientJoin(ClientJoinEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientLeave(ClientLeaveEvent e) {
|
public void onClientLeave(ClientLeaveEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServerEdit(ServerEditedEvent e) {
|
public void onServerEdit(ServerEditedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelEdit(ChannelEditedEvent e) {
|
public void onChannelEdit(ChannelEditedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelDescriptionChanged(ChannelDescriptionEditedEvent e) {
|
public void onChannelDescriptionChanged(ChannelDescriptionEditedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientMoved(ClientMovedEvent e) {
|
public void onClientMoved(ClientMovedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelCreate(ChannelCreateEvent e) {
|
public void onChannelCreate(ChannelCreateEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelDeleted(ChannelDeletedEvent e) {
|
public void onChannelDeleted(ChannelDeletedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelMoved(ChannelMovedEvent e) {
|
public void onChannelMoved(ChannelMovedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelPasswordChanged(ChannelPasswordChangedEvent e) {
|
public void onChannelPasswordChanged(ChannelPasswordChangedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelList(ChannelListEvent e) {
|
public void onChannelList(ChannelListEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrivilegeKeyUsed(PrivilegeKeyUsedEvent e) {
|
public void onPrivilegeKeyUsed(PrivilegeKeyUsedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelGroupList(ChannelGroupListEvent e) {
|
public void onChannelGroupList(ChannelGroupListEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServerGroupList(ServerGroupListEvent e) {
|
public void onServerGroupList(ServerGroupListEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientNeededPermissions(ClientNeededPermissionsEvent e) {
|
public void onClientNeededPermissions(ClientNeededPermissionsEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientChannelGroupChanged(ClientChannelGroupChangedEvent e) {
|
public void onClientChannelGroupChanged(ClientChannelGroupChangedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientChanged(ClientUpdatedEvent e) {
|
public void onClientChanged(ClientUpdatedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnected(DisconnectedEvent e) {
|
public void onDisconnected(DisconnectedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelSubscribed(ChannelSubscribedEvent e) {
|
public void onChannelSubscribed(ChannelSubscribedEvent e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final long[] t = {System.currentTimeMillis()};
|
assertEquals(client.getState(), ClientConnectionState.CONNECTED);
|
||||||
|
|
||||||
assertEquals(client.getState(), ClientConnectionState.CONNECTED);
|
client.subscribeAll();
|
||||||
|
|
||||||
client.subscribeAll();
|
client.listClients();
|
||||||
|
|
||||||
while (client.isConnected()) {
|
|
||||||
for (Client c : client.listClients())
|
|
||||||
client.getClientInfo(c.getId());
|
|
||||||
|
|
||||||
Thread.sleep(1000L);
|
Thread.sleep(1000L);
|
||||||
|
|
||||||
|
client.listClients();
|
||||||
|
|
||||||
|
client.disconnect();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user