add bedrock server support
Some checks failed
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Failing after 20s
Some checks failed
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Failing after 20s
This commit is contained in:
@ -12,7 +12,6 @@ import io.micrometer.common.lang.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import net.jodah.expiringmap.ExpirationPolicy;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
@ -38,14 +38,15 @@ public class ServerService {
|
||||
* @return the server
|
||||
*/
|
||||
public CachedMinecraftServer getServer(String platformName, String hostname, int port) {
|
||||
log.info("Getting server: {} {}:{}", platformName, hostname, port);
|
||||
MinecraftServer.Platform platform = EnumUtils.getEnumConstant(MinecraftServer.Platform.class, platformName.toUpperCase());
|
||||
if (platform == null) {
|
||||
log.info("Invalid platform: {} for server {}:{}", platformName, hostname, port);
|
||||
log.info("Invalid platform: {} for server {}", platformName, hostname);
|
||||
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)
|
||||
String key = "%s-%s:%s".formatted(platformName, hostname, port);
|
||||
|
||||
log.info("Getting server: {}:{}", hostname, port);
|
||||
Optional<CachedMinecraftServer> cached = serverCacheRepository.findById(key);
|
||||
if (cached.isPresent()) {
|
||||
log.info("Server {}:{} is cached", hostname, port);
|
||||
@ -54,7 +55,6 @@ public class ServerService {
|
||||
|
||||
InetSocketAddress address = platform == MinecraftServer.Platform.JAVA ? DNSUtils.resolveSRV(hostname) : null;
|
||||
if (address != null) {
|
||||
port = port != -1 ? port : platform.getDefaultPort(); // If the port is -1, set it to the default port
|
||||
hostname = address.getHostName();
|
||||
}
|
||||
|
||||
@ -65,8 +65,7 @@ public class ServerService {
|
||||
);
|
||||
|
||||
if (platform == MinecraftServer.Platform.JAVA) { // Check if the server is blocked by Mojang
|
||||
JavaMinecraftServer javaServer = (JavaMinecraftServer) server.getServer();
|
||||
javaServer.setMojangBanned(mojangService.isServerBlocked(hostname));
|
||||
((JavaMinecraftServer) server.getServer()).setMojangBanned(mojangService.isServerBlocked(hostname));
|
||||
}
|
||||
|
||||
log.info("Found server: {}:{}", hostname, port);
|
||||
|
@ -0,0 +1,72 @@
|
||||
package cc.fascinated.service.pinger.impl;
|
||||
|
||||
import cc.fascinated.common.DNSUtils;
|
||||
import cc.fascinated.common.packet.impl.bedrock.BedrockPacketUnconnectedPing;
|
||||
import cc.fascinated.common.packet.impl.bedrock.BedrockPacketUnconnectedPong;
|
||||
import cc.fascinated.exception.impl.BadRequestException;
|
||||
import cc.fascinated.exception.impl.ResourceNotFoundException;
|
||||
import cc.fascinated.model.server.BedrockMinecraftServer;
|
||||
import cc.fascinated.service.pinger.MinecraftServerPinger;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
|
||||
/**
|
||||
* The {@link MinecraftServerPinger} for pinging
|
||||
* {@link BedrockMinecraftServer} over UDP.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
@Log4j2(topic = "Bedrock MC Server Pinger")
|
||||
public final class BedrockMinecraftServerPinger implements MinecraftServerPinger<BedrockMinecraftServer> {
|
||||
private static final int TIMEOUT = 3000; // The timeout for the socket
|
||||
|
||||
/**
|
||||
* Ping the server with the given hostname and port.
|
||||
*
|
||||
* @param hostname the hostname of the server
|
||||
* @param port the port of the server
|
||||
* @return the server that was pinged
|
||||
*/
|
||||
@Override
|
||||
public BedrockMinecraftServer 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: {} -> {}", hostname, ip);
|
||||
}
|
||||
log.info("Pinging {}:{}...", hostname, port);
|
||||
long before = System.currentTimeMillis(); // Timestamp before pinging
|
||||
|
||||
// Open a socket connection to the server
|
||||
try (DatagramSocket socket = new DatagramSocket()) {
|
||||
socket.setSoTimeout(TIMEOUT);
|
||||
socket.connect(new InetSocketAddress(hostname, port));
|
||||
|
||||
long ping = System.currentTimeMillis() - before; // Calculate the ping
|
||||
log.info("Pinged {}:{} in {}ms", hostname, port, ping);
|
||||
|
||||
// Send the unconnected ping packet
|
||||
new BedrockPacketUnconnectedPing().process(socket);
|
||||
|
||||
// Handle the received unconnected pong packet
|
||||
BedrockPacketUnconnectedPong unconnectedPong = new BedrockPacketUnconnectedPong();
|
||||
unconnectedPong.process(socket);
|
||||
String response = unconnectedPong.getResponse();
|
||||
if (response == null) { // No pong response
|
||||
throw new ResourceNotFoundException("Server didn't respond to ping");
|
||||
}
|
||||
return BedrockMinecraftServer.create(hostname, ip, port, response); // Return the server
|
||||
} catch (IOException ex) {
|
||||
if (ex instanceof UnknownHostException) {
|
||||
throw new BadRequestException("Unknown hostname: %s".formatted(hostname));
|
||||
} else if (ex instanceof SocketTimeoutException) {
|
||||
throw new ResourceNotFoundException(ex);
|
||||
}
|
||||
log.error("An error occurred pinging %s:%s:".formatted(hostname, port), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ import cc.fascinated.exception.impl.BadRequestException;
|
||||
import cc.fascinated.exception.impl.ResourceNotFoundException;
|
||||
import cc.fascinated.model.mojang.JavaServerStatusToken;
|
||||
import cc.fascinated.model.server.JavaMinecraftServer;
|
||||
import cc.fascinated.model.server.MinecraftServer;
|
||||
import cc.fascinated.service.pinger.MinecraftServerPinger;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
|
||||
|
Reference in New Issue
Block a user