Name chat logs by the server's unique id for guests too

The id came from initserver, which never carries it, then from
serverinfo and servergetvariables, which a guest may not use; chat logs
only worked with admin rights. ts3j now derives it from the server's
handshake key, as the official client does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 10:35:41 +00:00
parent d074ffaa7a
commit eeccb495eb
2 changed files with 5 additions and 70 deletions

View File

@@ -4,10 +4,10 @@ import com.github.manevolent.ts3j.api.Client;
import com.github.manevolent.ts3j.command.CommandException;
import com.github.manevolent.ts3j.command.MultiCommand;
import com.github.manevolent.ts3j.command.SingleCommand;
import com.github.manevolent.ts3j.command.parameter.CommandParameter;
import com.github.manevolent.ts3j.command.parameter.CommandSingleParameter;
import com.github.manevolent.ts3j.event.*;
import com.github.manevolent.ts3j.identity.LocalIdentity;
import com.github.manevolent.ts3j.identity.Uid;
import com.github.manevolent.ts3j.protocol.ProtocolRole;
import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
import com.github.manevolent.ts3j.util.Ts3Crypt;
@@ -35,7 +35,6 @@ import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -1394,7 +1393,7 @@ public final class TeamspeakConnection implements TS3Listener {
String uniqueId = serverUniqueId();
if (uniqueId == null) {
chatLogs = null;
ui.onStatus("Chat logs unavailable: server unique id was not reported");
ui.onStatus("Chat logs unavailable: the server's unique id is not known");
return;
}
ChatLogStore logs = new ChatLogStore(uniqueId);
@@ -1413,72 +1412,8 @@ public final class TeamspeakConnection implements TS3Listener {
}
private String serverUniqueId() {
String uniqueId = validServerUniqueId(firstPresent(
client.getServerProperties().get("virtualserver_unique_identifier"),
client.getServerProperties().get("virtualserver_unique_id")));
if (uniqueId != null) return uniqueId;
uniqueId = serverUniqueIdFrom(new SingleCommand("serverinfo", ProtocolRole.CLIENT));
if (uniqueId != null) return uniqueId;
try {
SingleCommand command = new SingleCommand("servergetvariables", ProtocolRole.CLIENT);
String serverId = client.getServerProperties().get("virtualserver_id");
if (serverId != null && !serverId.isBlank()) {
command.add(new CommandSingleParameter("virtualserver_id", serverId));
}
return serverUniqueIdFrom(command);
} catch (Exception ignored) {
return null;
}
}
private String serverUniqueIdFrom(SingleCommand command) {
try {
for (SingleCommand response : client.executeCommand(command).get()) {
String uniqueId = validServerUniqueId(firstPresent(
parameterValue(response, "virtualserver_unique_identifier"),
parameterValue(response, "virtualserver_unique_id")));
if (uniqueId != null) return uniqueId;
}
return null;
} catch (Exception e) {
return null;
}
}
private static String validServerUniqueId(String value) {
if (value == null || value.isBlank()) return null;
try {
byte[] decoded = Base64.getDecoder().decode(value);
if (decoded.length != 20) return null;
// TS3 server UIDs are SHA-1-sized binary identifiers represented as base64.
// Plain host strings are rejected before they can become log folder names.
boolean printable = true;
for (byte b : decoded) {
int c = b & 0xff;
if (c < 0x20 || c > 0x7e) {
printable = false;
break;
}
}
return printable ? null : value;
} catch (IllegalArgumentException e) {
return null;
}
}
private static String firstPresent(String... values) {
for (String value : values) {
if (value != null && !value.isBlank()) return value;
}
return null;
}
private static String parameterValue(SingleCommand command, String key) {
CommandParameter parameter = command.get(key);
return parameter == null ? null : parameter.getValue();
Uid uid = client.getServerUid();
return uid == null ? null : uid.toBase64();
}
public void loadPrivateChatHistory(int clientId, String uniqueId) {

2
ts3j

Submodule ts3j updated: 8273a27160...c47bbdf96c