Keep the error id a server refused the last connect with

The message alone does not tell a ban from a refusal worth retrying.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 18:30:23 +00:00
parent 25ca586a50
commit 2281c125fa

View File

@@ -141,6 +141,8 @@ public final class TeamspeakConnection implements TS3Listener {
/** Guards against announcing the same disconnect from both the event and the teardown. */ /** Guards against announcing the same disconnect from both the event and the teardown. */
private volatile boolean disconnectAnnounced = true; private volatile boolean disconnectAnnounced = true;
private volatile long lastMutedTalkNanos; private volatile long lastMutedTalkNanos;
/** The server's error id for why the last connect was refused; 0 when it was not. */
private volatile int connectErrorId;
public TeamspeakConnection(Settings settings, AudioBackend audio, ConnectionListener ui, public TeamspeakConnection(Settings settings, AudioBackend audio, ConnectionListener ui,
SoundNotifier sounds, ContactStore contacts) { SoundNotifier sounds, ContactStore contacts) {
@@ -173,6 +175,14 @@ public final class TeamspeakConnection implements TS3Listener {
return playback; return playback;
} }
/**
* The error id the server refused the last connect with ({@code 3329} for a ban,
* for one), or 0 when it was not refused or did not get that far.
*/
public int getConnectErrorId() {
return connectErrorId;
}
/** The identity this connection authenticated with. */ /** The identity this connection authenticated with. */
public LocalIdentity getIdentity() { public LocalIdentity getIdentity() {
return identity; return identity;
@@ -257,6 +267,7 @@ public final class TeamspeakConnection implements TS3Listener {
String channel, String channelPassword) { String channel, String channelPassword) {
Object attempt = new Object(); Object attempt = new Object();
connectAttempt = attempt; connectAttempt = attempt;
connectErrorId = 0;
// A socket or audio line an earlier connect left behind must not outlive it. // A socket or audio line an earlier connect left behind must not outlive it.
connected = false; connected = false;
safeCleanup(); safeCleanup();
@@ -363,6 +374,7 @@ public final class TeamspeakConnection implements TS3Listener {
// connect has set up in the meantime. // connect has set up in the meantime.
if (connectAttempt != attempt) return; if (connectAttempt != attempt) return;
connected = false; connected = false;
connectErrorId = refusalId(e);
String failure = "Connection failed: " + rootMessage(e) + versionHint(e); String failure = "Connection failed: " + rootMessage(e) + versionHint(e);
ui.onError(failure); ui.onError(failure);
safeCleanup(); safeCleanup();
@@ -373,6 +385,13 @@ public final class TeamspeakConnection implements TS3Listener {
} }
} }
private static int refusalId(Throwable e) {
for (Throwable t = e; t != null; t = t.getCause()) {
if (t instanceof CommandException refusal) return refusal.getErrorId();
}
return 0;
}
/** /**
* "client is modified" is what a server answers when it does not accept the reported * "client is modified" is what a server answers when it does not accept the reported
* version: too old for its minimum, not a version it knows for that platform, or a * version: too old for its minimum, not a version it knows for that platform, or a