Show DNS records in MC server responses
Some checks failed
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Failing after 22s

This commit is contained in:
Braydon 2024-04-10 10:21:27 -04:00
parent 3a098433e0
commit 0cb6d3f028
11 changed files with 242 additions and 40 deletions

@ -26,11 +26,11 @@ package me.braydon.mc.common;
import lombok.NonNull; import lombok.NonNull;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import me.braydon.mc.model.dns.impl.ARecord;
import me.braydon.mc.model.dns.impl.SRVRecord;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record; import org.xbill.DNS.Record;
import org.xbill.DNS.*; import org.xbill.DNS.Type;
import java.net.InetAddress;
import java.net.InetSocketAddress;
/** /**
* @author Braydon * @author Braydon
@ -47,19 +47,16 @@ public final class DNSUtils {
* @return the resolved address and port, null if none * @return the resolved address and port, null if none
*/ */
@SneakyThrows @SneakyThrows
public static InetSocketAddress resolveSRV(@NonNull String hostname) { public static SRVRecord resolveSRV(@NonNull String hostname) {
Record[] records = new Lookup(SRV_QUERY_PREFIX.formatted(hostname), Type.SRV).run(); // Resolve SRV records Record[] records = new Lookup(SRV_QUERY_PREFIX.formatted(hostname), Type.SRV).run(); // Resolve SRV records
if (records == null) { // No records exist if (records == null) { // No records exist
return null; return null;
} }
String host = null; SRVRecord result = null;
int port = -1;
for (Record record : records) { for (Record record : records) {
SRVRecord srv = (SRVRecord) record; result = new SRVRecord((org.xbill.DNS.SRVRecord) record);
host = srv.getTarget().toString().replaceFirst("\\.$", "");
port = srv.getPort();
} }
return host == null ? null : new InetSocketAddress(host, port); return result;
} }
/** /**
@ -70,15 +67,15 @@ public final class DNSUtils {
* @return the resolved address, null if none * @return the resolved address, null if none
*/ */
@SneakyThrows @SneakyThrows
public static InetAddress resolveA(@NonNull String hostname) { public static ARecord resolveA(@NonNull String hostname) {
Record[] records = new Lookup(hostname, Type.A).run(); // Resolve A records Record[] records = new Lookup(hostname, Type.A).run(); // Resolve A records
if (records == null) { // No records exist if (records == null) { // No records exist
return null; return null;
} }
InetAddress address = null; ARecord result = null;
for (Record record : records) { for (Record record : records) {
address = ((ARecord) record).getAddress(); result = new ARecord((org.xbill.DNS.ARecord) record);
} }
return address; return result;
} }
} }

