Added the ability to specify a port in server and server favicon requests
This commit is contained in:
parent
9e99db3aa3
commit
1d5aa930f0
@ -39,7 +39,7 @@ jobs:
|
||||
run: mvn --batch-mode test -q
|
||||
|
||||
# Re-checkout to reset the FS before deploying to Dokku
|
||||
- name: Checkout
|
||||
- name: Checkout - Reset FS
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
@ -26,17 +26,19 @@ package me.braydon.mc.common;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
/**
|
||||
* A list of versions for the
|
||||
* Java edition of Minecraft.
|
||||
*
|
||||
* @author Braydon
|
||||
* @see <a href="https://wiki.vg/Protocol_version_numbers">Protocol Version Numbers</a>
|
||||
* @see <a href="https://www.spigotmc.org/wiki/spigot-nms-and-minecraft-versions-1-16">Spigot NMS (1.16+)</a>
|
||||
* @see <a href="https://www.spigotmc.org/wiki/spigot-nms-and-minecraft-versions-1-10-1-15">Spigot NMS (1.10 - 1.15)</a>
|
||||
* @see <a href="https://www.spigotmc.org/wiki/spigot-nms-and-minecraft-versions-legacy">Spigot NMS (1.8 - 1.9)</a>
|
||||
*/
|
||||
@RequiredArgsConstructor @Getter @ToString @Log4j2(topic = "Minecraft Version")
|
||||
public enum MinecraftVersion {
|
||||
@RequiredArgsConstructor @Getter @ToString
|
||||
public enum JavaMinecraftVersion {
|
||||
V1_20_3(765, "v1_20_R3"), // 1.20.3 & 1.20.4
|
||||
V1_20_2(764, "v1_20_R2"), // 1.20.2
|
||||
V1_20(763, "v1_20_R1"), // 1.20 & 1.20.1
|
||||
@ -91,19 +93,19 @@ public enum MinecraftVersion {
|
||||
UNKNOWN(-1, "Unknown");
|
||||
|
||||
// Game Updates
|
||||
public static final MinecraftVersion TRAILS_AND_TALES = MinecraftVersion.V1_20;
|
||||
public static final MinecraftVersion THE_WILD_UPDATE = MinecraftVersion.V1_19;
|
||||
public static final MinecraftVersion CAVES_AND_CLIFFS_PT_2 = MinecraftVersion.V1_18;
|
||||
public static final MinecraftVersion CAVES_AND_CLIFFS_PT_1 = MinecraftVersion.V1_17;
|
||||
public static final MinecraftVersion NETHER_UPDATE = MinecraftVersion.V1_16;
|
||||
public static final MinecraftVersion BUZZY_BEES = MinecraftVersion.V1_15;
|
||||
public static final MinecraftVersion VILLAGE_AND_PILLAGE = MinecraftVersion.V1_14;
|
||||
public static final MinecraftVersion UPDATE_AQUATIC = MinecraftVersion.V1_13;
|
||||
public static final MinecraftVersion WORLD_OF_COLOR_UPDATE = MinecraftVersion.V1_12;
|
||||
public static final MinecraftVersion EXPLORATION_UPDATE = MinecraftVersion.V1_11;
|
||||
public static final MinecraftVersion FROSTBURN_UPDATE = MinecraftVersion.V1_10;
|
||||
public static final MinecraftVersion THE_COMBAT_UPDATE = MinecraftVersion.V1_9;
|
||||
public static final MinecraftVersion BOUNTIFUL_UPDATE = MinecraftVersion.V1_8;
|
||||
public static final JavaMinecraftVersion TRAILS_AND_TALES = JavaMinecraftVersion.V1_20;
|
||||
public static final JavaMinecraftVersion THE_WILD_UPDATE = JavaMinecraftVersion.V1_19;
|
||||
public static final JavaMinecraftVersion CAVES_AND_CLIFFS_PT_2 = JavaMinecraftVersion.V1_18;
|
||||
public static final JavaMinecraftVersion CAVES_AND_CLIFFS_PT_1 = JavaMinecraftVersion.V1_17;
|
||||
public static final JavaMinecraftVersion NETHER_UPDATE = JavaMinecraftVersion.V1_16;
|
||||
public static final JavaMinecraftVersion BUZZY_BEES = JavaMinecraftVersion.V1_15;
|
||||
public static final JavaMinecraftVersion VILLAGE_AND_PILLAGE = JavaMinecraftVersion.V1_14;
|
||||
public static final JavaMinecraftVersion UPDATE_AQUATIC = JavaMinecraftVersion.V1_13;
|
||||
public static final JavaMinecraftVersion WORLD_OF_COLOR_UPDATE = JavaMinecraftVersion.V1_12;
|
||||
public static final JavaMinecraftVersion EXPLORATION_UPDATE = JavaMinecraftVersion.V1_11;
|
||||
public static final JavaMinecraftVersion FROSTBURN_UPDATE = JavaMinecraftVersion.V1_10;
|
||||
public static final JavaMinecraftVersion THE_COMBAT_UPDATE = JavaMinecraftVersion.V1_9;
|
||||
public static final JavaMinecraftVersion BOUNTIFUL_UPDATE = JavaMinecraftVersion.V1_8;
|
||||
|
||||
/**
|
||||
* The protocol number of this version.
|
||||
@ -140,67 +142,14 @@ public enum MinecraftVersion {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this version legacy?
|
||||
*
|
||||
* @return whether this version is legacy
|
||||
*/
|
||||
public boolean isLegacy() {
|
||||
return this.isBelow(MinecraftVersion.V1_16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this version is
|
||||
* above the one given.
|
||||
*
|
||||
* @param other the other version
|
||||
* @return true if above, otherwise false
|
||||
*/
|
||||
public boolean isAbove(MinecraftVersion other) {
|
||||
return this.protocol > other.getProtocol();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this version is
|
||||
* or above the one given.
|
||||
*
|
||||
* @param other the other version
|
||||
* @return true if is or above, otherwise false
|
||||
*/
|
||||
public boolean isOrAbove(MinecraftVersion other) {
|
||||
return this.protocol >= other.getProtocol();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this version is
|
||||
* below the one given.
|
||||
*
|
||||
* @param other the other version
|
||||
* @return true if below, otherwise false
|
||||
*/
|
||||
public boolean isBelow(MinecraftVersion other) {
|
||||
return this.protocol < other.getProtocol();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this version is
|
||||
* or below the one given.
|
||||
*
|
||||
* @param other the other version
|
||||
* @return true if is or below, otherwise false
|
||||
*/
|
||||
public boolean isOrBelow(MinecraftVersion other) {
|
||||
return this.protocol <= other.getProtocol();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version from the given protocol.
|
||||
*
|
||||
* @param protocol the protocol to get the version for
|
||||
* @return the version, null if none
|
||||
*/
|
||||
public static MinecraftVersion byProtocol(int protocol) {
|
||||
for (MinecraftVersion version : values()) {
|
||||
public static JavaMinecraftVersion byProtocol(int protocol) {
|
||||
for (JavaMinecraftVersion version : values()) {
|
||||
if (version.getProtocol() == protocol) {
|
||||
return version;
|
||||
}
|
@ -63,16 +63,17 @@ public final class ServerController {
|
||||
*
|
||||
* @param platform the platform of the server
|
||||
* @param hostname the hostname of the server
|
||||
* @param port the port of the server, null for default
|
||||
* @return the server
|
||||
* @throws BadRequestException if the hostname or platform is invalid
|
||||
* @throws BadRequestException if the hostname or platform is invalid
|
||||
* @throws ResourceNotFoundException if the server isn't found
|
||||
*/
|
||||
@GetMapping("/{platform}/{hostname}")
|
||||
@ResponseBody
|
||||
public ResponseEntity<CachedMinecraftServer> getServer(@PathVariable @NonNull String platform, @PathVariable @NonNull String hostname)
|
||||
throws BadRequestException, ResourceNotFoundException
|
||||
{
|
||||
return ResponseEntity.ofNullable(mojangService.getMinecraftServer(platform, hostname));
|
||||
public ResponseEntity<CachedMinecraftServer> getServer(@PathVariable @NonNull String platform, @PathVariable @NonNull String hostname,
|
||||
@RequestParam(required = false) String port
|
||||
) throws BadRequestException, ResourceNotFoundException {
|
||||
return ResponseEntity.ofNullable(mojangService.getMinecraftServer(platform, hostname, port));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,14 +96,15 @@ public final class ServerController {
|
||||
* server by its platform and hostname.
|
||||
*
|
||||
* @param hostname the hostname of the server
|
||||
* @param port the port of the server, null for default
|
||||
* @return the server icon
|
||||
*/
|
||||
@GetMapping(value = "/icon/{hostname}", produces = MediaType.IMAGE_PNG_VALUE)
|
||||
@ResponseBody
|
||||
public ResponseEntity<byte[]> getServerFavicon(@PathVariable @NonNull String hostname) {
|
||||
public ResponseEntity<byte[]> getServerFavicon(@PathVariable @NonNull String hostname, @RequestParam(required = false) String port) {
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.IMAGE_PNG)
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=%s.png".formatted(hostname))
|
||||
.body(mojangService.getServerFavicon(hostname));
|
||||
.body(mojangService.getServerFavicon(hostname, port));
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ package me.braydon.mc.model.server;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.*;
|
||||
import me.braydon.mc.RESTfulMC;
|
||||
import me.braydon.mc.common.MinecraftVersion;
|
||||
import me.braydon.mc.common.JavaMinecraftVersion;
|
||||
import me.braydon.mc.config.AppConfig;
|
||||
import me.braydon.mc.model.MinecraftServer;
|
||||
import me.braydon.mc.model.token.JavaServerStatusToken;
|
||||
@ -152,7 +152,7 @@ public final class JavaMinecraftServer extends MinecraftServer {
|
||||
platform = split[0];
|
||||
}
|
||||
}
|
||||
MinecraftVersion minecraftVersion = MinecraftVersion.byProtocol(protocol);
|
||||
JavaMinecraftVersion minecraftVersion = JavaMinecraftVersion.byProtocol(protocol);
|
||||
return new Version(name, platform, protocol, minecraftVersion == null ? null : minecraftVersion.getName());
|
||||
}
|
||||
}
|
||||
|
@ -271,13 +271,14 @@ public final class MojangService {
|
||||
* </p>
|
||||
*
|
||||
* @param hostname the hostname of the server
|
||||
* @param port the port of the server, null for default
|
||||
* @return the server favicon
|
||||
* @see #DEFAULT_SERVER_ICON for the default server icon
|
||||
*/
|
||||
public byte[] getServerFavicon(@NonNull String hostname) {
|
||||
public byte[] getServerFavicon(@NonNull String hostname, String port) {
|
||||
String icon = null; // The server base64 icon
|
||||
try {
|
||||
JavaMinecraftServer.Favicon favicon = ((JavaMinecraftServer) getMinecraftServer(MinecraftServer.Platform.JAVA.name(), hostname).getValue()).getFavicon();
|
||||
JavaMinecraftServer.Favicon favicon = ((JavaMinecraftServer) getMinecraftServer(MinecraftServer.Platform.JAVA.name(), hostname, port).getValue()).getFavicon();
|
||||
if (favicon != null) { // Use the server's favicon
|
||||
icon = favicon.getBase64();
|
||||
icon = icon.substring(icon.indexOf(",") + 1); // Remove the data type from the server icon
|
||||
@ -344,35 +345,45 @@ public final class MojangService {
|
||||
*
|
||||
* @param platformName the name of the platform
|
||||
* @param hostname the hostname of the server
|
||||
* @param portString the port of the server, null for default
|
||||
* @return the resolved Minecraft server
|
||||
* @throws BadRequestException if the hostname or platform is invalid
|
||||
* @throws ResourceNotFoundException if the server isn't found
|
||||
* @throws BadRequestException if the hostname or platform is invalid
|
||||
* @throws ResourceNotFoundException if the server isn't found
|
||||
*/
|
||||
@NonNull
|
||||
public CachedMinecraftServer getMinecraftServer(@NonNull String platformName, @NonNull String hostname)
|
||||
public CachedMinecraftServer getMinecraftServer(@NonNull String platformName, @NonNull String hostname, String portString)
|
||||
throws BadRequestException, ResourceNotFoundException {
|
||||
MinecraftServer.Platform platform = EnumUtils.getEnumConstant(MinecraftServer.Platform.class, platformName.toUpperCase());
|
||||
if (platform == null) { // Invalid platform
|
||||
throw new BadRequestException("Invalid platform: %s".formatted(platformName));
|
||||
}
|
||||
String lookupHostname = hostname; // The hostname used to lookup the server
|
||||
String lookupPort = portString; // The port used to lookup the server
|
||||
|
||||
int port = platform.getDefaultPort(); // Port to ping
|
||||
if (portString != null) {
|
||||
try { // Try and parse the port
|
||||
port = Integer.parseInt(portString);
|
||||
} catch (NumberFormatException ex) { // Invalid port
|
||||
throw new BadRequestException("Invalid port defined");
|
||||
}
|
||||
}
|
||||
|
||||
// Check the cache for the server
|
||||
Optional<CachedMinecraftServer> cached = minecraftServerCache.findById(platform.name() + "-" + hostname);
|
||||
Optional<CachedMinecraftServer> cached = minecraftServerCache.findById(platform.name() + "-" + hostname + "-" + port);
|
||||
if (cached.isPresent()) { // Respond with the cache if present
|
||||
log.info("Found server in cache: {}", hostname);
|
||||
return cached.get();
|
||||
}
|
||||
|
||||
InetSocketAddress address = platform == MinecraftServer.Platform.JAVA ? DNSUtils.resolveSRV(hostname) : null; // Resolve the SRV record
|
||||
int port = platform.getDefaultPort(); // Port to ping
|
||||
if (address != null) { // SRV was resolved, use the hostname and port
|
||||
hostname = address.getHostName();
|
||||
port = address.getPort();
|
||||
}
|
||||
|
||||
// Build our server model, cache it, and then return it
|
||||
CachedMinecraftServer minecraftServer = new CachedMinecraftServer(
|
||||
platform.name() + "-" + lookupHostname,
|
||||
platform.name() + "-" + lookupHostname + "-" + (lookupPort == null ? port : lookupPort),
|
||||
platform.getPinger().ping(hostname, port),
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user