-
Notifications
You must be signed in to change notification settings - Fork 0
Conversations
To reply to a received packet, use Connection#reply(packet, response).
Example:
client.addPacketListener((packet, conn, wait) -> {
if (packet instanceof TokenRequestPacket)
conn.reply(packet, new TokenPacket(2718281828)); // Client#reply works too
});
You can attach a response packet listener when sending a packet. You can also use Connection#sendPacketWithResponse to avoid lots of nested callbacks in a long conversation. However, refer to the WaitState section to avoid issues with blocking when using this method.
If you want to extend the amount of time response listeners stick around, use Connection#setTimeout. If you set the timeout to -1, you must remove the response listener later to prevent memory leaks.
Example:
// Using nested callbacks
server.addConnectionListener((conn, wait) -> {
conn.sendPacket(new TokenRequestPacket(), (response, conn2, wait2) -> {
if (response instanceof TokenPacket token && token.getToken() == 2718281828)
players.add(new Player(conn));
else {
conn.reply(response, new InvalidTokenPacket(), (invalidResponse, conn3, wait3) -> {
if (invalidResponse instanceof JoinAnywayPacket && joinAnywayAllowed)
players.add(new Player(conn).setValidated(false));
else
conn.close();
});
}
});
});
// Using withResponse
server.addConnectionListener((conn, wait) -> {
wait.dontWait(); // Prevent blocking issues
Packet response = conn.sendPacketWithResponse(new TokenRequestPacket());
if (response == null) { // Response timed out (5s default)
conn.close();
return;
}
if (response instanceof TokenPacket token && token.getToken() == 2718281828) {
players.add(new Player(conn));
return;
}
response = conn.replyWithResponse(response, new InvalidTokenPacket());
if (response instanceof JoinAnywayPacket && joinAnywayAllowed)
players.add(new Player(conn).setValidated(false));
else
conn.close();
});
While a packet listener or connection listener is running, the library pauses reading in packets. This prevents race conditions in the ordering of received packets. However, this can cause issues when using a blocking function that waits for incoming packets - like sendPacketWithResponse. Since the library is not reading in packets, it can't read in the response packet that sendPacketWithResponse is waiting for. To solve this, use WaitState#dontWait() to tell the library to continue reading in packets.
Example:
client.addPacketListener((packet, conn, wait) -> {
Packet response = client.sendPacketWithResponse(new TeleportRequestPacket(3, 1, 4)); // Will freeze packet handling for timeout, then return null
wait.dontWait();
response = client.sendPacketWithResponse(new TeleportRequestPacket(2, 7, 1)); // Will work properly
if (!(response instanceof TeleportConfirmPacket))
client.close();
});