@ -25,6 +25,7 @@ package me.braydon.mc.model;
import lombok.*; import lombok.*;
import me.braydon.mc.common.ColorUtils; import me.braydon.mc.common.ColorUtils;
import me.braydon.mc.model.dns.DNSRecord;
import me.braydon.mc.model.token.JavaServerStatusToken; import me.braydon.mc.model.token.JavaServerStatusToken;
import me.braydon.mc.service.pinger.MinecraftServerPinger; import me.braydon.mc.service.pinger.MinecraftServerPinger;
import me.braydon.mc.service.pinger.impl.BedrockMinecraftServerPinger; import me.braydon.mc.service.pinger.impl.BedrockMinecraftServerPinger;
@ -57,6 +58,11 @@ public class MinecraftServer {
*/ */
@EqualsAndHashCode.Include private final int port; @EqualsAndHashCode.Include private final int port;
/**
* The DNS records resolved for this server.
*/
@NonNull private final DNSRecord[] records;
/** /**
* The player counts of this server. * The player counts of this server.
*/ */

@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2024 Braydon (Rainnny).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.braydon.mc.model.dns;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
/**
* A representation of a DNS record.
*
* @author Braydon
*/
@AllArgsConstructor @Getter @ToString
public abstract class DNSRecord {
/**
* The type of this record.
*/
@NonNull private final Type type;
/**
* The TTL (Time To Live) of this record.
*/
private final long ttl;
/**
* Types of a record.
*/
public enum Type {
A, SRV
}
}

@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2024 Braydon (Rainnny).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.braydon.mc.model.dns.impl;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
import me.braydon.mc.model.dns.DNSRecord;
/**
* An A record implementation.
*
* @author Braydon
*/
@Getter @ToString(callSuper = true)
public final class ARecord extends DNSRecord {
/**
* The address of this record, null if unresolved.
*/
private final String address;
public ARecord(@NonNull org.xbill.DNS.ARecord bootstrap) {
super(Type.A, bootstrap.getTTL());
address = bootstrap.getAddress().getHostAddress();
}
}

@ -0,0 +1,79 @@
/*
* MIT License
*
* Copyright (c) 2024 Braydon (Rainnny).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.braydon.mc.model.dns.impl;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
import me.braydon.mc.model.dns.DNSRecord;
import java.net.InetSocketAddress;
/**
* An SRV record implementation.
*
* @author Braydon
*/
@Getter @ToString(callSuper = true)
public final class SRVRecord extends DNSRecord {
/**
* The priority of this record.
*/
private final int priority;
/**
* The weight of this record.
*/
private final int weight;
/**
* The port of this record.
*/
private final int port;
/**
* The target of this record.
*/
@NonNull private final String target;
public SRVRecord(@NonNull org.xbill.DNS.SRVRecord bootstrap) {
super(Type.SRV, bootstrap.getTTL());
priority = bootstrap.getPriority();
weight = bootstrap.getWeight();
port = bootstrap.getPort();
target = bootstrap.getTarget().toString().replaceFirst("\\.$", "");
}
/**
* Get a socket address from
* the target and port.
*
* @return the socket address
*/
@NonNull @JsonIgnore
public InetSocketAddress getSocketAddress() {
return new InetSocketAddress(target, port);
}
}

@ -25,6 +25,7 @@ package me.braydon.mc.model.server;
import lombok.*; import lombok.*;
import me.braydon.mc.model.MinecraftServer; import me.braydon.mc.model.MinecraftServer;
import me.braydon.mc.model.dns.DNSRecord;
/** /**
* A Bedrock edition {@link MinecraftServer}. * A Bedrock edition {@link MinecraftServer}.
@ -53,10 +54,10 @@ public final class BedrockMinecraftServer extends MinecraftServer {
*/ */
@NonNull private final GameMode gamemode; @NonNull private final GameMode gamemode;
private BedrockMinecraftServer(@NonNull String id, @NonNull String hostname, String ip, int port, private BedrockMinecraftServer(@NonNull String id, @NonNull String hostname, String ip, int port, @NonNull DNSRecord[] records,
@NonNull Edition edition, @NonNull Version version, @NonNull Players players, @NonNull Edition edition, @NonNull Version version, @NonNull Players players, @NonNull MOTD motd,
@NonNull MOTD motd, @NonNull GameMode gamemode) { @NonNull GameMode gamemode) {
super(hostname, ip, port, players, motd); super(hostname, ip, port, records, players, motd);
this.id = id; this.id = id;
this.edition = edition; this.edition = edition;
this.version = version; this.version = version;
@ -69,18 +70,20 @@ public final class BedrockMinecraftServer extends MinecraftServer {
* @param hostname the hostname of the server * @param hostname the hostname of the server
* @param ip the IP address of the server * @param ip the IP address of the server
* @param port the port of the server * @param port the port of the server
* @param records the DNS records of the server
* @param token the status token * @param token the status token
* @return the Bedrock Minecraft server * @return the Bedrock Minecraft server
*/ */
@NonNull @NonNull
public static BedrockMinecraftServer create(@NonNull String hostname, String ip, int port, @NonNull String token) { public static BedrockMinecraftServer create(@NonNull String hostname, String ip, int port,
@NonNull DNSRecord[] records, @NonNull String token) {
String[] split = token.split(";"); // Split the token String[] split = token.split(";"); // Split the token
Edition edition = Edition.valueOf(split[0]); Edition edition = Edition.valueOf(split[0]);
Version version = new Version(Integer.parseInt(split[2]), split[3]); Version version = new Version(Integer.parseInt(split[2]), split[3]);
Players players = new Players(Integer.parseInt(split[4]), Integer.parseInt(split[5]), null); Players players = new Players(Integer.parseInt(split[4]), Integer.parseInt(split[5]), null);
MOTD motd = MOTD.create(split[1] + "\n" + split[7]); MOTD motd = MOTD.create(split[1] + "\n" + split[7]);
GameMode gameMode = new GameMode(split[8], Integer.parseInt(split[9])); GameMode gameMode = new GameMode(split[8], Integer.parseInt(split[9]));
return new BedrockMinecraftServer(split[6], hostname, ip, port, edition, version, players, motd, gameMode); return new BedrockMinecraftServer(split[6], hostname, ip, port, records, edition, version, players, motd, gameMode);
} }
/** /**

@ -28,6 +28,7 @@ import lombok.*;
import me.braydon.mc.common.JavaMinecraftVersion; import me.braydon.mc.common.JavaMinecraftVersion;
import me.braydon.mc.config.AppConfig; import me.braydon.mc.config.AppConfig;
import me.braydon.mc.model.MinecraftServer; import me.braydon.mc.model.MinecraftServer;
import me.braydon.mc.model.dns.DNSRecord;
import me.braydon.mc.model.token.JavaServerStatusToken; import me.braydon.mc.model.token.JavaServerStatusToken;
import me.braydon.mc.service.MojangService; import me.braydon.mc.service.MojangService;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
@ -96,10 +97,10 @@ public final class JavaMinecraftServer extends MinecraftServer {
*/ */
private boolean mojangBanned; private boolean mojangBanned;
private JavaMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull Version version, private JavaMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull DNSRecord[] records, @NonNull Version version,
@NonNull Players players, @NonNull MOTD motd, Favicon favicon, ModInfo modInfo, @NonNull Players players, @NonNull MOTD motd, Favicon favicon, ModInfo modInfo, ForgeData forgeData,
ForgeData forgeData, boolean previewsChat, boolean enforcesSecureChat, boolean preventsChatReports, boolean mojangBanned) { boolean previewsChat, boolean enforcesSecureChat, boolean preventsChatReports, boolean mojangBanned) {
super(hostname, ip, port, players, motd); super(hostname, ip, port, records, players, motd);
this.version = version; this.version = version;
this.favicon = favicon; this.favicon = favicon;
this.modInfo = modInfo; this.modInfo = modInfo;
@ -116,16 +117,18 @@ public final class JavaMinecraftServer extends MinecraftServer {
* @param hostname the hostname of the server * @param hostname the hostname of the server
* @param ip the IP address of the server * @param ip the IP address of the server
* @param port the port of the server * @param port the port of the server
* @param records the DNS records of the server
* @param token the status token * @param token the status token
* @return the Java Minecraft server * @return the Java Minecraft server
*/ */
@NonNull @NonNull
public static JavaMinecraftServer create(@NonNull String hostname, String ip, int port, @NonNull JavaServerStatusToken token) { public static JavaMinecraftServer create(@NonNull String hostname, String ip, int port,
@NonNull DNSRecord[] records, @NonNull JavaServerStatusToken token) {
String motdString = token.getDescription() instanceof String ? (String) token.getDescription() : null; String motdString = token.getDescription() instanceof String ? (String) token.getDescription() : null;
if (motdString == null) { // Not a string motd, convert from Json if (motdString == null) { // Not a string motd, convert from Json
motdString = new TextComponent(ComponentSerializer.parse(AppConfig.GSON.toJson(token.getDescription()))).toLegacyText(); motdString = new TextComponent(ComponentSerializer.parse(AppConfig.GSON.toJson(token.getDescription()))).toLegacyText();
} }
return new JavaMinecraftServer(hostname, ip, port, token.getVersion().detailedCopy(), Players.create(token.getPlayers()), return new JavaMinecraftServer(hostname, ip, port, records, token.getVersion().detailedCopy(), Players.create(token.getPlayers()),
MOTD.create(motdString), Favicon.create(token.getFavicon(), hostname), token.getModInfo(), token.getForgeData(), MOTD.create(motdString), Favicon.create(token.getFavicon(), hostname), token.getModInfo(), token.getForgeData(),
token.isPreviewsChat(), token.isEnforcesSecureChat(), token.isPreventsChatReports(), false token.isPreviewsChat(), token.isEnforcesSecureChat(), token.isPreventsChatReports(), false
); );

@ -42,6 +42,9 @@ import me.braydon.mc.model.cache.CachedMinecraftServer;
import me.braydon.mc.model.cache.CachedPlayer; import me.braydon.mc.model.cache.CachedPlayer;
import me.braydon.mc.model.cache.CachedPlayerName; import me.braydon.mc.model.cache.CachedPlayerName;
import me.braydon.mc.model.cache.CachedSkinPartTexture; import me.braydon.mc.model.cache.CachedSkinPartTexture;
import me.braydon.mc.model.dns.DNSRecord;
import me.braydon.mc.model.dns.impl.ARecord;
import me.braydon.mc.model.dns.impl.SRVRecord;
import me.braydon.mc.model.server.JavaMinecraftServer; import me.braydon.mc.model.server.JavaMinecraftServer;
import me.braydon.mc.model.token.MojangProfileToken; import me.braydon.mc.model.token.MojangProfileToken;
import me.braydon.mc.model.token.MojangUsernameToUUIDToken; import me.braydon.mc.model.token.MojangUsernameToUUIDToken;
@ -55,7 +58,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -394,20 +396,25 @@ public final class MojangService {
log.info("Found server in cache: {}", hostname); log.info("Found server in cache: {}", hostname);
return cached.get(); return cached.get();
} }
InetSocketAddress address = platform == MinecraftServer.Platform.JAVA ? DNSUtils.resolveSRV(hostname) : null; // Resolve the SRV record List<DNSRecord> records = new ArrayList<>(); // The resolved DNS records for the server
if (address != null) { // SRV was resolved, use the hostname and port
hostname = address.getHostName(); SRVRecord srvRecord = platform == MinecraftServer.Platform.JAVA ? DNSUtils.resolveSRV(hostname) : null; // Resolve the SRV record
port = address.getPort(); if (srvRecord != null) { // SRV was resolved, use the hostname and port
records.add(srvRecord); // Going to need this for later
InetSocketAddress socketAddress = srvRecord.getSocketAddress();
hostname = socketAddress.getHostName();
port = socketAddress.getPort();
} }
InetAddress inetAddress = DNSUtils.resolveA(hostname); // Resolve the hostname to an IP address ARecord aRecord = DNSUtils.resolveA(hostname); // Resolve the A record so we can get the IPv4 address
String ip = inetAddress == null ? null : inetAddress.getHostAddress(); // Get the IP address String ip = aRecord == null ? null : aRecord.getAddress(); // Get the IP address
if (ip != null) { // Was the IP resolved? if (ip != null) { // Was the IP resolved?
records.add(aRecord); // Going to need this for later
log.info("Resolved hostname: {} -> {}", hostname, ip); log.info("Resolved hostname: {} -> {}", hostname, ip);
} }
// Build our server model, cache it, and then return it // Build our server model, cache it, and then return it
MinecraftServer response = platform.getPinger().ping(hostname, ip, port); // Ping the server and await a response MinecraftServer response = platform.getPinger().ping(hostname, ip, port, records.toArray(new DNSRecord[0])); // Ping the server and await a response
if (response == null) { // No response from ping if (response == null) { // No response from ping
throw new ResourceNotFoundException("Server didn't respond to ping"); throw new ResourceNotFoundException("Server didn't respond to ping");
} }

@ -25,6 +25,7 @@ package me.braydon.mc.service.pinger;
import lombok.NonNull; import lombok.NonNull;
import me.braydon.mc.model.MinecraftServer; import me.braydon.mc.model.MinecraftServer;
import me.braydon.mc.model.dns.DNSRecord;
/** /**
* A {@link MinecraftServerPinger} is * A {@link MinecraftServerPinger} is
@ -40,7 +41,8 @@ public interface MinecraftServerPinger<T extends MinecraftServer> {
* @param hostname the hostname of the server * @param hostname the hostname of the server
* @param ip the ip of the server, null if unresolved * @param ip the ip of the server, null if unresolved
* @param port the port of the server * @param port the port of the server
* @param records the DNS records of the server
* @return the server that was pinged * @return the server that was pinged
*/ */
T ping(@NonNull String hostname, String ip, int port); T ping(@NonNull String hostname, String ip, int port, @NonNull DNSRecord[] records);
} }

@ -29,6 +29,7 @@ import me.braydon.mc.common.packet.impl.bedrock.BedrockPacketUnconnectedPing;
import me.braydon.mc.common.packet.impl.bedrock.BedrockPacketUnconnectedPong; import me.braydon.mc.common.packet.impl.bedrock.BedrockPacketUnconnectedPong;
import me.braydon.mc.exception.impl.BadRequestException; import me.braydon.mc.exception.impl.BadRequestException;
import me.braydon.mc.exception.impl.ResourceNotFoundException; import me.braydon.mc.exception.impl.ResourceNotFoundException;
import me.braydon.mc.model.dns.DNSRecord;
import me.braydon.mc.model.server.BedrockMinecraftServer; import me.braydon.mc.model.server.BedrockMinecraftServer;
import me.braydon.mc.service.pinger.MinecraftServerPinger; import me.braydon.mc.service.pinger.MinecraftServerPinger;
@ -54,10 +55,11 @@ public final class BedrockMinecraftServerPinger implements MinecraftServerPinger
* @param hostname the hostname of the server * @param hostname the hostname of the server
* @param ip the ip of the server, null if unresolved * @param ip the ip of the server, null if unresolved
* @param port the port of the server * @param port the port of the server
* @param records the DNS records of the server
* @return the server that was pinged * @return the server that was pinged
*/ */
@Override @Override
public BedrockMinecraftServer ping(@NonNull String hostname, String ip, int port) { public BedrockMinecraftServer ping(@NonNull String hostname, String ip, int port, @NonNull DNSRecord[] records) {
log.info("Pinging {}:{}...", hostname, port); log.info("Pinging {}:{}...", hostname, port);
long before = System.currentTimeMillis(); // Timestamp before pinging long before = System.currentTimeMillis(); // Timestamp before pinging
@ -79,7 +81,7 @@ public final class BedrockMinecraftServerPinger implements MinecraftServerPinger
if (response == null) { // No pong response if (response == null) { // No pong response
throw new ResourceNotFoundException("Server didn't respond to ping"); throw new ResourceNotFoundException("Server didn't respond to ping");
} }
return BedrockMinecraftServer.create(hostname, ip, port, response); // Return the server return BedrockMinecraftServer.create(hostname, ip, port, records, response); // Return the server
} catch (IOException ex) { } catch (IOException ex) {
if (ex instanceof UnknownHostException) { if (ex instanceof UnknownHostException) {
throw new BadRequestException("Unknown hostname: %s".formatted(hostname)); throw new BadRequestException("Unknown hostname: %s".formatted(hostname));

@ -31,6 +31,7 @@ import me.braydon.mc.common.packet.impl.java.JavaPacketStatusInStart;
import me.braydon.mc.config.AppConfig; import me.braydon.mc.config.AppConfig;
import me.braydon.mc.exception.impl.BadRequestException; import me.braydon.mc.exception.impl.BadRequestException;
import me.braydon.mc.exception.impl.ResourceNotFoundException; import me.braydon.mc.exception.impl.ResourceNotFoundException;
import me.braydon.mc.model.dns.DNSRecord;
import me.braydon.mc.model.server.JavaMinecraftServer; import me.braydon.mc.model.server.JavaMinecraftServer;
import me.braydon.mc.model.token.JavaServerStatusToken; import me.braydon.mc.model.token.JavaServerStatusToken;
import me.braydon.mc.service.pinger.MinecraftServerPinger; import me.braydon.mc.service.pinger.MinecraftServerPinger;
@ -56,10 +57,11 @@ public final class JavaMinecraftServerPinger implements MinecraftServerPinger<Ja
* @param hostname the hostname of the server * @param hostname the hostname of the server
* @param ip the ip of the server, null if unresolved * @param ip the ip of the server, null if unresolved
* @param port the port of the server * @param port the port of the server
* @param records the DNS records of the server
* @return the server that was pinged * @return the server that was pinged
*/ */
@Override @Override
public JavaMinecraftServer ping(@NonNull String hostname, String ip, int port) { public JavaMinecraftServer ping(@NonNull String hostname, String ip, int port, @NonNull DNSRecord[] records) {
log.info("Pinging {}:{}...", hostname, port); log.info("Pinging {}:{}...", hostname, port);
long before = System.currentTimeMillis(); // Timestamp before pinging long before = System.currentTimeMillis(); // Timestamp before pinging
@ -86,7 +88,7 @@ public final class JavaMinecraftServerPinger implements MinecraftServerPinger<Ja
throw new ResourceNotFoundException("Server didn't respond to status request"); throw new ResourceNotFoundException("Server didn't respond to status request");
} }
JavaServerStatusToken token = AppConfig.GSON.fromJson(response, JavaServerStatusToken.class); JavaServerStatusToken token = AppConfig.GSON.fromJson(response, JavaServerStatusToken.class);
return JavaMinecraftServer.create(hostname, ip, port, token); // Return the server return JavaMinecraftServer.create(hostname, ip, port, records, token); // Return the server
} }
} catch (IOException ex) { } catch (IOException ex) {
if (ex instanceof UnknownHostException) { if (ex instanceof UnknownHostException) {