Add identity management
Manage several TeamSpeak identities like the official client instead of using one auto-generated identity file. - IdentityStore/IdentityEntry keep each identity as a TeamSpeak-format INI in ~/.ts3jclient/identities, so files interchange with the TS3 client; supports create, import, export, rename, remove and a cancellable security-level search. A legacy identity.ini is migrated in on first load. - Settings hold the default identity; bookmarks may pin their own, falling back to the default when unset. - TeamspeakConnection now connects with the identity it is handed. - Swing: Tools -> Identities manager, plus an identity drop-down in the connect and bookmark forms. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,8 @@ import com.ts3client.audio.AudioBackend;
|
||||
import com.ts3client.audio.desktop.JavaSoundAudioBackend;
|
||||
import com.ts3client.config.Bookmark;
|
||||
import com.ts3client.config.Bookmarks;
|
||||
import com.ts3client.config.IdentityEntry;
|
||||
import com.ts3client.config.IdentityStore;
|
||||
import com.ts3client.config.Settings;
|
||||
import com.ts3client.net.ChannelNode;
|
||||
import com.ts3client.net.ClientEntry;
|
||||
@@ -43,9 +45,13 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
|
||||
private final Settings settings;
|
||||
private final Bookmarks bookmarks = Bookmarks.load();
|
||||
private final IdentityStore identities;
|
||||
private final AudioBackend audio = new JavaSoundAudioBackend();
|
||||
private TeamspeakConnection conn;
|
||||
|
||||
/** Identity of the current/last connection, so it can be saved into a bookmark. */
|
||||
private String currentIdentityId = "";
|
||||
|
||||
private JMenu bookmarksMenu;
|
||||
private JCheckBoxMenuItem awayItem;
|
||||
private JCheckBoxMenuItem commanderItem;
|
||||
@@ -73,6 +79,7 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
public MainFrame(Settings settings) {
|
||||
super("TS3J — TeamSpeak 3 Java Client");
|
||||
this.settings = settings;
|
||||
this.identities = IdentityStore.load(settings);
|
||||
|
||||
setIconImage(Icons.app().getImage());
|
||||
// We tear the connection down ourselves on close, so don't let Swing kill the JVM.
|
||||
@@ -165,8 +172,12 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
self.add(rename);
|
||||
|
||||
JMenu tools = new JMenu("Tools");
|
||||
JMenuItem identitiesItem = new JMenuItem("Identities…");
|
||||
identitiesItem.addActionListener(e -> showIdentities());
|
||||
JMenuItem options = new JMenuItem("Options…");
|
||||
options.addActionListener(e -> showSettings());
|
||||
tools.add(identitiesItem);
|
||||
tools.addSeparator();
|
||||
tools.add(options);
|
||||
|
||||
JMenu help = new JMenu("Help");
|
||||
@@ -193,7 +204,7 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
JMenuItem addCurrent = new JMenuItem("Add current server…");
|
||||
addCurrent.addActionListener(e -> addCurrentServerBookmark());
|
||||
JMenuItem manage = new JMenuItem("Manage bookmarks…");
|
||||
manage.addActionListener(e -> new BookmarksDialog(this, bookmarks,
|
||||
manage.addActionListener(e -> new BookmarksDialog(this, bookmarks, identities,
|
||||
this::connectToBookmark, this::rebuildBookmarksMenu).setVisible(true));
|
||||
bookmarksMenu.add(addCurrent);
|
||||
bookmarksMenu.add(manage);
|
||||
@@ -290,13 +301,16 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
"Connect", JOptionPane.INFORMATION_MESSAGE);
|
||||
return;
|
||||
}
|
||||
ConnectDialog dlg = new ConnectDialog(this, settings);
|
||||
ConnectDialog dlg = new ConnectDialog(this, settings, identities);
|
||||
dlg.setVisible(true);
|
||||
if (!dlg.isConfirmed()) return;
|
||||
startConnection(dlg.getAddress(), dlg.getPort(), dlg.getNickname(), dlg.getPassword());
|
||||
startConnection(dlg.getAddress(), dlg.getPort(), dlg.getNickname(), dlg.getPassword(), dlg.getIdentityId());
|
||||
}
|
||||
|
||||
private void startConnection(String address, int port, String nickname, String password) {
|
||||
/**
|
||||
* @param identityId identity to use, or empty for the default one
|
||||
*/
|
||||
private void startConnection(String address, int port, String nickname, String password, String identityId) {
|
||||
if (conn.isConnected()) {
|
||||
JOptionPane.showMessageDialog(this, "Already connected. Disconnect first.",
|
||||
"Connect", JOptionPane.INFORMATION_MESSAGE);
|
||||
@@ -307,12 +321,28 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
settings.serverPassword = password;
|
||||
settings.save();
|
||||
chatPanel.appendSystem("Connecting to " + address + ":" + port + " …");
|
||||
conn.connect(address, port, nickname, password);
|
||||
|
||||
// Resolving may have to generate a first identity, so keep it off the EDT.
|
||||
onStatus("Loading identity…");
|
||||
new Thread(() -> {
|
||||
final IdentityEntry entry;
|
||||
try {
|
||||
entry = identities.resolve(settings, identityId);
|
||||
} catch (Exception e) {
|
||||
onError("Could not load identity: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
currentIdentityId = entry.getId();
|
||||
chatPanel.appendSystem("Using identity \"" + entry.getName() + "\".");
|
||||
});
|
||||
conn.connect(address, port, nickname, password, entry.getIdentity());
|
||||
}, "identity-resolve").start();
|
||||
}
|
||||
|
||||
private void connectToBookmark(Bookmark b) {
|
||||
String nick = (b.nickname != null && !b.nickname.isBlank()) ? b.nickname : settings.nickname;
|
||||
startConnection(b.address, b.port, nick, b.password);
|
||||
startConnection(b.address, b.port, nick, b.password, b.identityId);
|
||||
}
|
||||
|
||||
private void addCurrentServerBookmark() {
|
||||
@@ -328,7 +358,9 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
}
|
||||
String label = JOptionPane.showInputDialog(this, "Bookmark label:", addr);
|
||||
if (label == null) return;
|
||||
bookmarks.add(new Bookmark(label.trim(), addr, port, settings.nickname, settings.serverPassword));
|
||||
Bookmark bookmark = new Bookmark(label.trim(), addr, port, settings.nickname, settings.serverPassword);
|
||||
bookmark.identityId = currentIdentityId;
|
||||
bookmarks.add(bookmark);
|
||||
bookmarks.save();
|
||||
rebuildBookmarksMenu();
|
||||
}
|
||||
@@ -371,6 +403,10 @@ public final class MainFrame extends JFrame implements ConnectionListener, Serve
|
||||
}
|
||||
}
|
||||
|
||||
private void showIdentities() {
|
||||
new IdentitiesDialog(this, identities, settings, bookmarks, null).setVisible(true);
|
||||
}
|
||||
|
||||
private void showSettings() {
|
||||
SettingsDialog dlg = new SettingsDialog(this, settings,
|
||||
conn.getMicrophone(), conn.getPlayback(), () -> {
|
||||
|
||||
Reference in New Issue
Block a user