Add the contact list (friends, blocked, neutral)
Mirrors the TeamSpeak 3 client's Contacts: clients can be filed as friend,
blocked or neutral from their context menu or by dragging them into the
Contacts window, given a custom and phonetic nickname, shown under either
name or both, and per contact muted automatically, ignored in server/channel
or private chat and pokes, have their away message hidden and whispers
allowed or denied. Friends are green and blocked clients red in the tree
(optional), new contacts start from per-type defaults ("Set Defaults"), and
the global whisper policy lives in Options -> Contacts. "Change Volume..."
adds a per-client dB gain that a contact entry remembers.
Contacts are stored in ~/.ts3jclient/contacts.txt using the exact record
format the official client keeps in the Contacts table of its settings.db
(field names and codes recovered from the binary), so entries move between
the two verbatim. A small read-only pure-Java SQLite reader imports the
official client's list on first run and on demand, without a driver.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import com.ts3client.config.IdentityEntry;
|
||||
import com.ts3client.config.IdentityStore;
|
||||
import com.ts3client.config.BanReasonPresets;
|
||||
import com.ts3client.config.Settings;
|
||||
import com.ts3client.contacts.ContactStore;
|
||||
import com.ts3client.net.ChannelNode;
|
||||
import com.ts3client.net.ClientEntry;
|
||||
import com.ts3client.net.ServerModel;
|
||||
@@ -64,7 +65,7 @@ final class ServerTab implements ServerTabConnectionEvents.Listener {
|
||||
private BanListDialog banList;
|
||||
|
||||
ServerTab(MainFrame host, Settings settings, IdentityStore identities, AudioBackend audio,
|
||||
SoundNotifier sounds) {
|
||||
SoundNotifier sounds, ContactStore contacts) {
|
||||
this.host = host;
|
||||
this.settings = settings;
|
||||
this.identities = identities;
|
||||
@@ -74,12 +75,12 @@ final class ServerTab implements ServerTabConnectionEvents.Listener {
|
||||
// panels and the other tab helpers that read from it — so wiring finishes with
|
||||
// an explicit attach() once everything is built. Nothing fires callbacks before then.
|
||||
this.events = new ServerTabConnectionEvents(host, this, this);
|
||||
this.conn = new TeamspeakConnection(settings, audio, events, sounds);
|
||||
this.conn = new TeamspeakConnection(settings, audio, events, sounds, contacts);
|
||||
this.groupIcons = new GroupIcons(conn.getIcons());
|
||||
this.selfState = new ServerTabSelfState(conn);
|
||||
this.chatPanel = new ChatPanel();
|
||||
this.treeActions = new ServerTabTreeActions(host, this, conn, chatPanel, infoPanel, groupIcons);
|
||||
this.treePanel = new ServerTreePanel(conn.getModel(), groupIcons, treeActions);
|
||||
this.treePanel = new ServerTreePanel(conn.getModel(), groupIcons, contacts, settings, treeActions);
|
||||
treeActions.attach(treePanel);
|
||||
events.attach(conn, treePanel, chatPanel, selfState, treeActions);
|
||||
|
||||
@@ -298,6 +299,13 @@ final class ServerTab implements ServerTabConnectionEvents.Listener {
|
||||
else banList.connectionLost();
|
||||
}
|
||||
|
||||
/** The contact list changed: names, colours and per-client playback follow. */
|
||||
void contactsChanged() {
|
||||
conn.applyContacts();
|
||||
treePanel.refreshRowSizes();
|
||||
treeActions.renderInfo();
|
||||
}
|
||||
|
||||
/** Releases the background resources of a tab that is being thrown away. */
|
||||
void dispose() {
|
||||
conn.getIcons().shutdown();
|
||||
@@ -388,7 +396,7 @@ final class ServerTab implements ServerTabConnectionEvents.Listener {
|
||||
|
||||
private String peerName(int clientId) {
|
||||
ClientEntry c = conn.getModel().getClient(clientId);
|
||||
return c != null ? c.nickname : "Client " + clientId;
|
||||
return c != null ? conn.displayName(c) : "Client " + clientId;
|
||||
}
|
||||
|
||||
/** Joins the channel at a "/"-separated path, as the hotkey action names it. */
|
||||
|
||||
Reference in New Issue
Block a user