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:
2026-08-13 07:42:08 +00:00
parent f912cab07b
commit 17ad6cde1c
12 changed files with 880 additions and 38 deletions

View File

@@ -2,6 +2,7 @@ package com.ts3client.ui;
import com.ts3client.config.Bookmark;
import com.ts3client.config.Bookmarks;
import com.ts3client.config.IdentityStore;
import javax.swing.BorderFactory;
import javax.swing.Box;
@@ -26,14 +27,17 @@ import java.util.function.Consumer;
public final class BookmarksDialog extends JDialog {
private final Bookmarks bookmarks;
private final IdentityStore identities;
private final Consumer<Bookmark> onConnect;
private final Runnable onChanged;
private final DefaultListModel<Bookmark> listModel = new DefaultListModel<>();
private final JList<Bookmark> list = new JList<>(listModel);
public BookmarksDialog(Frame owner, Bookmarks bookmarks, Consumer<Bookmark> onConnect, Runnable onChanged) {
public BookmarksDialog(Frame owner, Bookmarks bookmarks, IdentityStore identities,
Consumer<Bookmark> onConnect, Runnable onChanged) {
super(owner, "Manage Bookmarks", true);
this.bookmarks = bookmarks;
this.identities = identities;
this.onConnect = onConnect;
this.onChanged = onChanged;
@@ -120,6 +124,7 @@ public final class BookmarksDialog extends JDialog {
JTextField port = new JTextField(Integer.toString(b.port));
JTextField nick = new JTextField(b.nickname == null ? "" : b.nickname);
JPasswordField password = new JPasswordField(b.password == null ? "" : b.password);
IdentityChooser identity = new IdentityChooser(identities, true, b.identityId);
JPanel form = new JPanel(new GridLayout(0, 1, 0, 2));
form.add(new JLabel("Label:"));
@@ -132,6 +137,8 @@ public final class BookmarksDialog extends JDialog {
form.add(nick);
form.add(new JLabel("Password (optional):"));
form.add(password);
form.add(new JLabel("Identity:"));
form.add(identity);
int result = JOptionPane.showConfirmDialog(this, form,
"Bookmark", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
@@ -150,6 +157,7 @@ public final class BookmarksDialog extends JDialog {
}
b.nickname = nick.getText().trim();
b.password = new String(password.getPassword());
b.identityId = identity.getSelectedIdentityId();
return true;
}
}