change how the port is fetched from the hostname and lowered the timeout for server pings
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 1m33s

This commit is contained in:
Lee 2024-04-10 12:26:47 +01:00
parent 7855b5bcca
commit 3790d4a312
5 changed files with 25 additions and 30 deletions

@ -1,21 +1,11 @@
package cc.fascinated.common; package cc.fascinated.common;
import cc.fascinated.exception.impl.BadRequestException;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
@UtilityClass @UtilityClass
public class ServerUtils { public class ServerUtils {
/**
* Get the hostname and port from a hostname string
*
* @param hostname the hostname string
* @return the hostname and port
*/
public static Tuple<String, Integer> getHostnameAndPort(String hostname) {
String[] split = hostname.split(":");
return new Tuple<>(split[0], split.length == 1 ? -1 : Integer.parseInt(split[1]));
}
/** /**
* Gets the address of the server. * Gets the address of the server.
* *

@ -34,8 +34,7 @@ public class ServerController {
public CachedMinecraftServer getServer( public CachedMinecraftServer getServer(
@Parameter(description = "The platform of the server", example = "java") @PathVariable String platform, @Parameter(description = "The platform of the server", example = "java") @PathVariable String platform,
@Parameter(description = "The hostname and port of the server", example = "play.hypixel.net") @PathVariable String hostname) { @Parameter(description = "The hostname and port of the server", example = "play.hypixel.net") @PathVariable String hostname) {
Tuple<String, Integer> host = ServerUtils.getHostnameAndPort(hostname); return serverService.getServer(platform, hostname);
return serverService.getServer(platform, host.getLeft(), host.getRight());
} }
@ResponseBody @ResponseBody
@ -43,15 +42,12 @@ public class ServerController {
public ResponseEntity<?> getServerIcon( public ResponseEntity<?> getServerIcon(
@Parameter(description = "The hostname and port of the server", example = "play.hypixel.net") @PathVariable String hostname, @Parameter(description = "The hostname and port of the server", example = "play.hypixel.net") @PathVariable String hostname,
@Parameter(description = "Whether to download the image") @RequestParam(required = false, defaultValue = "false") boolean download) { @Parameter(description = "Whether to download the image") @RequestParam(required = false, defaultValue = "false") boolean download) {
Tuple<String, Integer> host = ServerUtils.getHostnameAndPort(hostname);
hostname = host.getLeft();
int port = host.getRight();
String dispositionHeader = download ? "attachment; filename=%s.png" : "inline; filename=%s.png"; String dispositionHeader = download ? "attachment; filename=%s.png" : "inline; filename=%s.png";
return ResponseEntity.ok() return ResponseEntity.ok()
.contentType(MediaType.IMAGE_PNG) .contentType(MediaType.IMAGE_PNG)
.header(HttpHeaders.CONTENT_DISPOSITION, dispositionHeader.formatted(ServerUtils.getAddress(hostname, port))) .header(HttpHeaders.CONTENT_DISPOSITION, dispositionHeader.formatted(hostname))
.body(serverService.getServerFavicon(hostname, port)); .body(serverService.getServerFavicon(hostname));
} }
@ResponseBody @ResponseBody

@ -34,25 +34,36 @@ public class ServerService {
* *
* @param platformName the name of the platform * @param platformName the name of the platform
* @param hostname the hostname of the server * @param hostname the hostname of the server
* @param port the port of the server
* @return the server * @return the server
*/ */
public CachedMinecraftServer getServer(String platformName, String hostname, int port) { public CachedMinecraftServer getServer(String platformName, String hostname) {
MinecraftServer.Platform platform = EnumUtils.getEnumConstant(MinecraftServer.Platform.class, platformName.toUpperCase()); MinecraftServer.Platform platform = EnumUtils.getEnumConstant(MinecraftServer.Platform.class, platformName.toUpperCase());
if (platform == null) { if (platform == null) {
log.info("Invalid platform: {} for server {}", platformName, hostname); log.info("Invalid platform: {} for server {}", platformName, hostname);
throw new BadRequestException("Invalid platform: %s".formatted(platformName)); throw new BadRequestException("Invalid platform: %s".formatted(platformName));
} }
port = port == -1 ? platform.getDefaultPort() : port; // Use the default port if the port is -1 (not provided) int port = platform.getDefaultPort();
if (hostname.contains(":")) {
String[] parts = hostname.split(":");
hostname = parts[0];
try {
port = Integer.parseInt(parts[1]);
} catch (NumberFormatException e) {
log.info("Invalid port: {} for server {}", parts[1], hostname);
throw new BadRequestException("Invalid port: %s".formatted(parts[1]));
}
}
String key = "%s-%s:%s".formatted(platformName, hostname, port); String key = "%s-%s:%s".formatted(platformName, hostname, port);
log.info("Getting server: {}:{}", hostname, port); log.info("Getting server: {}:{}", hostname, port);
// Check if the server is cached
Optional<CachedMinecraftServer> cached = serverCacheRepository.findById(key); Optional<CachedMinecraftServer> cached = serverCacheRepository.findById(key);
if (cached.isPresent()) { if (cached.isPresent()) {
log.info("Server {}:{} is cached", hostname, port); log.info("Server {}:{} is cached", hostname, port);
return cached.get(); return cached.get();
} }
// Resolve the SRV record if the platform is Java
InetSocketAddress address = platform == MinecraftServer.Platform.JAVA ? DNSUtils.resolveSRV(hostname) : null; InetSocketAddress address = platform == MinecraftServer.Platform.JAVA ? DNSUtils.resolveSRV(hostname) : null;
if (address != null) { if (address != null) {
hostname = address.getHostName(); hostname = address.getHostName();
@ -64,7 +75,8 @@ public class ServerService {
System.currentTimeMillis() System.currentTimeMillis()
); );
if (platform == MinecraftServer.Platform.JAVA) { // Check if the server is blocked by Mojang // Check if the server is blocked by Mojang
if (platform == MinecraftServer.Platform.JAVA) {
((JavaMinecraftServer) server.getServer()).setMojangBanned(mojangService.isServerBlocked(hostname)); ((JavaMinecraftServer) server.getServer()).setMojangBanned(mojangService.isServerBlocked(hostname));
} }
@ -78,13 +90,12 @@ public class ServerService {
* Gets the server favicon. * Gets the server favicon.
* *
* @param hostname the hostname of the server * @param hostname the hostname of the server
* @param port the port of the server
* @return the server favicon, null if not found * @return the server favicon, null if not found
*/ */
public byte[] getServerFavicon(String hostname, int port) { public byte[] getServerFavicon(String hostname) {
String icon = null; // The server base64 icon String icon = null; // The server base64 icon
try { try {
JavaMinecraftServer.Favicon favicon = ((JavaMinecraftServer) getServer(MinecraftServer.Platform.JAVA.name(), hostname, port).getServer()).getFavicon(); JavaMinecraftServer.Favicon favicon = ((JavaMinecraftServer) getServer(MinecraftServer.Platform.JAVA.name(), hostname).getServer()).getFavicon();
if (favicon != null) { // Use the server's favicon if (favicon != null) { // Use the server's favicon
icon = favicon.getBase64(); icon = favicon.getBase64();
icon = icon.substring(icon.indexOf(",") + 1); // Remove the data type from the server icon icon = icon.substring(icon.indexOf(",") + 1); // Remove the data type from the server icon

@ -21,7 +21,7 @@ import java.net.*;
*/ */
@Log4j2(topic = "Bedrock MC Server Pinger") @Log4j2(topic = "Bedrock MC Server Pinger")
public final class BedrockMinecraftServerPinger implements MinecraftServerPinger<BedrockMinecraftServer> { public final class BedrockMinecraftServerPinger implements MinecraftServerPinger<BedrockMinecraftServer> {
private static final int TIMEOUT = 3000; // The timeout for the socket private static final int TIMEOUT = 1500; // The timeout for the socket
/** /**
* Ping the server with the given hostname and port. * Ping the server with the given hostname and port.

@ -22,9 +22,7 @@ import java.net.*;
*/ */
@Log4j2(topic = "Java Pinger") @Log4j2(topic = "Java Pinger")
public final class JavaMinecraftServerPinger implements MinecraftServerPinger<JavaMinecraftServer> { public final class JavaMinecraftServerPinger implements MinecraftServerPinger<JavaMinecraftServer> {
public static final JavaMinecraftServerPinger INSTANCE = new JavaMinecraftServerPinger(); private static final int TIMEOUT = 1500; // The timeout for the socket
private static final int TIMEOUT = 3000; // The timeout for the socket
@Override @Override
public JavaMinecraftServer ping(String hostname, int port) { public JavaMinecraftServer ping(String hostname, int port) {