Server pinger
This commit is contained in:
parent
617c19bf3c
commit
eadfb191b2
@ -2,16 +2,15 @@ package me.braydon.mc.service;
|
|||||||
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import me.braydon.mc.common.EnumUtils;
|
||||||
import me.braydon.mc.common.Tuple;
|
import me.braydon.mc.common.Tuple;
|
||||||
import me.braydon.mc.common.UUIDUtils;
|
import me.braydon.mc.common.UUIDUtils;
|
||||||
import me.braydon.mc.common.web.JsonWebException;
|
import me.braydon.mc.common.web.JsonWebException;
|
||||||
import me.braydon.mc.common.web.JsonWebRequest;
|
import me.braydon.mc.common.web.JsonWebRequest;
|
||||||
import me.braydon.mc.exception.impl.BadRequestException;
|
import me.braydon.mc.exception.impl.BadRequestException;
|
||||||
|
import me.braydon.mc.exception.impl.InvalidMinecraftServerPlatform;
|
||||||
import me.braydon.mc.exception.impl.ResourceNotFoundException;
|
import me.braydon.mc.exception.impl.ResourceNotFoundException;
|
||||||
import me.braydon.mc.model.Cape;
|
import me.braydon.mc.model.*;
|
||||||
import me.braydon.mc.model.Player;
|
|
||||||
import me.braydon.mc.model.ProfileAction;
|
|
||||||
import me.braydon.mc.model.Skin;
|
|
||||||
import me.braydon.mc.model.cache.CachedPlayer;
|
import me.braydon.mc.model.cache.CachedPlayer;
|
||||||
import me.braydon.mc.model.cache.CachedPlayerName;
|
import me.braydon.mc.model.cache.CachedPlayerName;
|
||||||
import me.braydon.mc.model.token.MojangProfileToken;
|
import me.braydon.mc.model.token.MojangProfileToken;
|
||||||
@ -130,6 +129,14 @@ public final class MojangService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MinecraftServer getMinecraftServer(@NonNull String platformName, @NonNull String hostname) throws InvalidMinecraftServerPlatform {
|
||||||
|
MinecraftServer.Platform platform = EnumUtils.getEnumConstant(MinecraftServer.Platform.class, platformName.toUpperCase());
|
||||||
|
if (platform == null) { // Invalid platform
|
||||||
|
throw new InvalidMinecraftServerPlatform();
|
||||||
|
}
|
||||||
|
return platform.getPinger().ping(hostname, 25565);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the UUID of a player by their username.
|
* Get the UUID of a player by their username.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package me.braydon.mc.service.pinger;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.braydon.mc.model.MinecraftServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MinecraftServerPinger} is
|
||||||
|
* used to ping a {@link MinecraftServer}.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
* @param <T> the type of server to ping
|
||||||
|
*/
|
||||||
|
public interface MinecraftServerPinger<T extends MinecraftServer> {
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
T ping(@NonNull String hostname, int port);
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package me.braydon.mc.service.pinger.impl;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import me.braydon.mc.model.server.BedrockMinecraftServer;
|
||||||
|
import me.braydon.mc.service.pinger.MinecraftServerPinger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link MinecraftServerPinger} for
|
||||||
|
* pinging {@link BedrockMinecraftServer}'s.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
@Log4j2(topic = "Bedrock MC Server Pinger")
|
||||||
|
public final class BedrockMinecraftServerPinger implements MinecraftServerPinger<BedrockMinecraftServer> {
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
throw new UnsupportedOperationException("Not yet implemented.");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
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.packet.impl.PacketHandshakingInSetProtocol;
|
||||||
|
import me.braydon.mc.common.packet.impl.PacketStatusInStart;
|
||||||
|
import me.braydon.mc.model.server.JavaMinecraftServer;
|
||||||
|
import me.braydon.mc.model.token.JavaServerStatusToken;
|
||||||
|
import me.braydon.mc.service.pinger.MinecraftServerPinger;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link MinecraftServerPinger} for
|
||||||
|
* pinging {@link JavaMinecraftServer}'s.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
@Log4j2(topic = "Java MC Server Pinger")
|
||||||
|
public final class JavaMinecraftServerPinger implements MinecraftServerPinger<JavaMinecraftServer> {
|
||||||
|
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 JavaMinecraftServer ping(@NonNull String hostname, int port) {
|
||||||
|
log.info("Pinging {}:{}...", hostname, port);
|
||||||
|
long before = System.currentTimeMillis(); // Timestamp before pinging
|
||||||
|
|
||||||
|
// Open a socket connection to the server
|
||||||
|
try (Socket socket = new Socket()) {
|
||||||
|
socket.setTcpNoDelay(true);
|
||||||
|
socket.connect(new InetSocketAddress(hostname, port), TIMEOUT);
|
||||||
|
long ping = System.currentTimeMillis() - before; // Calculate the ping
|
||||||
|
log.info("Pinged {}:{} in {}ms", hostname, port, ping);
|
||||||
|
|
||||||
|
// Open data streams to begin packet transaction
|
||||||
|
try (DataInputStream inputStream = new DataInputStream(socket.getInputStream());
|
||||||
|
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream())) {
|
||||||
|
// Begin handshaking with the server
|
||||||
|
new PacketHandshakingInSetProtocol(hostname, port, 47).process(inputStream, outputStream);
|
||||||
|
|
||||||
|
// Send the status request to the server, and await back the response
|
||||||
|
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
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
log.error("An error occurred pinging %s:%s:".formatted(hostname, port), ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user