StatusAPI/src/main/java/net/viper/status/StatusAPI.java aktualisiert
This commit is contained in:
@@ -1,29 +1,47 @@
|
|||||||
package net.viper.status;
|
package net.viper.status;
|
||||||
|
|
||||||
|
import net.luckperms.api.LuckPerms;
|
||||||
|
import net.luckperms.api.LuckPermsProvider; // <--- HINZUGEFÜGT
|
||||||
|
import net.luckperms.api.model.user.User;
|
||||||
|
import net.luckperms.api.query.QueryOptions;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.config.ListenerInfo;
|
import net.md_5.bungee.api.config.ListenerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class StatusAPI extends Plugin implements Runnable {
|
public class StatusAPI extends Plugin implements Runnable {
|
||||||
|
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
private int port = 9191;
|
private int port = 9191;
|
||||||
|
private UpdateChecker updateChecker;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
getLogger().info("StatusAPI wird aktiviert...");
|
getLogger().info("StatusAPI wird aktiviert...");
|
||||||
getLogger().info("Starte Web-Server auf Port " + port + "...");
|
getLogger().info("Starte Web-Server auf Port " + port + "...");
|
||||||
|
|
||||||
thread = new Thread(this);
|
// Start HTTP server thread
|
||||||
|
thread = new Thread(this, "StatusAPI-HTTP-Server");
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
|
// Start UpdateChecker: initialer Check (async) + regelmäßiger Schedule
|
||||||
|
String currentVersion = getDescription() != null ? getDescription().getVersion() : "0.0.0";
|
||||||
|
updateChecker = new UpdateChecker(this, currentVersion, 6); // 6 Stunden Intervall
|
||||||
|
|
||||||
|
// initialer sofortiger Start (async)
|
||||||
|
ProxyServer.getInstance().getScheduler().runAsync(this, () -> updateChecker.checkNow());
|
||||||
|
|
||||||
|
// planmäßiger Intervall (alle 6 Stunden)
|
||||||
|
ProxyServer.getInstance().getScheduler().schedule(this, updateChecker, 6, 6, TimeUnit.HOURS);
|
||||||
|
|
||||||
|
// Register join listener to notify OPs on login
|
||||||
|
ProxyServer.getInstance().getPluginManager().registerListener(this, new UpdateListener(this, updateChecker));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,6 +49,9 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
getLogger().info("Stoppe Web-Server...");
|
getLogger().info("Stoppe Web-Server...");
|
||||||
if (thread != null) {
|
if (thread != null) {
|
||||||
thread.interrupt();
|
thread.interrupt();
|
||||||
|
try {
|
||||||
|
thread.join(1000);
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,13 +65,13 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
Socket clientSocket = serverSocket.accept();
|
Socket clientSocket = serverSocket.accept();
|
||||||
handleConnection(clientSocket);
|
handleConnection(clientSocket);
|
||||||
} catch (java.net.SocketTimeoutException e) {
|
} catch (java.net.SocketTimeoutException e) {
|
||||||
// Loop Check
|
// Loop Check (timeout) - erlaubt Unterbrechungsschleife
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Ignorieren
|
getLogger().warning("Fehler beim Akzeptieren einer Verbindung: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
getLogger().severe("Konnte ServerSocket nicht starten auf Port " + port);
|
getLogger().severe("Konnte ServerSocket nicht starten auf Port " + port + ": " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,24 +81,24 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
OutputStream out = null;
|
OutputStream out = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
|
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "UTF-8"));
|
||||||
out = clientSocket.getOutputStream();
|
out = clientSocket.getOutputStream();
|
||||||
|
|
||||||
String inputLine = in.readLine();
|
String inputLine = in.readLine();
|
||||||
|
|
||||||
if (inputLine != null && inputLine.startsWith("GET")) {
|
if (inputLine != null && inputLine.startsWith("GET")) {
|
||||||
|
|
||||||
Map<String, Object> data = new HashMap<>();
|
Map<String, Object> data = new LinkedHashMap<>();
|
||||||
data.put("online", true);
|
data.put("online", true);
|
||||||
|
|
||||||
// --- VERSION CLEANUP START ---
|
// --- VERSION CLEANUP START ---
|
||||||
String versionRaw = ProxyServer.getInstance().getVersion();
|
String versionRaw = ProxyServer.getInstance().getVersion();
|
||||||
String versionClean = versionRaw;
|
String versionClean = versionRaw;
|
||||||
|
|
||||||
if (versionRaw.contains("BungeeCord-Bootstrap:")) {
|
if (versionRaw != null && versionRaw.contains(":")) {
|
||||||
String[] parts = versionRaw.split(":");
|
String[] parts = versionRaw.split(":");
|
||||||
if (parts.length >= 3) {
|
if (parts.length >= 3) {
|
||||||
versionClean = parts[2];
|
versionClean = parts[2].trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.put("version", versionClean);
|
data.put("version", versionClean);
|
||||||
@@ -87,20 +108,53 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
|
|
||||||
String motd = "BungeeCord";
|
String motd = "BungeeCord";
|
||||||
try {
|
try {
|
||||||
ListenerInfo listener = ProxyServer.getInstance().getConfig().getListeners().iterator().next();
|
Iterator<ListenerInfo> it = ProxyServer.getInstance().getConfig().getListeners().iterator();
|
||||||
if (listener != null) {
|
if (it.hasNext()) {
|
||||||
|
ListenerInfo listener = it.next();
|
||||||
|
if (listener != null && listener.getMotd() != null) {
|
||||||
motd = listener.getMotd();
|
motd = listener.getMotd();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Fallback
|
// Fallback bleibt "BungeeCord"
|
||||||
}
|
}
|
||||||
data.put("motd", motd);
|
data.put("motd", motd);
|
||||||
|
|
||||||
List<String> playerNames = new ArrayList<>();
|
// --- LUCKPERMS INTEGRATION START ---
|
||||||
for (net.md_5.bungee.api.connection.ProxiedPlayer p : ProxyServer.getInstance().getPlayers()) {
|
// LuckPerms API über Provider holen (Verhindert ClassCastException)
|
||||||
playerNames.add(p.getName());
|
LuckPerms luckPermsApi = null;
|
||||||
|
try {
|
||||||
|
luckPermsApi = LuckPermsProvider.get();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// LuckPerms ist nicht geladen
|
||||||
}
|
}
|
||||||
data.put("players", playerNames);
|
|
||||||
|
List<Map<String, String>> playersList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ProxiedPlayer p : ProxyServer.getInstance().getPlayers()) {
|
||||||
|
Map<String, String> playerInfo = new LinkedHashMap<>();
|
||||||
|
playerInfo.put("name", p.getName());
|
||||||
|
|
||||||
|
// Prefix abfragen, falls LP gefunden wurde
|
||||||
|
String prefix = "";
|
||||||
|
if (luckPermsApi != null) {
|
||||||
|
User user = luckPermsApi.getUserManager().getUser(p.getUniqueId());
|
||||||
|
if (user != null) {
|
||||||
|
// Context bestimmen (Global oder Server-spezifisch)
|
||||||
|
QueryOptions queryOptions = luckPermsApi.getContextManager().getQueryOptions(user)
|
||||||
|
.orElse(QueryOptions.defaultContextualOptions());
|
||||||
|
|
||||||
|
String lpPrefix = user.getCachedData().getMetaData(queryOptions).getPrefix();
|
||||||
|
if (lpPrefix != null) {
|
||||||
|
prefix = lpPrefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playerInfo.put("prefix", prefix);
|
||||||
|
playersList.add(playerInfo);
|
||||||
|
}
|
||||||
|
data.put("players", playersList);
|
||||||
|
// --- LUCKPERMS INTEGRATION ENDE ---
|
||||||
|
|
||||||
String json = buildJsonString(data);
|
String json = buildJsonString(data);
|
||||||
byte[] jsonBytes = json.getBytes("UTF-8");
|
byte[] jsonBytes = json.getBytes("UTF-8");
|
||||||
@@ -119,6 +173,11 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
// Body senden
|
// Body senden
|
||||||
out.write(jsonBytes);
|
out.write(jsonBytes);
|
||||||
out.flush();
|
out.flush();
|
||||||
|
} else {
|
||||||
|
// Ungültige Anfrage -> 400
|
||||||
|
String resp = "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n";
|
||||||
|
out.write(resp.getBytes("UTF-8"));
|
||||||
|
out.flush();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
getLogger().severe("Fehler beim Verarbeiten der Anfrage: " + e.getMessage());
|
getLogger().severe("Fehler beim Verarbeiten der Anfrage: " + e.getMessage());
|
||||||
@@ -137,32 +196,56 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rekursiver JSON Builder, der nun auch Listen von Objekten (Maps) verarbeiten kann.
|
||||||
|
*/
|
||||||
private String buildJsonString(Map<String, Object> data) {
|
private String buildJsonString(Map<String, Object> data) {
|
||||||
StringBuilder sb = new StringBuilder("{");
|
StringBuilder sb = new StringBuilder("{");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||||
if (!first) sb.append(",");
|
if (!first) sb.append(",");
|
||||||
first = false;
|
first = false;
|
||||||
sb.append("\"").append(entry.getKey()).append("\":");
|
sb.append("\"").append(escapeJson(entry.getKey())).append("\":");
|
||||||
|
|
||||||
Object value = entry.getValue();
|
// Wert verarbeiten (String, Boolean, List oder Map)
|
||||||
if (value instanceof List) {
|
sb.append(valueToString(entry.getValue()));
|
||||||
sb.append("[");
|
|
||||||
List<?> list = (List<?>) value;
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
if (i > 0) sb.append(",");
|
|
||||||
sb.append("\"").append(list.get(i)).append("\"");
|
|
||||||
}
|
|
||||||
sb.append("]");
|
|
||||||
} else if (value instanceof String) {
|
|
||||||
sb.append("\"").append(((String) value).replace("\"", "\\\"")).append("\"");
|
|
||||||
} else if (value instanceof Boolean) {
|
|
||||||
sb.append(value);
|
|
||||||
} else {
|
|
||||||
sb.append("\"").append(value).append("\"");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sb.append("}");
|
sb.append("}");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hilfsmethode, um verschiedene Objekttypen in JSON-Strings umzuwandeln.
|
||||||
|
*/
|
||||||
|
private String valueToString(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return "null";
|
||||||
|
} else if (value instanceof Boolean) {
|
||||||
|
return value.toString();
|
||||||
|
} else if (value instanceof List) {
|
||||||
|
StringBuilder sb = new StringBuilder("[");
|
||||||
|
List<?> list = (List<?>) value;
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
if (i > 0) sb.append(",");
|
||||||
|
Object item = list.get(i);
|
||||||
|
// Wenn es eine Map ist (Player-Objekt), rufen wir buildJsonString rekursiv auf
|
||||||
|
if (item instanceof Map) {
|
||||||
|
sb.append(buildJsonString((Map<String, Object>) item));
|
||||||
|
} else {
|
||||||
|
// Andernfalls String behandeln
|
||||||
|
sb.append("\"").append(escapeJson(String.valueOf(item))).append("\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("]");
|
||||||
|
return sb.toString();
|
||||||
|
} else {
|
||||||
|
// Standard String Behandlung
|
||||||
|
return "\"" + escapeJson(String.valueOf(value)) + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String escapeJson(String s) {
|
||||||
|
if (s == null) return "";
|
||||||
|
return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user