diff --git a/src/main/java/net/viper/status/modules/verify/VerifyModule.java b/src/main/java/net/viper/status/modules/verify/VerifyModule.java deleted file mode 100644 index f065a12..0000000 --- a/src/main/java/net/viper/status/modules/verify/VerifyModule.java +++ /dev/null @@ -1,248 +0,0 @@ -package net.viper.status.modules.verify; - -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.plugin.Command; -import net.md_5.bungee.api.plugin.Plugin; -import net.viper.status.module.Module; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -/** - * VerifyModule: Multi-Server Support. - * Liest pro Server die passende ID und das Secret aus der verify.properties. - */ -public class VerifyModule implements Module { - - private String wpVerifyUrl; - // Speichert für jeden Servernamen (z.B. "Lobby") die passende Konfiguration - private final Map serverConfigs = new HashMap<>(); - - @Override - public String getName() { - return "VerifyModule"; - } - - @Override - public void onEnable(Plugin plugin) { - loadConfig(plugin); - - // Befehl registrieren - ProxyServer.getInstance().getPluginManager().registerCommand(plugin, new VerifyCommand()); - - plugin.getLogger().info("VerifyModule aktiviert. " + serverConfigs.size() + " Server-Konfigurationen geladen."); - } - - @Override - public void onDisable(Plugin plugin) { - // Befehl muss nicht manuell entfernt werden, BungeeCord übernimmt das beim Plugin-Stop - } - - // --- Konfiguration Laden & Kopieren --- - private void loadConfig(Plugin plugin) { - String fileName = "verify.properties"; - File configFile = new File(plugin.getDataFolder(), fileName); - Properties props = new Properties(); - - // 1. Datei kopieren, falls sie noch nicht existiert - if (!configFile.exists()) { - plugin.getDataFolder().mkdirs(); - try (InputStream in = plugin.getResourceAsStream(fileName); - OutputStream out = new FileOutputStream(configFile)) { - if (in == null) { - plugin.getLogger().warning("Standard-config '" + fileName + "' nicht in JAR gefunden. Erstelle manuell."); - return; - } - byte[] buffer = new byte[1024]; - int length; - while ((length = in.read(buffer)) > 0) { - out.write(buffer, 0, length); - } - plugin.getLogger().info("Konfigurationsdatei '" + fileName + "' erstellt."); - } catch (Exception e) { - plugin.getLogger().severe("Fehler beim Erstellen der Config: " + e.getMessage()); - return; - } - } - - // 2. Eigentliche Config laden - try (InputStream in = new FileInputStream(configFile)) { - props.load(in); - } catch (IOException e) { - e.printStackTrace(); - return; - } - - // Globale URL - this.wpVerifyUrl = props.getProperty("wp_verify_url", "https://deine-wp-domain.tld"); - - // Server-Configs parsen (z.B. server.Lobby.id) - this.serverConfigs.clear(); - for (String key : props.stringPropertyNames()) { - if (key.startsWith("server.")) { - // Key Struktur: server..id oder .secret - String[] parts = key.split("\\."); - if (parts.length == 3) { - String serverName = parts[1]; - String type = parts[2]; - - // Eintrag in der Map erstellen oder holen - ServerConfig config = serverConfigs.computeIfAbsent(serverName, k -> new ServerConfig()); - - if ("id".equalsIgnoreCase(type)) { - try { - config.serverId = Integer.parseInt(props.getProperty(key)); - } catch (NumberFormatException e) { - plugin.getLogger().warning("Ungültige Server ID für " + serverName); - } - } else if ("secret".equalsIgnoreCase(type)) { - config.sharedSecret = props.getProperty(key); - } - } - } - } - } - - // --- Hilfsklasse für die Daten eines Servers --- - private static class ServerConfig { - int serverId = 0; - String sharedSecret = ""; - } - - // --- Die Command Klasse --- - private class VerifyCommand extends Command { - - public VerifyCommand() { - super("verify"); - } - - @Override - public void execute(CommandSender sender, String[] args) { - if (!(sender instanceof ProxiedPlayer)) { - sender.sendMessage(ChatColor.RED + "Nur Spieler können diesen Befehl benutzen."); - return; - } - - ProxiedPlayer p = (ProxiedPlayer) sender; - if (args.length != 1) { - p.sendMessage(ChatColor.YELLOW + "Benutzung: /verify "); - return; - } - - // --- WICHTIG: Servernamen ermitteln --- - String serverName = p.getServer().getInfo().getName(); - - // Konfiguration für diesen Server laden - ServerConfig config = serverConfigs.get(serverName); - - // Check ob Konfig existiert - if (config == null || config.serverId == 0 || config.sharedSecret.isEmpty()) { - p.sendMessage(ChatColor.RED + "✗ Dieser Server ist nicht in der Verify-Konfiguration hinterlegt."); - p.sendMessage(ChatColor.GRAY + "Aktueller Servername: " + ChatColor.WHITE + serverName); - p.sendMessage(ChatColor.GRAY + "Bitte kontaktiere einen Admin."); - return; - } - - String token = args[0].trim(); - String playerName = p.getName(); - - HttpURLConnection conn = null; - try { - Charset utf8 = Charset.forName("UTF-8"); - // Wir signieren Name + Token mit dem SERVER-SPECIFISCHEN Secret - String signature = hmacSHA256(playerName + token, config.sharedSecret, utf8); - - // Payload aufbauen mit der SERVER-SPECIFISCHEN ID - String payload = "{\"player\":\"" + escapeJson(playerName) + "\",\"token\":\"" + escapeJson(token) + "\",\"server_id\":" + config.serverId + ",\"signature\":\"" + signature + "\"}"; - - URL url = new URL(wpVerifyUrl + "/wp-json/mc-gallery/v1/verify"); - conn = (HttpURLConnection) url.openConnection(); - conn.setConnectTimeout(5000); - conn.setReadTimeout(7000); - conn.setDoOutput(true); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/json; charset=utf-8"); - - try (OutputStream os = conn.getOutputStream()) { - os.write(payload.getBytes(utf8)); - } - - int code = conn.getResponseCode(); - String resp; - - if (code >= 200 && code < 300) { - resp = streamToString(conn.getInputStream(), utf8); - } else { - resp = streamToString(conn.getErrorStream(), utf8); - } - - // Antwort verarbeiten - if (resp != null && !resp.isEmpty() && resp.trim().startsWith("{")) { - boolean isSuccess = resp.contains("\"success\":true"); - String message = "Ein unbekannter Fehler ist aufgetreten."; - - int keyIndex = resp.indexOf("\"message\":\""); - if (keyIndex != -1) { - int startIndex = keyIndex + 11; - int endIndex = resp.indexOf("\"", startIndex); - if (endIndex != -1) { - message = resp.substring(startIndex, endIndex); - } - } - - if (isSuccess) { - p.sendMessage(ChatColor.GREEN + "✓ " + message); - p.sendMessage(ChatColor.GRAY + "Du kannst nun Bilder hochladen!"); - } else { - p.sendMessage(ChatColor.RED + "✗ " + message); - } - } else { - p.sendMessage(ChatColor.RED + "✗ Fehler beim Verbinden mit der Webseite (Code: " + code + ")"); - } - - } catch (Exception ex) { - p.sendMessage(ChatColor.RED + "✗ Ein interner Fehler ist aufgetreten."); - ProxyServer.getInstance().getLogger().warning("Verify error: " + ex.getMessage()); - ex.printStackTrace(); - } finally { - if (conn != null) { - conn.disconnect(); - } - } - } - } - - // --- Helper Methoden --- - private static String hmacSHA256(String data, String key, Charset charset) throws Exception { - Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(new SecretKeySpec(key.getBytes(charset), "HmacSHA256")); - byte[] raw = mac.doFinal(data.getBytes(charset)); - StringBuilder sb = new StringBuilder(); - for (byte b : raw) sb.append(String.format("%02x", b)); - return sb.toString(); - } - - private static String streamToString(InputStream in, Charset charset) throws IOException { - if (in == null) return ""; - try (BufferedReader br = new BufferedReader(new InputStreamReader(in, charset))) { - StringBuilder sb = new StringBuilder(); - String line; - while ((line = br.readLine()) != null) sb.append(line); - return sb.toString(); - } - } - - private static String escapeJson(String s) { - return s.replace("\\", "\\\\").replace("\"","\\\"").replace("\n","\\n").replace("\r","\\r"); - } -} \ No newline at end of file