Skip to content

Instantly share code, notes, and snippets.

@tekgator
Last active August 29, 2015 14:16
Show Gist options
  • Save tekgator/fd39017561b506139962 to your computer and use it in GitHub Desktop.
Save tekgator/fd39017561b506139962 to your computer and use it in GitHub Desktop.
Resolving Minecraft server hostname address and port by different inputs, e.g. hostname:port, hostname, port etc. If no port is provided try to get the port via the Minecraft specific SRV record. Used for an Androis project (dependency can be removed by remove logging and IP address pattern). Uses xbill.org DNS class for DNS resolving purposes.
import android.util.Log;
import android.util.Patterns;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.SRVRecord;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Created by tekgator on 07-Mar-2015.
*/
public class MinecraftServerDns {
private static final String TAG = "MinecraftServerDns";
private static final int DEFAULT_PORT = 25565;
private static final String SRV_STR = "_minecraft._tcp.";
private String ipAddress = "";
private String hostName = "";
private int port = 0;
public MinecraftServerDns(String hostName, int port) throws
UnknownHostException {
this.resolve(hostName, port);
}
public MinecraftServerDns(String hostName) throws
UnknownHostException {
this.resolve(hostName, 0);
}
private void resolve(String hostName, int port) throws
UnknownHostException {
// check whether the port is encoded within the hostname string
String[] parts = hostName.split(":");
if (parts.length > 1) {
this.hostName = parts[0];
try {
this.port = Integer.parseInt(parts[1]);
} catch (NumberFormatException e) {
Log.d(TAG, String.format("Invalid port within hostname '%s' provided, use port from second parameter '%d'", hostName, port));
this.port = port;
}
} else {
this.hostName = hostName;
this.port = port;
}
if (!Patterns.IP_ADDRESS.matcher(this.hostName).matches() &&
this.hostName != InetAddress.getLocalHost().getHostName() &&
this.port == 0) {
// input is an hostname, but no port submitted, try to resolve via SRV record
try {
SRVRecord srvRecord = (SRVRecord) lookupRecord(SRV_STR + hostName, Type.SRV);
this.hostName = srvRecord.getTarget().toString().replaceFirst("\\.$","");
this.port = srvRecord.getPort();
} catch (UnknownHostException e) {
// no SRV record found at the moment, just continue
}
}
if (Patterns.IP_ADDRESS.matcher(this.hostName).matches()) {
// hostname provided is a IP address
this.ipAddress = this.hostName;
} else {
// hostname provided is an actual hostname, resolve IP address
this.ipAddress = ((ARecord) lookupRecord(this.hostName, Type.A)).getAddress().getHostAddress();
}
if (this.port == 0) {
// couldn't resolve via SVR record, therefore use default minecraft port
this.port = DEFAULT_PORT;
}
}
private Record lookupRecord(String hostName, int type) throws
UnknownHostException {
Record record = null;
Lookup lookup;
int result;
try {
lookup = new Lookup(hostName, type);
} catch (TextParseException e) {
throw new UnknownHostException(String.format("Host '%s' parsing error:%s", hostName, e.getMessage()));
}
lookup.run();
result = lookup.getResult();
if (result == Lookup.SUCCESSFUL) {
Log.i(TAG, String.format("Successfully got DNS record of type '%d' for hostname '%s'", type, hostName));
record = lookup.getAnswers()[0];
} else {
Log.d(TAG, String.format("Failed to get DNS record of type '%d' for hostname '%s'", type, hostName));
switch (result) {
case Lookup.HOST_NOT_FOUND:
throw new UnknownHostException(String.format("Host '%s' not found", hostName));
case Lookup.TYPE_NOT_FOUND:
throw new UnknownHostException(String.format("Host '%s' not found (no A record)", hostName));
case Lookup.UNRECOVERABLE:
throw new UnknownHostException(String.format("Cannot lookup host '%s'", hostName));
case Lookup.TRY_AGAIN:
throw new UnknownHostException(String.format("Temporary failure to lookup host '%s'", hostName));
default:
throw new UnknownHostException(String.format("Unknown error %d in host lookup of '%s'", result, hostName));
}
}
return record;
}
public int getPort() {
return this.port;
}
public String getHostName() {
return this.hostName;
}
public String getIpAddress() {
return this.ipAddress;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment