diff --git a/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java b/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java index 8c54500..94a9cd4 100644 --- a/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java +++ b/ts3-client/core/src/main/java/com/ts3client/session/ServerSession.java @@ -56,6 +56,13 @@ public final class ServerSession { private volatile boolean connecting; /** Identity used for the current connection, so it can be saved into a bookmark. */ private volatile String identityId = ""; + /** How the last connect was made, for {@link #reconnect}; null before the first one. */ + private volatile Target lastTarget; + /** The channel we were in when the connection last went, to return to on a reconnect. */ + private volatile String lastChannelPath = ""; + + private record Target(String address, int port, String nickname, String password, String channelPassword) { + } private volatile boolean micMuted; private volatile boolean micLocalMuted; @@ -120,6 +127,8 @@ public final class ServerSession { if (isBusy()) return; connecting = true; } + lastTarget = new Target(address, port, nickname, password, channelPassword); + lastChannelPath = channel == null ? "" : channel; title = address + ":" + port; listener.onSystemMessage("Connecting to " + address + ":" + port + (channel == null || channel.isBlank() ? "" : " (channel \"" + channel + "\")") + " …"); @@ -158,6 +167,19 @@ public final class ServerSession { }, "ts3j-switch-server").start(); } + /** + * Connects again to the server of the last connect, with the same identity, returning to + * the channel we were in — for a connection that dropped, or a network that changed. + * Leaves the server first if still on it. Does nothing before a first connect. + */ + public void reconnect() { + Target target = lastTarget; + if (target == null) return; + String channel = conn.isConnected() ? currentChannelPath() : lastChannelPath; + switchTo(target.address(), target.port(), target.nickname(), target.password(), identityId, + channel, target.channelPassword()); + } + public void disconnect() { if (conn.isConnected()) conn.disconnect(); } @@ -393,6 +415,9 @@ public final class ServerSession { @Override public void onModelChanged() { + // By the time a connection is reported gone, it no longer knows where we were. + String channel = currentChannelPath(); + if (!channel.isEmpty()) lastChannelPath = channel; String name = conn.getModel().getServerName(); if (conn.isConnected() && name != null && !name.isBlank() && !name.equals(title)) { title = name;