From 1d5aa930f0e43a04ec92da8ca631edeeca21e5a2 Mon Sep 17 00:00:00 2001
From: Rainnny7
Date: Wed, 10 Apr 2024 04:20:39 -0400
Subject: [PATCH] Added the ability to specify a port in server and server
favicon requests
---
.gitea/workflows/deploy.yml | 2 +-
...Version.java => JavaMinecraftVersion.java} | 91 ++++---------------
.../mc/controller/ServerController.java | 16 ++--
.../mc/model/server/JavaMinecraftServer.java | 4 +-
.../me/braydon/mc/service/MojangService.java | 29 ++++--
5 files changed, 52 insertions(+), 90 deletions(-)
rename src/main/java/me/braydon/mc/common/{MinecraftVersion.java => JavaMinecraftVersion.java} (62%)
diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml
index 80abb05..3555574 100644
--- a/.gitea/workflows/deploy.yml
+++ b/.gitea/workflows/deploy.yml
@@ -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
diff --git a/src/main/java/me/braydon/mc/common/MinecraftVersion.java b/src/main/java/me/braydon/mc/common/JavaMinecraftVersion.java
similarity index 62%
rename from src/main/java/me/braydon/mc/common/MinecraftVersion.java
rename to src/main/java/me/braydon/mc/common/JavaMinecraftVersion.java
index a49b152..a55d178 100644
--- a/src/main/java/me/braydon/mc/common/MinecraftVersion.java
+++ b/src/main/java/me/braydon/mc/common/JavaMinecraftVersion.java
@@ -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 Protocol Version Numbers
* @see Spigot NMS (1.16+)
* @see Spigot NMS (1.10 - 1.15)
* @see Spigot NMS (1.8 - 1.9)
*/
-@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;
}
diff --git a/src/main/java/me/braydon/mc/controller/ServerController.java b/src/main/java/me/braydon/mc/controller/ServerController.java
index eb55fd9..691a97b 100644
--- a/src/main/java/me/braydon/mc/controller/ServerController.java
+++ b/src/main/java/me/braydon/mc/controller/ServerController.java
@@ -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 getServer(@PathVariable @NonNull String platform, @PathVariable @NonNull String hostname)
- throws BadRequestException, ResourceNotFoundException
- {
- return ResponseEntity.ofNullable(mojangService.getMinecraftServer(platform, hostname));
+ public ResponseEntity 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 getServerFavicon(@PathVariable @NonNull String hostname) {
+ public ResponseEntity 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));
}
}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/mc/model/server/JavaMinecraftServer.java b/src/main/java/me/braydon/mc/model/server/JavaMinecraftServer.java
index 7a02e4c..2050493 100644
--- a/src/main/java/me/braydon/mc/model/server/JavaMinecraftServer.java
+++ b/src/main/java/me/braydon/mc/model/server/JavaMinecraftServer.java
@@ -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());
}
}
diff --git a/src/main/java/me/braydon/mc/service/MojangService.java b/src/main/java/me/braydon/mc/service/MojangService.java
index 08c8739..0626f38 100644
--- a/src/main/java/me/braydon/mc/service/MojangService.java
+++ b/src/main/java/me/braydon/mc/service/MojangService.java
@@ -271,13 +271,14 @@ public final class MojangService {
*
*
* @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 cached = minecraftServerCache.findById(platform.name() + "-" + hostname);
+ Optional 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()
);