Drop the commons-lang and dnsjava dependencies
Both were pulled in for a single call each: commons-lang for ConstructorUtils.invokeConstructor when building a packet handler, and dnsjava for the _ts3._udp SRV lookup. Together they added over a megabyte to a shaded jar (and dnsjava drops jnamed/update classes into the jar root). Plain reflection and JNDI's dns: provider cover both. Also drop the BouncyCastleProvider registration: every digest here is requested by a name the SUN provider already answers, so the only thing it accomplished was keeping the whole JCE provider, the post-quantum suite and the X.509 stack reachable for a shaded-jar tree-shaker. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -40,18 +40,6 @@
|
|||||||
<version>1.67</version>
|
<version>1.67</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-lang</groupId>
|
|
||||||
<artifactId>commons-lang</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>dnsjava</groupId>
|
|
||||||
<artifactId>dnsjava</artifactId>
|
|
||||||
<version>2.1.8</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ini4j</groupId>
|
<groupId>org.ini4j</groupId>
|
||||||
<artifactId>ini4j</artifactId>
|
<artifactId>ini4j</artifactId>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.github.manevolent.ts3j.protocol;
|
package com.github.manevolent.ts3j.protocol;
|
||||||
|
|
||||||
import org.xbill.DNS.*;
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.Attribute;
|
||||||
|
import javax.naming.directory.Attributes;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class TS3DNS {
|
public class TS3DNS {
|
||||||
private static final int TS3_VOICE_DEFAULT_PORT = 9987;
|
private static final int TS3_VOICE_DEFAULT_PORT = 9987;
|
||||||
@@ -18,23 +18,56 @@ public class TS3DNS {
|
|||||||
private static final String DNS_PREFIX_TCP = "_tsdns._tcp.";
|
private static final String DNS_PREFIX_TCP = "_tsdns._tcp.";
|
||||||
private static final String DNS_PREFIX_UDP = "_ts3._udp.";
|
private static final String DNS_PREFIX_UDP = "_ts3._udp.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SRV record, as returned by JNDI: "priority weight port target."
|
||||||
|
*/
|
||||||
|
private static final class SrvRecord {
|
||||||
|
private final int priority, weight, port;
|
||||||
|
private final String target;
|
||||||
|
|
||||||
|
private SrvRecord(String record) {
|
||||||
|
String[] parts = record.trim().split("\\s+");
|
||||||
|
if (parts.length < 4) throw new IllegalArgumentException("malformed SRV record: " + record);
|
||||||
|
|
||||||
|
this.priority = Integer.parseInt(parts[0]);
|
||||||
|
this.weight = Integer.parseInt(parts[1]);
|
||||||
|
this.port = Integer.parseInt(parts[2]);
|
||||||
|
|
||||||
|
// Trim the trailing dot of the fully-qualified target name.
|
||||||
|
String target = parts[3];
|
||||||
|
this.target = target.endsWith(".") ? target.substring(0, target.length() - 1) : target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static List<InetSocketAddress> lookupSRV(String domain) throws IOException {
|
private static List<InetSocketAddress> lookupSRV(String domain) throws IOException {
|
||||||
org.xbill.DNS.Record[] records = new Lookup(domain, Type.SRV).run();
|
Attribute attribute;
|
||||||
|
|
||||||
if (records == null || records.length <= 0) throw new UnknownHostException("Host not found");
|
try {
|
||||||
|
Attributes attributes = new InitialDirContext().getAttributes("dns:/" + domain, new String[] { "SRV" });
|
||||||
|
attribute = attributes.get("SRV");
|
||||||
|
} catch (NamingException e) {
|
||||||
|
throw new UnknownHostException("Host not found: " + domain);
|
||||||
|
}
|
||||||
|
|
||||||
return Arrays.stream(records)
|
if (attribute == null || attribute.size() <= 0) throw new UnknownHostException("Host not found");
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.map(x -> (SRVRecord) x)
|
List<SrvRecord> records = new ArrayList<>(attribute.size());
|
||||||
.filter(x -> x.getTarget() != null)
|
|
||||||
.sorted((a, b) -> {
|
try {
|
||||||
// Loose sorting
|
for (int i = 0; i < attribute.size(); i++)
|
||||||
int prioComp = Integer.compare(a.getPriority(), b.getPriority());
|
records.add(new SrvRecord((String) attribute.get(i)));
|
||||||
if (prioComp != 0) return prioComp;
|
} catch (NamingException e) {
|
||||||
else return Integer.compare(a.getWeight(), b.getWeight());
|
throw new IOException(e);
|
||||||
})
|
}
|
||||||
.map(x -> new InetSocketAddress(x.getTarget().toString(), x.getPort()))
|
|
||||||
.collect(Collectors.toList());
|
// Loose sorting
|
||||||
|
records.sort(Comparator.comparingInt((SrvRecord x) -> x.priority).thenComparingInt(x -> x.weight));
|
||||||
|
|
||||||
|
List<InetSocketAddress> addresses = new ArrayList<>(records.size());
|
||||||
|
for (SrvRecord record : records)
|
||||||
|
addresses.add(new InetSocketAddress(record.target, record.port));
|
||||||
|
|
||||||
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<InetSocketAddress> lookup(String domain) throws IOException {
|
public static List<InetSocketAddress> lookup(String domain) throws IOException {
|
||||||
|
|||||||
+7
-2
@@ -24,7 +24,6 @@ import com.github.manevolent.ts3j.util.QuickLZ;
|
|||||||
import com.github.manevolent.ts3j.util.Ts3Crypt;
|
import com.github.manevolent.ts3j.util.Ts3Crypt;
|
||||||
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
||||||
import com.github.manevolent.ts3j.util.Pair;
|
import com.github.manevolent.ts3j.util.Pair;
|
||||||
import org.apache.commons.lang.reflect.ConstructorUtils;
|
|
||||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
@@ -1466,6 +1465,12 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
}
|
}
|
||||||
|
|
||||||
private PacketHandler createHandler(Class<? extends PacketHandler> clazz) throws ReflectiveOperationException {
|
private PacketHandler createHandler(Class<? extends PacketHandler> clazz) throws ReflectiveOperationException {
|
||||||
return (PacketHandler) ConstructorUtils.invokeConstructor(clazz, this);
|
for (java.lang.reflect.Constructor<?> constructor : clazz.getConstructors()) {
|
||||||
|
Class<?>[] parameters = constructor.getParameterTypes();
|
||||||
|
if (parameters.length == 1 && parameters[0].isInstance(this))
|
||||||
|
return (PacketHandler) constructor.newInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NoSuchMethodException(clazz.getName() + " has no constructor accepting " + getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,6 @@ import java.security.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public final class Ts3Crypt {
|
public final class Ts3Crypt {
|
||||||
static {
|
|
||||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] hash128(byte[] data, int offs, int len) {
|
public static byte[] hash128(byte[] data, int offs, int len) {
|
||||||
try {
|
try {
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
||||||
|
|||||||
Reference in New Issue
Block a user