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