mirror of
https://github.com/filoghost/HolographicDisplays.git
synced 2024-11-15 23:15:10 +01:00
Use pinger utility in FCommons
This commit is contained in:
parent
f6c7fd5f0f
commit
1eb58dfd0a
@ -6,12 +6,13 @@
|
||||
package me.filoghost.holographicdisplays.plugin.bridge.bungeecord;
|
||||
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.fcommons.ping.MinecraftServerPinger;
|
||||
import me.filoghost.fcommons.ping.PingParseException;
|
||||
import me.filoghost.fcommons.ping.PingResponse;
|
||||
import me.filoghost.holographicdisplays.common.DebugLogger;
|
||||
import me.filoghost.holographicdisplays.plugin.HolographicDisplays;
|
||||
import me.filoghost.holographicdisplays.plugin.bridge.bungeecord.pinger.PingResponse;
|
||||
import me.filoghost.holographicdisplays.plugin.bridge.bungeecord.pinger.ServerPinger;
|
||||
import me.filoghost.holographicdisplays.plugin.disk.Settings;
|
||||
import me.filoghost.holographicdisplays.plugin.disk.ServerAddress;
|
||||
import me.filoghost.holographicdisplays.plugin.disk.Settings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -94,17 +95,23 @@ public class BungeeServerTracker {
|
||||
|
||||
private ServerInfo pingServer(ServerAddress serverAddress) {
|
||||
try {
|
||||
PingResponse data = ServerPinger.fetchData(serverAddress, Settings.pingerTimeout);
|
||||
PingResponse data = MinecraftServerPinger.ping(serverAddress.getAddress(), serverAddress.getPort(), Settings.pingerTimeout);
|
||||
return ServerInfo.online(data.getOnlinePlayers(), data.getMaxPlayers(), data.getMotd());
|
||||
} catch (SocketTimeoutException e) {
|
||||
// Common error, do not log
|
||||
} catch (UnknownHostException e) {
|
||||
Log.warning("Couldn't fetch data from " + serverAddress + ": unknown host address.");
|
||||
} catch (IOException e) {
|
||||
Log.warning("Couldn't fetch data from " + serverAddress + ".", e);
|
||||
}
|
||||
|
||||
return ServerInfo.offline(Settings.pingerOfflineMotd);
|
||||
} catch (PingParseException e) {
|
||||
DebugLogger.warning("Received invalid JSON response from IP \"" + serverAddress + "\": " + e.getJsonString());
|
||||
return ServerInfo.online(0, 0, "Invalid ping response (" + e.getMessage() + ")");
|
||||
|
||||
} catch (IOException e) {
|
||||
if (e instanceof SocketTimeoutException) {
|
||||
// Common error, do not log
|
||||
} else if (e instanceof UnknownHostException) {
|
||||
Log.warning("Couldn't fetch data from " + serverAddress + ": unknown host address.");
|
||||
} else {
|
||||
Log.warning("Couldn't fetch data from " + serverAddress + ".", e);
|
||||
}
|
||||
return ServerInfo.offline(Settings.pingerOfflineMotd);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeUnusedServers() {
|
||||
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) filoghost and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.plugin.bridge.bungeecord.pinger;
|
||||
|
||||
import me.filoghost.holographicdisplays.common.DebugLogger;
|
||||
import me.filoghost.holographicdisplays.plugin.disk.ServerAddress;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
public class PingResponse {
|
||||
|
||||
private final String motd;
|
||||
private final int onlinePlayers;
|
||||
private final int maxPlayers;
|
||||
|
||||
private PingResponse(String motd, int onlinePlayers, int maxPlayers) {
|
||||
this.motd = motd;
|
||||
this.onlinePlayers = onlinePlayers;
|
||||
this.maxPlayers = maxPlayers;
|
||||
}
|
||||
|
||||
protected static PingResponse fromJson(String jsonString, ServerAddress address) {
|
||||
if (jsonString == null || jsonString.isEmpty()) {
|
||||
return errorResponse("Invalid ping response (null or empty)", jsonString, address);
|
||||
}
|
||||
|
||||
Object jsonObject = JSONValue.parse(jsonString);
|
||||
|
||||
if (!(jsonObject instanceof JSONObject)) {
|
||||
return errorResponse("Invalid ping response (wrong format)", jsonString, address);
|
||||
}
|
||||
|
||||
JSONObject json = (JSONObject) jsonObject;
|
||||
|
||||
Object descriptionObject = json.get("description");
|
||||
|
||||
String motd;
|
||||
int onlinePlayers = 0;
|
||||
int maxPlayers = 0;
|
||||
|
||||
if (descriptionObject == null) {
|
||||
return errorResponse("Invalid ping response (description not found)", jsonString, address);
|
||||
}
|
||||
|
||||
if (descriptionObject instanceof JSONObject) {
|
||||
String descriptionString = ((JSONObject) descriptionObject).toJSONString();
|
||||
try {
|
||||
motd = ComponentSerializer.parse(descriptionString)[0].toLegacyText();
|
||||
} catch (Exception e) {
|
||||
return errorResponse("Invalid ping response (could not parse description)", jsonString, address);
|
||||
}
|
||||
} else {
|
||||
motd = descriptionObject.toString();
|
||||
}
|
||||
|
||||
Object playersObject = json.get("players");
|
||||
|
||||
if (playersObject instanceof JSONObject) {
|
||||
JSONObject playersJson = (JSONObject) playersObject;
|
||||
|
||||
Object onlineObject = playersJson.get("online");
|
||||
if (onlineObject instanceof Number) {
|
||||
onlinePlayers = ((Number) onlineObject).intValue();
|
||||
}
|
||||
|
||||
Object maxObject = playersJson.get("max");
|
||||
if (maxObject instanceof Number) {
|
||||
maxPlayers = ((Number) maxObject).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
return new PingResponse(motd, onlinePlayers, maxPlayers);
|
||||
}
|
||||
|
||||
private static PingResponse errorResponse(String error, String jsonString, ServerAddress address) {
|
||||
DebugLogger.warning("Received invalid JSON response from IP \"" + address + "\": " + jsonString);
|
||||
return new PingResponse(error, 0, 0);
|
||||
}
|
||||
|
||||
public String getMotd() {
|
||||
return motd;
|
||||
}
|
||||
|
||||
public int getOnlinePlayers() {
|
||||
return onlinePlayers;
|
||||
}
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return maxPlayers;
|
||||
}
|
||||
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) filoghost and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.plugin.bridge.bungeecord.pinger;
|
||||
|
||||
import me.filoghost.holographicdisplays.plugin.disk.ServerAddress;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class ServerPinger {
|
||||
|
||||
public static PingResponse fetchData(final ServerAddress serverAddress, int timeout) throws IOException {
|
||||
try (Socket socket = openSocket(serverAddress)) {
|
||||
socket.setSoTimeout(timeout);
|
||||
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
||||
DataInputStream in = new DataInputStream(socket.getInputStream());
|
||||
|
||||
// Handshake packet
|
||||
ByteArrayOutputStream handshakeBytes = new ByteArrayOutputStream();
|
||||
DataOutputStream handshakeOut = new DataOutputStream(handshakeBytes);
|
||||
handshakeOut.writeByte(0x00); // Packet ID
|
||||
writeVarInt(handshakeOut, 4); // Protocol version
|
||||
writeString(handshakeOut, serverAddress.getAddress());
|
||||
handshakeOut.writeShort(serverAddress.getPort());
|
||||
writeVarInt(handshakeOut, 1); // Next state: status request
|
||||
writeByteArray(out, handshakeBytes.toByteArray());
|
||||
|
||||
// Status request packet
|
||||
writeByteArray(out, new byte[]{0x00}); // Packet ID
|
||||
|
||||
// Response packet
|
||||
readVarInt(in); // Packet size
|
||||
readVarInt(in); // Packet ID
|
||||
String responseJson = readString(in);
|
||||
|
||||
return PingResponse.fromJson(responseJson, serverAddress);
|
||||
}
|
||||
}
|
||||
|
||||
private static Socket openSocket(ServerAddress serverAddress) throws IOException {
|
||||
return new Socket(serverAddress.getAddress(), serverAddress.getPort());
|
||||
}
|
||||
|
||||
private static String readString(DataInputStream in) throws IOException {
|
||||
byte[] bytes = readByteArray(in);
|
||||
return new String(bytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private static void writeString(DataOutputStream out, String s) throws IOException {
|
||||
byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
|
||||
writeByteArray(out, bytes);
|
||||
}
|
||||
|
||||
private static byte[] readByteArray(DataInputStream in) throws IOException {
|
||||
int length = readVarInt(in);
|
||||
byte[] bytes = new byte[length];
|
||||
in.readFully(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static void writeByteArray(DataOutputStream out, byte[] bytes) throws IOException {
|
||||
writeVarInt(out, bytes.length);
|
||||
out.write(bytes);
|
||||
}
|
||||
|
||||
private static int readVarInt(DataInputStream in) throws IOException {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (true) {
|
||||
int k = in.readByte();
|
||||
i |= (k & 0x7F) << j++ * 7;
|
||||
if (j > 5) {
|
||||
throw new RuntimeException("VarInt too big");
|
||||
}
|
||||
if ((k & 0x80) != 0x80) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
|
||||
while ((paramInt & 0xFFFFFF80) != 0x0) {
|
||||
out.writeByte((paramInt & 0x7F) | 0x80);
|
||||
paramInt >>>= 7;
|
||||
}
|
||||
out.writeByte(paramInt);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user