From da8242aba468b3ae845c9b488c9675a8582d9224 Mon Sep 17 00:00:00 2001 From: Git Manager GUI Date: Fri, 22 May 2026 19:27:22 +0200 Subject: [PATCH] Upload folder via GUI - src --- .../statusapibridge/StatusAPIBridge.java | 112 ++++++++++++++++++ StatusAPIBridge/src/main/resources/config.yml | 4 + 2 files changed, 116 insertions(+) diff --git a/StatusAPIBridge/src/main/java/net/viper/statusapibridge/StatusAPIBridge.java b/StatusAPIBridge/src/main/java/net/viper/statusapibridge/StatusAPIBridge.java index afdeb4f..d0eadfa 100644 --- a/StatusAPIBridge/src/main/java/net/viper/statusapibridge/StatusAPIBridge.java +++ b/StatusAPIBridge/src/main/java/net/viper/statusapibridge/StatusAPIBridge.java @@ -47,6 +47,14 @@ public class StatusAPIBridge extends JavaPlugin implements Listener { private final Map lastPapiValues = new ConcurrentHashMap<>(); private boolean papiEnabled = false; + // ── Nametag ─────────────────────────────────────────────────────────────── + /** Scoreboard für Nametag-Teams (einmalig pro Server erstellt) */ + private org.bukkit.scoreboard.Scoreboard nametagBoard = null; + /** Zuletzt gesetzter Prefix pro Spieler (Change-Detection) */ + private final Map lastNametagPrefix = new ConcurrentHashMap<>(); + /** Feature aktivierbar via config: nametag-enabled */ + private boolean nametagEnabled = true; + // ── Versions-Detection ──────────────────────────────────────────────────── // true = 1.21.x-Modus (Spigot/Paper) // false = 26.1.x-Modus (neuere Server-Version, kein NMS-Fallback) @@ -62,6 +70,12 @@ public class StatusAPIBridge extends JavaPlugin implements Listener { public void onEnable() { saveDefaultConfig(); detectMinecraftVersion(); + nametagEnabled = getConfig().getBoolean("nametag-enabled", true); + if (nametagEnabled) { + // Eigenes Scoreboard für Nametag-Teams erstellen + nametagBoard = Bukkit.getScoreboardManager().getNewScoreboard(); + getLogger().info("Nametag-Prefix aktiviert (LuckPerms)."); + } statusApiUrl = getConfig().getString("statusapi-url", "http://127.0.0.1:9191").trim(); pushDelayTicks = getConfig().getInt("push-delay-ticks", 40); liveSyncIntervalTicks = Math.max(20, getConfig().getInt("live-sync-interval-ticks", 20)); @@ -131,6 +145,8 @@ public class StatusAPIBridge extends JavaPlugin implements Listener { if (economy != null) pushEconomy(player); pushPlayerScoreboardData(player); if (papiEnabled && !papiTokens.isEmpty()) pushPapiValues(player); + // Nametag: LuckPerms-Prefix über dem Kopf setzen + if (nametagEnabled) applyNametag(player); }, pushDelayTicks); } @@ -146,6 +162,9 @@ public class StatusAPIBridge extends JavaPlugin implements Listener { lastPushedData.remove(id); lastPushedStats.remove(id); lastPapiValues.remove(id); + lastNametagPrefix.remove(id); + // Nametag-Team beim Quit aufräumen + if (nametagEnabled) removeNametag(player); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @@ -196,6 +215,8 @@ public class StatusAPIBridge extends JavaPlugin implements Listener { pushWorldIfChanged(player); pushPlayerDataIfChanged(player); pushStatsIfChanged(player); + // Nametag periodisch aktualisieren (reagiert auf Rang-Änderungen) + if (nametagEnabled) applyNametag(player); } // ── Push-Methoden ───────────────────────────────────────────────────────── @@ -486,6 +507,97 @@ public class StatusAPIBridge extends JavaPlugin implements Listener { }); } + // ── Nametag-Methoden ────────────────────────────────────────────────────── + + /** + * Setzt den LuckPerms-Prefix als Nametag über dem Spieler-Kopf. + * Nutzt die Bukkit Scoreboard Team API – zuverlässig auf allen Spigot/Paper-Versionen. + * Wird bei Join und periodisch (scoreboard-sync) aufgerufen. + */ + @SuppressWarnings("deprecation") + private void applyNametag(Player player) { + if (!nametagEnabled || nametagBoard == null) return; + String prefix = getLuckPermsPrefix(player); + + // Change-Detection: nicht neu setzen wenn Prefix gleich geblieben + String last = lastNametagPrefix.get(player.getUniqueId()); + if (prefix.equals(last)) return; + lastNametagPrefix.put(player.getUniqueId(), prefix); + + // Team-Name: "vnt_" + erste 12 Zeichen der UUID (ohne Bindestriche) + // Minecraft-Limit: 16 Zeichen für Teamnamen + String teamName = "vnt" + player.getUniqueId().toString().replace("-", "").substring(0, 13); + + try { + // Bestehendes Team holen oder neu erstellen + org.bukkit.scoreboard.Team team = nametagBoard.getTeam(teamName); + if (team == null) { + team = nametagBoard.registerNewTeam(teamName); + } + + // Prefix setzen (Bukkit konvertiert §-Codes automatisch) + String coloredPrefix = org.bukkit.ChatColor.translateAlternateColorCodes('&', prefix) + " "; + team.setPrefix(coloredPrefix); + team.setSuffix(""); + + // Spieler dem Team zuweisen + team.addEntry(player.getName()); + + // Scoreboard dem Spieler zuweisen + player.setScoreboard(nametagBoard); + + // Alle anderen Spieler auf dasselbe Scoreboard setzen damit sie den Prefix sehen + for (Player other : Bukkit.getOnlinePlayers()) { + if (!other.equals(player) && other.getScoreboard() != nametagBoard) { + other.setScoreboard(nametagBoard); + } + } + } catch (Exception e) { + getLogger().warning("[Nametag] Fehler beim Setzen des Prefixes für " + player.getName() + ": " + e.getMessage()); + } + } + + /** + * Entfernt den Spieler aus seinem Nametag-Team beim Disconnect. + */ + private void removeNametag(Player player) { + if (nametagBoard == null) return; + String teamName = "vnt" + player.getUniqueId().toString().replace("-", "").substring(0, 13); + try { + org.bukkit.scoreboard.Team team = nametagBoard.getTeam(teamName); + if (team != null) { + team.removeEntry(player.getName()); + // Team löschen wenn leer + if (team.getEntries().isEmpty()) team.unregister(); + } + } catch (Exception ignored) {} + } + + /** + * Holt den LuckPerms-Prefix eines Spielers via Reflection (keine harte Dependency). + * Gibt leeren String zurück wenn LuckPerms nicht vorhanden oder kein Prefix gesetzt. + */ + private String getLuckPermsPrefix(Player player) { + try { + Class provClass = Class.forName("net.luckperms.api.LuckPermsProvider"); + Object api = provClass.getMethod("get").invoke(null); + Object um = api.getClass().getMethod("getUserManager").invoke(api); + Object usr = um.getClass().getMethod("getUser", UUID.class).invoke(um, player.getUniqueId()); + if (usr == null) return ""; + Class qoClass = Class.forName("net.luckperms.api.query.QueryOptions"); + Object opts = qoClass.getMethod("defaultContextualOptions").invoke(null); + Object cache = usr.getClass().getMethod("getCachedData").invoke(usr); + Object meta = cache.getClass().getMethod("getMetaData", qoClass).invoke(cache, opts); + Object pfx = meta.getClass().getMethod("getPrefix").invoke(meta); + if (pfx != null && !pfx.toString().isEmpty()) return pfx.toString(); + } catch (ClassNotFoundException ignored) { + // LuckPerms nicht installiert + } catch (Exception e) { + getLogger().warning("[Nametag] LuckPerms-Prefix konnte nicht gelesen werden: " + e.getMessage()); + } + return ""; + } + // ── Hilfsmethoden ───────────────────────────────────────────────────────── /** diff --git a/StatusAPIBridge/src/main/resources/config.yml b/StatusAPIBridge/src/main/resources/config.yml index dc7104f..825c675 100644 --- a/StatusAPIBridge/src/main/resources/config.yml +++ b/StatusAPIBridge/src/main/resources/config.yml @@ -10,3 +10,7 @@ live-sync-interval-ticks: 20 # Sync-Intervall fuer Scoreboard-Daten (Health, Compass, TPS, World) in Ticks (mind. 20) # Compass und Health werden zusaetzlich event-basiert aktualisiert. scoreboard-sync-interval-ticks: 20 + +# Nametag: LuckPerms-Prefix ueber dem Spieler-Kopf anzeigen +# Auf false setzen zum Deaktivieren. +nametag-enabled: true