Kick and ban clients from the context menu
The client menu gains "Kick Client from Channel", "Kick Client from Server" and "Ban Client", each asking for a reason first. Kicks use a shared prompt that enforces the protocol's 40-character limit; the ban dialog adds a duration, whose unit dropdown ends in "Permanent" — the zero-length ban the server understands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,10 @@ public final class TeamspeakConnection implements TS3Listener {
|
||||
/** Upper bound for a downloaded group icon; anything larger is not an icon. */
|
||||
private static final int MAX_ICON_BYTES = 1024 * 1024;
|
||||
|
||||
/** The protocol's reason ids for the two flavours of <b>clientkick</b>. */
|
||||
private static final int REASON_KICK_CHANNEL = 4;
|
||||
private static final int REASON_KICK_SERVER = 5;
|
||||
|
||||
/** Shortest gap between two "you are talking while muted" reminders. */
|
||||
private static final long MUTED_TALK_COOLDOWN_NANOS = 5_000_000_000L;
|
||||
|
||||
@@ -520,6 +524,48 @@ public final class TeamspeakConnection implements TS3Listener {
|
||||
}, "ts3j-move-client").start();
|
||||
}
|
||||
|
||||
/** Kicks a client out of its channel, back into the server's default one. */
|
||||
public void kickFromChannel(int clientId, String reason) {
|
||||
kick(clientId, REASON_KICK_CHANNEL, reason, "Could not kick client from the channel: ");
|
||||
}
|
||||
|
||||
/** Kicks a client off the server entirely. */
|
||||
public void kickFromServer(int clientId, String reason) {
|
||||
kick(clientId, REASON_KICK_SERVER, reason, "Could not kick client from the server: ");
|
||||
}
|
||||
|
||||
private void kick(int clientId, int reasonId, String reason, String errorPrefix) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
SingleCommand cmd = new SingleCommand("clientkick", ProtocolRole.CLIENT);
|
||||
cmd.add(new CommandSingleParameter("clid", Integer.toString(clientId)));
|
||||
cmd.add(new CommandSingleParameter("reasonid", Integer.toString(reasonId)));
|
||||
if (reason != null && !reason.isEmpty()) {
|
||||
cmd.add(new CommandSingleParameter("reasonmsg", reason));
|
||||
}
|
||||
client.executeCommand(cmd).complete();
|
||||
} catch (Exception e) {
|
||||
error(errorPrefix + rootMessage(e));
|
||||
}
|
||||
}, "ts3j-kick").start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bans a client from the server.
|
||||
*
|
||||
* @param seconds how long the ban lasts, or 0 for a permanent one
|
||||
*/
|
||||
public void banClient(int clientId, long seconds, String reason) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
client.banClient(clientId, seconds <= 0 ? null : (int) Math.min(seconds, Integer.MAX_VALUE),
|
||||
reason == null || reason.isEmpty() ? null : reason);
|
||||
} catch (Exception e) {
|
||||
error("Could not ban client: " + rootMessage(e));
|
||||
}
|
||||
}, "ts3j-ban").start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-parents and repositions a channel.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user