mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 01:16:46 -04:00
dns handling: srv resolving
This commit is contained in:
parent
983c3844dd
commit
04ab1b5254
64
.idea/jarRepositories.xml
generated
64
.idea/jarRepositories.xml
generated
@ -1,35 +1,35 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="RemoteRepositoriesConfiguration">
|
<component name="RemoteRepositoriesConfiguration">
|
||||||
<remote-repository>
|
<remote-repository>
|
||||||
<option name="id" value="jitpack.io" />
|
<option name="id" value="jitpack.io"/>
|
||||||
<option name="name" value="jitpack.io" />
|
<option name="name" value="jitpack.io"/>
|
||||||
<option name="url" value="http://www.jitpack.io" />
|
<option name="url" value="http://www.jitpack.io"/>
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
<remote-repository>
|
<remote-repository>
|
||||||
<option name="id" value="jitpack.io" />
|
<option name="id" value="jitpack.io"/>
|
||||||
<option name="name" value="jitpack.io" />
|
<option name="name" value="jitpack.io"/>
|
||||||
<option name="url" value="https://www.jitpack.io" />
|
<option name="url" value="https://www.jitpack.io"/>
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
<remote-repository>
|
<remote-repository>
|
||||||
<option name="id" value="central" />
|
<option name="id" value="central"/>
|
||||||
<option name="name" value="Central Repository" />
|
<option name="name" value="Central Repository"/>
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
<option name="url" value="https://repo.maven.apache.org/maven2"/>
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
<remote-repository>
|
<remote-repository>
|
||||||
<option name="id" value="central" />
|
<option name="id" value="jitpack.io"/>
|
||||||
<option name="name" value="Maven Central repository" />
|
<option name="name" value="jitpack.io"/>
|
||||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
<option name="url" value="https://jitpack.io"/>
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
<remote-repository>
|
<remote-repository>
|
||||||
<option name="id" value="jitpack.io" />
|
<option name="id" value="central"/>
|
||||||
<option name="name" value="jitpack.io" />
|
<option name="name" value="Maven Central repository"/>
|
||||||
<option name="url" value="https://jitpack.io" />
|
<option name="url" value="https://repo1.maven.org/maven2"/>
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
<remote-repository>
|
<remote-repository>
|
||||||
<option name="id" value="jboss.community" />
|
<option name="id" value="jboss.community"/>
|
||||||
<option name="name" value="JBoss Community repository" />
|
<option name="name" value="JBoss Community repository"/>
|
||||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/"/>
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
10
pom.xml
10
pom.xml
@ -26,8 +26,8 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>11</source>
|
<source>14</source>
|
||||||
<target>11</target>
|
<target>14</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
@ -54,5 +54,11 @@
|
|||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>29.0-jre</version>
|
<version>29.0-jre</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/dnsjava/dnsjava -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>dnsjava</groupId>
|
||||||
|
<artifactId>dnsjava</artifactId>
|
||||||
|
<version>3.2.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
@ -21,6 +21,7 @@ import de.bixilon.minosoft.logging.Log;
|
|||||||
import de.bixilon.minosoft.logging.LogLevel;
|
import de.bixilon.minosoft.logging.LogLevel;
|
||||||
import de.bixilon.minosoft.mojang.api.MojangAccount;
|
import de.bixilon.minosoft.mojang.api.MojangAccount;
|
||||||
import de.bixilon.minosoft.protocol.network.Connection;
|
import de.bixilon.minosoft.protocol.network.Connection;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ConnectionReason;
|
||||||
import de.bixilon.minosoft.util.FolderUtil;
|
import de.bixilon.minosoft.util.FolderUtil;
|
||||||
import de.bixilon.minosoft.util.OSUtil;
|
import de.bixilon.minosoft.util.OSUtil;
|
||||||
import de.bixilon.minosoft.util.Util;
|
import de.bixilon.minosoft.util.Util;
|
||||||
@ -67,7 +68,7 @@ public class Minosoft {
|
|||||||
|
|
||||||
checkClientToken();
|
checkClientToken();
|
||||||
|
|
||||||
Connection c = new Connection(config.getString("debug.host"), config.getInteger("debug.port"));
|
Connection c = new Connection(config.getString("debug.host"));
|
||||||
accountList = config.getMojangAccounts();
|
accountList = config.getMojangAccounts();
|
||||||
if (accountList.size() == 0) {
|
if (accountList.size() == 0) {
|
||||||
/*
|
/*
|
||||||
@ -84,7 +85,7 @@ public class Minosoft {
|
|||||||
Log.mojang("Could not refresh session, you will not be able to join premium servers!");
|
Log.mojang("Could not refresh session, you will not be able to join premium servers!");
|
||||||
}
|
}
|
||||||
c.setPlayer(new Player(account));
|
c.setPlayer(new Player(account));
|
||||||
c.connect();
|
c.resolve(ConnectionReason.CONNECT); // resolve dns address and connect
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,17 +32,20 @@ import de.bixilon.minosoft.protocol.packets.serverbound.login.PacketLoginStart;
|
|||||||
import de.bixilon.minosoft.protocol.packets.serverbound.status.PacketStatusPing;
|
import de.bixilon.minosoft.protocol.packets.serverbound.status.PacketStatusPing;
|
||||||
import de.bixilon.minosoft.protocol.packets.serverbound.status.PacketStatusRequest;
|
import de.bixilon.minosoft.protocol.packets.serverbound.status.PacketStatusRequest;
|
||||||
import de.bixilon.minosoft.protocol.protocol.*;
|
import de.bixilon.minosoft.protocol.protocol.*;
|
||||||
|
import de.bixilon.minosoft.util.DNSUtil;
|
||||||
|
import de.bixilon.minosoft.util.ServerAddress;
|
||||||
|
import org.xbill.DNS.TextParseException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Connection {
|
public class Connection {
|
||||||
final String host;
|
final ArrayList<ServerAddress> addresses;
|
||||||
final int port;
|
|
||||||
final Network network;
|
final Network network;
|
||||||
final PacketHandler handler;
|
final PacketHandler handler;
|
||||||
final PacketSender sender;
|
final PacketSender sender;
|
||||||
final ArrayList<ClientboundPacket> handlingQueue;
|
final ArrayList<ClientboundPacket> handlingQueue;
|
||||||
final VelocityHandler velocityHandler = new VelocityHandler(this);
|
final VelocityHandler velocityHandler = new VelocityHandler(this);
|
||||||
|
ServerAddress address;
|
||||||
PluginChannelHandler pluginChannelHandler;
|
PluginChannelHandler pluginChannelHandler;
|
||||||
Thread handleThread;
|
Thread handleThread;
|
||||||
Version version = Versions.getLowestVersionSupported(); // default
|
Version version = Versions.getLowestVersionSupported(); // default
|
||||||
@ -50,11 +53,16 @@ public class Connection {
|
|||||||
Player player;
|
Player player;
|
||||||
ConnectionState state = ConnectionState.DISCONNECTED;
|
ConnectionState state = ConnectionState.DISCONNECTED;
|
||||||
ConnectionReason reason;
|
ConnectionReason reason;
|
||||||
|
ConnectionReason nextReason;
|
||||||
ConnectionPing connectionStatusPing;
|
ConnectionPing connectionStatusPing;
|
||||||
|
|
||||||
public Connection(String host, int port) {
|
public Connection(String hostname) {
|
||||||
this.host = host;
|
try {
|
||||||
this.port = port;
|
addresses = DNSUtil.getServerAddresses(hostname);
|
||||||
|
} catch (TextParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
network = new Network(this);
|
network = new Network(this);
|
||||||
handlingQueue = new ArrayList<>();
|
handlingQueue = new ArrayList<>();
|
||||||
handler = new PacketHandler(this);
|
handler = new PacketHandler(this);
|
||||||
@ -65,29 +73,41 @@ public class Connection {
|
|||||||
* Sends an server ping to the server (player count, motd, ...)
|
* Sends an server ping to the server (player count, motd, ...)
|
||||||
*/
|
*/
|
||||||
public void ping() {
|
public void ping() {
|
||||||
Log.info(String.format("Pinging server: %s:%d", host, port));
|
Log.info(String.format("Pinging server: %s", address));
|
||||||
reason = ConnectionReason.PING;
|
reason = ConnectionReason.PING;
|
||||||
network.connect();
|
network.connect(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resolve(ConnectionReason reason) {
|
||||||
|
address = addresses.get(0);
|
||||||
|
this.nextReason = reason;
|
||||||
|
Log.info(String.format("Trying to connect to %s", address));
|
||||||
|
resolve(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resolve(ServerAddress address) {
|
||||||
|
reason = ConnectionReason.DNS;
|
||||||
|
network.connect(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to connect to the server and login
|
* Tries to connect to the server and login
|
||||||
*/
|
*/
|
||||||
public void connect() {
|
public void connect() {
|
||||||
Log.info(String.format("Connecting to server: %s:%d", host, port));
|
Log.info(String.format("Connecting to server: %s", address));
|
||||||
if (reason == null) {
|
if (reason == null || reason == ConnectionReason.DNS) {
|
||||||
// first get version, then login
|
// first get version, then login
|
||||||
reason = ConnectionReason.GET_VERSION;
|
reason = ConnectionReason.GET_VERSION;
|
||||||
}
|
}
|
||||||
network.connect();
|
network.connect(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHost() {
|
public ServerAddress getAddress() {
|
||||||
return host;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPort() {
|
public ArrayList<ServerAddress> getAvailableAddresses() {
|
||||||
return port;
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectionState getConnectionState() {
|
public ConnectionState getConnectionState() {
|
||||||
@ -105,7 +125,17 @@ public class Connection {
|
|||||||
// connection established, starting threads and logging in
|
// connection established, starting threads and logging in
|
||||||
startHandlingThread();
|
startHandlingThread();
|
||||||
ConnectionState next = ((reason == ConnectionReason.CONNECT) ? ConnectionState.LOGIN : ConnectionState.STATUS);
|
ConnectionState next = ((reason == ConnectionReason.CONNECT) ? ConnectionState.LOGIN : ConnectionState.STATUS);
|
||||||
network.sendPacket(new PacketHandshake(getHost(), getPort(), next, (next == ConnectionState.STATUS) ? -1 : getVersion().getProtocolVersion()));
|
if (reason == ConnectionReason.DNS) {
|
||||||
|
// valid hostname found
|
||||||
|
if (nextReason == ConnectionReason.CONNECT) {
|
||||||
|
// connecting, we must get the version first
|
||||||
|
reason = ConnectionReason.GET_VERSION;
|
||||||
|
} else {
|
||||||
|
reason = nextReason;
|
||||||
|
}
|
||||||
|
Log.info(String.format("Connection to %s seems to be okay, connecting...", address));
|
||||||
|
}
|
||||||
|
network.sendPacket(new PacketHandshake(address, next, (next == ConnectionState.STATUS) ? -1 : getVersion().getProtocolVersion()));
|
||||||
// after sending it, switch to next state
|
// after sending it, switch to next state
|
||||||
setConnectionState(next);
|
setConnectionState(next);
|
||||||
break;
|
break;
|
||||||
@ -128,6 +158,18 @@ public class Connection {
|
|||||||
// unregister all custom recipes
|
// unregister all custom recipes
|
||||||
Recipes.removeCustomRecipes();
|
Recipes.removeCustomRecipes();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case FAILED:
|
||||||
|
// connect to next hostname, if available
|
||||||
|
int nextIndex = addresses.indexOf(address) + 1;
|
||||||
|
if (addresses.size() > nextIndex) {
|
||||||
|
ServerAddress nextAddress = addresses.get(nextIndex);
|
||||||
|
Log.warn(String.format("Could not connect to %s, trying next hostname: %s", address, nextAddress));
|
||||||
|
this.address = nextAddress;
|
||||||
|
resolve(address);
|
||||||
|
}
|
||||||
|
// else: failed
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import de.bixilon.minosoft.protocol.packets.clientbound.interfaces.PacketCompres
|
|||||||
import de.bixilon.minosoft.protocol.packets.clientbound.login.PacketLoginSuccess;
|
import de.bixilon.minosoft.protocol.packets.clientbound.login.PacketLoginSuccess;
|
||||||
import de.bixilon.minosoft.protocol.packets.serverbound.login.PacketEncryptionResponse;
|
import de.bixilon.minosoft.protocol.packets.serverbound.login.PacketEncryptionResponse;
|
||||||
import de.bixilon.minosoft.protocol.protocol.*;
|
import de.bixilon.minosoft.protocol.protocol.*;
|
||||||
|
import de.bixilon.minosoft.util.ServerAddress;
|
||||||
import de.bixilon.minosoft.util.Util;
|
import de.bixilon.minosoft.util.Util;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
@ -30,7 +31,9 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Network {
|
public class Network {
|
||||||
@ -51,7 +54,7 @@ public class Network {
|
|||||||
this.queue = new ArrayList<>();
|
this.queue = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect() {
|
public void connect(ServerAddress address) {
|
||||||
// wait for data or send until it should disconnect
|
// wait for data or send until it should disconnect
|
||||||
// first send, then receive
|
// first send, then receive
|
||||||
// something to send it, send it
|
// something to send it, send it
|
||||||
@ -61,7 +64,9 @@ public class Network {
|
|||||||
// Could not connect
|
// Could not connect
|
||||||
socketThread = new Thread(() -> {
|
socketThread = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
socket = new Socket(connection.getHost(), connection.getPort());
|
socket = new Socket();
|
||||||
|
socket.setSoTimeout(ProtocolDefinition.SOCKET_CONNECT_TIMEOUT);
|
||||||
|
socket.connect(new InetSocketAddress(address.getHostname(), address.getPort()), ProtocolDefinition.SOCKET_CONNECT_TIMEOUT);
|
||||||
connected = true;
|
connected = true;
|
||||||
connection.setConnectionState(ConnectionState.HANDSHAKING);
|
connection.setConnectionState(ConnectionState.HANDSHAKING);
|
||||||
socket.setKeepAlive(true);
|
socket.setKeepAlive(true);
|
||||||
@ -197,7 +202,9 @@ public class Network {
|
|||||||
connection.setConnectionState(ConnectionState.DISCONNECTED);
|
connection.setConnectionState(ConnectionState.DISCONNECTED);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Could not connect
|
// Could not connect
|
||||||
connection.setConnectionState(ConnectionState.DISCONNECTED);
|
if (e instanceof SocketTimeoutException) {
|
||||||
|
connection.setConnectionState(ConnectionState.FAILED);
|
||||||
|
}
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -19,26 +19,23 @@ import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
|
|||||||
import de.bixilon.minosoft.protocol.protocol.ConnectionState;
|
import de.bixilon.minosoft.protocol.protocol.ConnectionState;
|
||||||
import de.bixilon.minosoft.protocol.protocol.OutPacketBuffer;
|
import de.bixilon.minosoft.protocol.protocol.OutPacketBuffer;
|
||||||
import de.bixilon.minosoft.protocol.protocol.Packets;
|
import de.bixilon.minosoft.protocol.protocol.Packets;
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
|
import de.bixilon.minosoft.util.ServerAddress;
|
||||||
|
|
||||||
public class PacketHandshake implements ServerboundPacket {
|
public class PacketHandshake implements ServerboundPacket {
|
||||||
|
|
||||||
final String address;
|
final ServerAddress address;
|
||||||
final int port;
|
|
||||||
final ConnectionState nextState;
|
final ConnectionState nextState;
|
||||||
final int version;
|
final int version;
|
||||||
|
|
||||||
public PacketHandshake(String address, int port, ConnectionState nextState, int version) {
|
public PacketHandshake(ServerAddress address, ConnectionState nextState, int version) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.port = port;
|
|
||||||
this.nextState = nextState;
|
this.nextState = nextState;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketHandshake(String address, int version) {
|
public PacketHandshake(ServerAddress address, int version) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.port = ProtocolDefinition.DEFAULT_PORT;
|
|
||||||
this.nextState = ConnectionState.STATUS;
|
this.nextState = ConnectionState.STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,14 +43,14 @@ public class PacketHandshake implements ServerboundPacket {
|
|||||||
public OutPacketBuffer write(Connection connection) {
|
public OutPacketBuffer write(Connection connection) {
|
||||||
OutPacketBuffer buffer = new OutPacketBuffer(connection, Packets.Serverbound.HANDSHAKING_HANDSHAKE);
|
OutPacketBuffer buffer = new OutPacketBuffer(connection, Packets.Serverbound.HANDSHAKING_HANDSHAKE);
|
||||||
buffer.writeVarInt((nextState == ConnectionState.STATUS ? -1 : connection.getVersion().getProtocolVersion())); // get best protocol version
|
buffer.writeVarInt((nextState == ConnectionState.STATUS ? -1 : connection.getVersion().getProtocolVersion())); // get best protocol version
|
||||||
buffer.writeString(address);
|
buffer.writeString(address.getHostname());
|
||||||
buffer.writeShort((short) port);
|
buffer.writeShort((short) address.getPort());
|
||||||
buffer.writeVarInt(nextState.getId());
|
buffer.writeVarInt(nextState.getId());
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void log() {
|
public void log() {
|
||||||
Log.protocol(String.format("Sending handshake packet (host=%s, port=%d)", address, port));
|
Log.protocol(String.format("Sending handshake packet (address=%s)", address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
package de.bixilon.minosoft.protocol.protocol;
|
package de.bixilon.minosoft.protocol.protocol;
|
||||||
|
|
||||||
public enum ConnectionReason {
|
public enum ConnectionReason {
|
||||||
|
DNS,
|
||||||
PING,
|
PING,
|
||||||
GET_VERSION,
|
GET_VERSION,
|
||||||
CONNECT
|
CONNECT
|
||||||
|
@ -20,7 +20,8 @@ public enum ConnectionState {
|
|||||||
LOGIN(2),
|
LOGIN(2),
|
||||||
PLAY(3),
|
PLAY(3),
|
||||||
DISCONNECTING(5),
|
DISCONNECTING(5),
|
||||||
DISCONNECTED(6);
|
DISCONNECTED(6),
|
||||||
|
FAILED(7);
|
||||||
|
|
||||||
final int id;
|
final int id;
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ package de.bixilon.minosoft.protocol.protocol;
|
|||||||
public final class ProtocolDefinition {
|
public final class ProtocolDefinition {
|
||||||
public static final int STRING_MAX_LEN = 32767;
|
public static final int STRING_MAX_LEN = 32767;
|
||||||
public static final int DEFAULT_PORT = 25565;
|
public static final int DEFAULT_PORT = 25565;
|
||||||
|
public static final int SOCKET_CONNECT_TIMEOUT = 5000;
|
||||||
|
public static final int SOCKET_TIMEOUT = 30000;
|
||||||
public static final int PROTOCOL_PACKET_MAX_SIZE = 2097152;
|
public static final int PROTOCOL_PACKET_MAX_SIZE = 2097152;
|
||||||
public static final float ANGLE_CALCULATION_CONSTANT = 360.0F / 256.0F;
|
public static final float ANGLE_CALCULATION_CONSTANT = 360.0F / 256.0F;
|
||||||
|
|
||||||
|
61
src/main/java/de/bixilon/minosoft/util/DNSUtil.java
Normal file
61
src/main/java/de/bixilon/minosoft/util/DNSUtil.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.util;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
|
||||||
|
import org.xbill.DNS.Record;
|
||||||
|
import org.xbill.DNS.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class DNSUtil {
|
||||||
|
|
||||||
|
public static ArrayList<ServerAddress> getServerAddresses(String hostname) throws TextParseException {
|
||||||
|
ServerAddress fallbackAddress = getServerAddress(hostname);
|
||||||
|
ArrayList<ServerAddress> ret = new ArrayList<>();
|
||||||
|
if (hostname.contains(":")) {
|
||||||
|
// port provided, skip srv check
|
||||||
|
ret.add(fallbackAddress);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
String query = "_minecraft._tcp." + hostname;
|
||||||
|
Record[] records = new Lookup(query, Type.SRV).run();
|
||||||
|
if (records == null) {
|
||||||
|
ret.add(fallbackAddress);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
for (Record record : records) {
|
||||||
|
SRVRecord srvRecord = (SRVRecord) record;
|
||||||
|
ret.add(new ServerAddress(srvRecord.getTarget().toString(true), srvRecord.getPort()));
|
||||||
|
}
|
||||||
|
ret.add(fallbackAddress);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServerAddress getServerAddress(String hostname) {
|
||||||
|
String[] splitHostname = hostname.split(":", 2);
|
||||||
|
if (splitHostname.length == 1) {
|
||||||
|
return new ServerAddress(splitHostname[0], ProtocolDefinition.DEFAULT_PORT);
|
||||||
|
}
|
||||||
|
return new ServerAddress(splitHostname[0], Integer.parseInt(splitHostname[1]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String correctHostName(String hostname) {
|
||||||
|
// replaces invalid chars to avoid copy and paste issues (like spaces, ...)
|
||||||
|
hostname = hostname.replaceAll("\\s", "");
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
37
src/main/java/de/bixilon/minosoft/util/ServerAddress.java
Normal file
37
src/main/java/de/bixilon/minosoft/util/ServerAddress.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Codename Minosoft
|
||||||
|
* Copyright (C) 2020 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.util;
|
||||||
|
|
||||||
|
public class ServerAddress {
|
||||||
|
final String hostname;
|
||||||
|
final int port;
|
||||||
|
|
||||||
|
public ServerAddress(String hostname, int port) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHostname() {
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getHostname() + ":" + getPort();
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,5 @@ account:
|
|||||||
|
|
||||||
# this will be removed soon, only for debugging (pre alpha stage): some features are not implemented yet -/-
|
# this will be removed soon, only for debugging (pre alpha stage): some features are not implemented yet -/-
|
||||||
debug:
|
debug:
|
||||||
host: "127.0.0.1"
|
server: "127.0.0.1"
|
||||||
port: 25565
|
|
||||||
version: -1
|
version: -1
|
Loading…
x
Reference in New Issue
Block a user