Update src
This commit is contained in:
parent
2bd471d607
commit
4cd5369bee
@ -1,2 +1,2 @@
|
||||
# RESTfulMC
|
||||
A simple, yet useful RESTful API for Minecraft!
|
||||
A simple, yet useful RESTful API for Minecraft utilizing Springboot.
|
17
pom.xml
17
pom.xml
@ -33,6 +33,15 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!-- Repos -->
|
||||
<repositories>
|
||||
<!-- Jitpack - Used for dnsjava -->
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<!-- Depends -->
|
||||
<dependencies>
|
||||
<!-- Spring -->
|
||||
@ -71,6 +80,14 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- DNS Lookup -->
|
||||
<dependency>
|
||||
<groupId>com.github.dnsjava</groupId>
|
||||
<artifactId>dnsjava</artifactId>
|
||||
<version>v3.5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Tests -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
53
src/main/java/me/braydon/mc/common/DNSUtils.java
Normal file
53
src/main/java/me/braydon/mc/common/DNSUtils.java
Normal file
@ -0,0 +1,53 @@
|
||||
package me.braydon.mc.common;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.xbill.DNS.Record;
|
||||
import org.xbill.DNS.*;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@UtilityClass
|
||||
public final class DNSUtils {
|
||||
private static final String SRV_QUERY_PREFIX = "_minecraft._tcp.%s";
|
||||
|
||||
/**
|
||||
* Resolve the hostname to an {@link InetSocketAddress}.
|
||||
*
|
||||
* @param hostname the hostname to resolve
|
||||
* @return the resolved {@link InetSocketAddress}
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static InetSocketAddress resolveSRV(@NonNull String hostname) {
|
||||
Record[] records = new Lookup(SRV_QUERY_PREFIX.formatted(hostname), Type.SRV).run(); // Resolve SRV records
|
||||
if (records == null) { // No records exist
|
||||
return null;
|
||||
}
|
||||
String host = null;
|
||||
int port = -1;
|
||||
for (Record record : records) {
|
||||
SRVRecord srv = (SRVRecord) record;
|
||||
host = srv.getTarget().toString().replaceFirst("\\.$", "");
|
||||
port = srv.getPort();
|
||||
}
|
||||
return host == null ? null : new InetSocketAddress(host, port);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static InetAddress resolveA(@NonNull String hostname) {
|
||||
Record[] records = new Lookup(hostname, Type.A).run(); // Resolve A records
|
||||
if (records == null) { // No records exist
|
||||
return null;
|
||||
}
|
||||
InetAddress address = null;
|
||||
for (Record record : records) {
|
||||
address = ((ARecord) record).getAddress();
|
||||
}
|
||||
return address;
|
||||
}
|
||||
}
|
@ -13,9 +13,14 @@ import me.braydon.mc.service.pinger.impl.JavaMinecraftServerPinger;
|
||||
@AllArgsConstructor @Getter @EqualsAndHashCode(onlyExplicitlyIncluded = true) @ToString
|
||||
public class MinecraftServer {
|
||||
/**
|
||||
* The IP address of this server.
|
||||
* The hostname of this server.
|
||||
*/
|
||||
@EqualsAndHashCode.Include @NonNull private final String ip;
|
||||
@EqualsAndHashCode.Include @NonNull private final String hostname;
|
||||
|
||||
/**
|
||||
* The IP address of this server, if resolved.
|
||||
*/
|
||||
private final String ip;
|
||||
|
||||
/**
|
||||
* The port of this server.
|
||||
|
@ -9,7 +9,7 @@ import me.braydon.mc.model.MinecraftServer;
|
||||
* @author Braydon
|
||||
*/
|
||||
public final class BedrockMinecraftServer extends MinecraftServer {
|
||||
private BedrockMinecraftServer(@NonNull String ip, int port, @NonNull Version version, @NonNull Players players) {
|
||||
super(ip, port, version, players);
|
||||
private BedrockMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull Version version, @NonNull Players players) {
|
||||
super(hostname, ip, port, version, players);
|
||||
}
|
||||
}
|
@ -10,11 +10,21 @@ import me.braydon.mc.model.token.JavaServerStatusToken;
|
||||
* @author Braydon
|
||||
*/
|
||||
public final class JavaMinecraftServer extends MinecraftServer {
|
||||
private JavaMinecraftServer(@NonNull String ip, int port, @NonNull Version version, @NonNull Players players) {
|
||||
super(ip, port, version, players);
|
||||
private JavaMinecraftServer(@NonNull String hostname, String ip, int port, @NonNull Version version, @NonNull Players players) {
|
||||
super(hostname, ip, port, version, players);
|
||||
}
|
||||
|
||||
public static JavaMinecraftServer create(@NonNull String ip, int port, @NonNull JavaServerStatusToken token) {
|
||||
return new JavaMinecraftServer(ip, port, token.getVersion(), token.getPlayers());
|
||||
/**
|
||||
* Create a new Java Minecraft server.
|
||||
*
|
||||
* @param hostname the hostname of the server
|
||||
* @param ip the IP address of the server
|
||||
* @param port the port of the server
|
||||
* @param token the status token
|
||||
* @return the Java Minecraft server
|
||||
*/
|
||||
@NonNull
|
||||
public static JavaMinecraftServer create(@NonNull String hostname, String ip, int port, @NonNull JavaServerStatusToken token) {
|
||||
return new JavaMinecraftServer(hostname, ip, port, token.getVersion(), token.getPlayers());
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package me.braydon.mc.service;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import me.braydon.mc.common.DNSUtils;
|
||||
import me.braydon.mc.common.EnumUtils;
|
||||
import me.braydon.mc.common.Tuple;
|
||||
import me.braydon.mc.common.UUIDUtils;
|
||||
@ -21,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -129,12 +131,28 @@ public final class MojangService {
|
||||
}
|
||||
}
|
||||
|
||||
public MinecraftServer getMinecraftServer(@NonNull String platformName, @NonNull String hostname) throws InvalidMinecraftServerPlatform {
|
||||
/**
|
||||
* Resolve a Minecraft server on the given
|
||||
* platform with the given hostname.
|
||||
*
|
||||
* @param platformName the name of the platform
|
||||
* @param hostname the hostname of the server
|
||||
* @return the resolved Minecraft server
|
||||
* @throws InvalidMinecraftServerPlatform if the platform is invalid
|
||||
* @throws ResourceNotFoundException if the server isn't found
|
||||
*/
|
||||
@NonNull
|
||||
public MinecraftServer getMinecraftServer(@NonNull String platformName, @NonNull String hostname)
|
||||
throws InvalidMinecraftServerPlatform, ResourceNotFoundException {
|
||||
MinecraftServer.Platform platform = EnumUtils.getEnumConstant(MinecraftServer.Platform.class, platformName.toUpperCase());
|
||||
if (platform == null) { // Invalid platform
|
||||
throw new InvalidMinecraftServerPlatform();
|
||||
}
|
||||
return platform.getPinger().ping(hostname, 25565);
|
||||
InetSocketAddress address = DNSUtils.resolveSRV(hostname); // Resolve the SRV record
|
||||
if (address == null) { // No address found
|
||||
throw new ResourceNotFoundException("No SRV record found for hostname: %s".formatted(hostname));
|
||||
}
|
||||
return platform.getPinger().ping(address.getHostName(), address.getPort()); // Ping the server and return with the response
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@ package me.braydon.mc.service.pinger.impl;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import me.braydon.mc.RESTfulMC;
|
||||
import me.braydon.mc.common.DNSUtils;
|
||||
import me.braydon.mc.common.packet.impl.PacketHandshakingInSetProtocol;
|
||||
import me.braydon.mc.common.packet.impl.PacketStatusInStart;
|
||||
import me.braydon.mc.model.server.JavaMinecraftServer;
|
||||
@ -12,6 +13,7 @@ import me.braydon.mc.service.pinger.MinecraftServerPinger;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
@ -34,6 +36,11 @@ public final class JavaMinecraftServerPinger implements MinecraftServerPinger<Ja
|
||||
*/
|
||||
@Override
|
||||
public JavaMinecraftServer ping(@NonNull String hostname, int port) {
|
||||
InetAddress inetAddress = DNSUtils.resolveA(hostname); // Resolve the hostname to an IP address
|
||||
String ip = inetAddress == null ? null : inetAddress.getHostAddress(); // Get the IP address
|
||||
if (ip != null) { // Was the IP resolved?
|
||||
log.info("Resolved hostname {} to {}", hostname, ip);
|
||||
}
|
||||
log.info("Pinging {}:{}...", hostname, port);
|
||||
long before = System.currentTimeMillis(); // Timestamp before pinging
|
||||
|
||||
@ -54,7 +61,7 @@ public final class JavaMinecraftServerPinger implements MinecraftServerPinger<Ja
|
||||
PacketStatusInStart packetStatusInStart = new PacketStatusInStart();
|
||||
packetStatusInStart.process(inputStream, outputStream);
|
||||
JavaServerStatusToken token = RESTfulMC.GSON.fromJson(packetStatusInStart.getResponse(), JavaServerStatusToken.class);
|
||||
return JavaMinecraftServer.create(hostname, port, token); // Return the server
|
||||
return JavaMinecraftServer.create(hostname, ip, port, token); // Return the server
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
log.error("An error occurred pinging %s:%s:".formatted(hostname, port), ex);
|
||||
|
Loading…
Reference in New Issue
Block a user