6 Commits
4.0.1 ... 4.0.2

5 changed files with 169 additions and 65 deletions

View File

@@ -1,7 +1,7 @@
# StatusAPI # StatusAPI
![Build Status](https://img.shields.io/badge/build-passing-brightgreen) ![Build Status](https://img.shields.io/badge/build-passing-brightgreen)
![Version](https://img.shields.io/badge/version-4.0.0-blue) ![Version](https://img.shields.io/badge/version-4.0.1-blue)
Ein modulares und mächtiges Plugin für BungeeCord, das einen zentralen JSON-Status, ein globales Chat-System, WordPress-Verifizierung und dynamische Server-Navigation bereitstellt. Ein modulares und mächtiges Plugin für BungeeCord, das einen zentralen JSON-Status, ein globales Chat-System, WordPress-Verifizierung und dynamische Server-Navigation bereitstellt.
@@ -86,6 +86,7 @@ Die meisten Befehle werden dynamisch basierend auf deiner `verify.properties` er
| `/survival` / `/lobby` | Führt dich auf den entsprechenden Server um (wird dynamisch erstellt) | - | | `/survival` / `/lobby` | Führt dich auf den entsprechenden Server um (wird dynamisch erstellt) | - |
| `/globalmute` | Aktiviert oder deaktiviert den globalen Chat | `globalchat.mute` | | `/globalmute` | Aktiviert oder deaktiviert den globalen Chat | `globalchat.mute` |
| `/globalreload` | Lädt Filter und Konfigurationen neu | `globalchat.reload` | | `/globalreload` | Lädt Filter und Konfigurationen neu | `globalchat.reload` |
| `/togglechat` | schaltet für den Spieler den Chat ab | |
| `/support <msg>` | Sendet eine Nachricht an das Online-Team | - | | `/support <msg>` | Sendet eine Nachricht an das Online-Team | - |
| `/reply <msg>` | Antwortet auf eine Support-Anfrage | - | | `/reply <msg>` | Antwortet auf eine Support-Anfrage | - |
| `/info` | Zeigt Plugin-Informationen an | - | | `/info` | Zeigt Plugin-Informationen an | - |

View File

@@ -7,7 +7,7 @@
<groupId>net.viper.bungee</groupId> <groupId>net.viper.bungee</groupId>
<artifactId>StatusAPI</artifactId> <artifactId>StatusAPI</artifactId>
<version>4.0.1</version> <version>4.0.2</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>StatusAPI</name> <name>StatusAPI</name>

View File

@@ -54,6 +54,9 @@ public class GlobalChatModule implements Module, Listener {
private List<String> welcomeMessages = new ArrayList<>(); private List<String> welcomeMessages = new ArrayList<>();
private Map<String, String> serverDisplayNames = new HashMap<>(); private Map<String, String> serverDisplayNames = new HashMap<>();
// NEU: Map für gruppen-spezifische Formate aus der verify.properties
private Map<String, String> groupFormats = new HashMap<>();
@Override @Override
public String getName() { public String getName() {
@@ -145,6 +148,9 @@ public class GlobalChatModule implements Module, Listener {
isChatEnabled = Boolean.parseBoolean(props.getProperty("chat.enabled", "true")); isChatEnabled = Boolean.parseBoolean(props.getProperty("chat.enabled", "true"));
serverDisplayNames.clear(); serverDisplayNames.clear();
// NEU: Gruppen-Formate laden
groupFormats.clear();
for (String key : props.stringPropertyNames()) { for (String key : props.stringPropertyNames()) {
if (key.startsWith("server.")) { if (key.startsWith("server.")) {
String[] parts = key.split("\\."); String[] parts = key.split("\\.");
@@ -153,9 +159,15 @@ public class GlobalChatModule implements Module, Listener {
String displayName = props.getProperty(key); String displayName = props.getProperty(key);
serverDisplayNames.put(serverName, displayName); serverDisplayNames.put(serverName, displayName);
} }
} else if (key.startsWith("groupformat.")) {
// Format: groupformat.Owner = &c[Owner] || &b || &d
String groupName = key.substring("groupformat.".length());
String format = props.getProperty(key);
groupFormats.put(groupName, format);
} }
} }
plugin.getLogger().info("§eGeladene Server-Displaynames: " + serverDisplayNames.size() + " (Chat aktiv: " + isChatEnabled + ")"); plugin.getLogger().info("§eGeladene Server-Displaynames: " + serverDisplayNames.size() + " (Chat aktiv: " + isChatEnabled + ")");
plugin.getLogger().info("§eGeladene Chat-Formate: " + groupFormats.size());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -262,24 +274,29 @@ public class GlobalChatModule implements Module, Listener {
String serverName = player.getServer().getInfo().getName(); String serverName = player.getServer().getInfo().getName();
String serverDisplay = getDisplayName(serverName); String serverDisplay = getDisplayName(serverName);
// Index 0: Prefix (Rang), Index 1: Suffix, Index 2: Spielername Farbe, Index 3: Chat Farbe
String[] ps = getPrefixSuffix(player); String[] ps = getPrefixSuffix(player);
String prefix = ps[0] == null ? "" : ps[0].trim(); String prefix = ps[0];
String suffix = ps[1] == null ? "" : ps[1].trim(); String playerColor = ps[2];
String chatColor = ps[3];
String displayTag = ""; String displayTag = "";
if (!prefix.isEmpty()) { if (!prefix.isEmpty()) {
displayTag = prefix; displayTag = prefix;
} else if (!suffix.isEmpty()) { } else if (!ps[1].isEmpty()) {
displayTag = suffix; displayTag = ps[1];
} }
if (!displayTag.isEmpty() && !displayTag.endsWith(" ")) displayTag = displayTag + " "; if (!displayTag.isEmpty() && !displayTag.endsWith(" ")) displayTag = displayTag + " ";
StringBuilder out = new StringBuilder(); StringBuilder out = new StringBuilder();
out.append("§7[").append(serverDisplay).append("] "); out.append("§7[").append(serverDisplay).append("§r§7] "); // FIX: Reset vor der Klammer
if (!displayTag.isEmpty()) out.append(displayTag); if (!displayTag.isEmpty()) out.append(displayTag);
out.append(player.getName());
out.append("§f: ").append(censoredMsg); // Spielername mit eigener Farbe
out.append(playerColor).append(player.getName());
out.append("§f: ").append(chatColor).append(censoredMsg); // Chatnachricht mit eigener Farbe
String chatOut = out.toString(); String chatOut = out.toString();
@@ -357,9 +374,10 @@ public class GlobalChatModule implements Module, Listener {
String toName = to.getName(); String toName = to.getName();
String toDisplay = getDisplayName(toName); String toDisplay = getDisplayName(toName);
// Hier nutzen wir nur das Prefix (Index 0), nicht die Chatfarbe oder Spielerfarbe
String[] ps = getPrefixSuffix(player); String[] ps = getPrefixSuffix(player);
String prefix = ps[0] == null ? "" : ps[0].trim(); String prefix = ps[0];
String suffix = ps[1] == null ? "" : ps[1].trim(); String suffix = ps[1];
String displayTag = ""; String displayTag = "";
if (!prefix.isEmpty()) displayTag = prefix; if (!prefix.isEmpty()) displayTag = prefix;
@@ -368,9 +386,12 @@ public class GlobalChatModule implements Module, Listener {
if (!displayTag.isEmpty() && !displayTag.endsWith(" ")) displayTag = displayTag + " "; if (!displayTag.isEmpty() && !displayTag.endsWith(" ")) displayTag = displayTag + " ";
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
msg.append("§7[").append(toDisplay).append("] "); msg.append("§7[").append(toDisplay).append("§r§7] "); // FIX: Reset vor der Klammer
if (!displayTag.isEmpty()) msg.append(displayTag); if (!displayTag.isEmpty()) msg.append(displayTag);
// Switch Nachricht: Spielername weiß oder Standard
msg.append(player.getName()); msg.append(player.getName());
msg.append(" §7hat den Server gewechselt: §e") msg.append(" §7hat den Server gewechselt: §e")
.append(fromDisplay).append(" §7→ §e").append(toDisplay).append("§7."); .append(fromDisplay).append(" §7→ §e").append(toDisplay).append("§7.");
@@ -414,45 +435,112 @@ public class GlobalChatModule implements Module, Listener {
} }
// =========================== // ===========================
// Prefix/Suffix via LuckPerms // Prefix/Suffix via LuckPerms & Properties (ROBUST + CHAT COLOR + PLAYER COLOR)
// =========================== // ===========================
private String[] getPrefixSuffix(ProxiedPlayer player) { private String[] getPrefixSuffix(ProxiedPlayer player) {
String prefix = ""; String prefix = "";
String suffix = ""; String suffix = "";
String playerColor = "§f"; // Standard Weiß für Spielername
String chatColor = "§f"; // Standard Weiß für Chat
// Standard Gruppe falls nichts gefunden wird
String groupName = "Spieler";
// 1. Versuch: Gruppe von LuckPerms holen
try { try {
LuckPerms lp = LuckPermsProvider.get(); LuckPerms lp = LuckPermsProvider.get();
if (lp != null) { if (lp != null) {
User user = lp.getUserManager().getUser(player.getUniqueId()); User user = lp.getUserManager().getUser(player.getUniqueId());
if (user == null) { if (user == null) {
try { try {
// User synchron laden
user = lp.getUserManager().loadUser(player.getUniqueId()).join(); user = lp.getUserManager().loadUser(player.getUniqueId()).join();
} catch (Exception ignored) { } catch (Exception ignored) {}
user = null; }
if (user != null) {
String lpGroup = user.getPrimaryGroup();
if (lpGroup != null && !lpGroup.isEmpty() && !lpGroup.equalsIgnoreCase("default")) {
groupName = lpGroup;
} }
} }
}
} catch (Throwable ignored) {}
// 2. FALLBACK: Permission-Check (Funktioniert auch OHNE LuckPerms Datenbank)
if (groupName == null || groupName.equalsIgnoreCase("default") || groupName.equalsIgnoreCase("Spieler")) {
if (player.hasPermission("group.owner")) groupName = "Owner";
else if (player.hasPermission("group.admin")) groupName = "Admin";
else if (player.hasPermission("group.developer")) groupName = "Developer";
else if (player.hasPermission("group.premium")) groupName = "Premium";
else if (player.hasPermission("group.spieler")) groupName = "Spieler";
else groupName = "Spieler";
}
// 3. Farben aus verify.properties anwenden (Höchste Priorität)
if (groupName != null && groupFormats.containsKey(groupName)) {
String rawFormat = groupFormats.get(groupName);
// NEU: Check auf " || " für Spielername Farbe UND Chat Farbe
if (rawFormat.contains(" || ")) {
String[] parts = rawFormat.split(" \\|\\| ");
// Syntax: Prefix || PlayerColor || ChatColor
// Teil 1: Prefix (Rang)
prefix = ChatColor.translateAlternateColorCodes('&', parts[0]);
// Teil 2: Spieler Name Farbe
playerColor = ChatColor.translateAlternateColorCodes('&', parts[1]);
// Teil 3: Chat Farbe
chatColor = ChatColor.translateAlternateColorCodes('&', parts[2]);
suffix = "";
}
// ALTER FALLBACK (Kompatibilität): Check auf ": "
else if (rawFormat.contains(": ")) {
String[] parts = rawFormat.split(": ", 2);
// Teil 1: Prefix
prefix = ChatColor.translateAlternateColorCodes('&', parts[0]);
// Teil 2: Chat Farbe
chatColor = ChatColor.translateAlternateColorCodes('&', parts[1]);
// Spielername bleibt Standard Weiß
playerColor = "§f";
suffix = "";
} else {
// Kein Separator gefunden -> Nur Prefix
prefix = ChatColor.translateAlternateColorCodes('&', rawFormat);
suffix = "";
playerColor = "§f";
chatColor = "§f";
}
return new String[]{prefix, suffix, playerColor, chatColor};
}
// 4. Wenn nichts in Properties gefunden wurde, Fallback auf LuckPerms Meta
try {
LuckPerms lp = LuckPermsProvider.get();
if (lp != null) {
User user = lp.getUserManager().getUser(player.getUniqueId());
if (user == null) {
try { user = lp.getUserManager().loadUser(player.getUniqueId()).join(); } catch (Exception ignored) {}
}
if (user != null) { if (user != null) {
CachedMetaData meta = user.getCachedData().getMetaData(); CachedMetaData meta = user.getCachedData().getMetaData();
if (meta != null) { if (meta != null) {
String p = meta.getPrefix(); String p = meta.getPrefix();
String s = meta.getSuffix(); String s = meta.getSuffix();
if (p != null) prefix = p; if (p != null) prefix = ChatColor.translateAlternateColorCodes('&', p);
if (s != null) suffix = s; if (s != null) suffix = ChatColor.translateAlternateColorCodes('&', s);
} }
} }
} }
} catch (Throwable ignored) { } catch (Throwable ignored) {}
}
if (prefix != null && !prefix.isEmpty()) prefix = ChatColor.translateAlternateColorCodes('&', prefix);
if (suffix != null && !suffix.isEmpty()) suffix = ChatColor.translateAlternateColorCodes('&', suffix);
if (prefix == null) prefix = ""; if (prefix == null) prefix = "";
if (suffix == null) suffix = ""; if (suffix == null) suffix = "";
return new String[]{prefix, suffix}; return new String[]{prefix, suffix, playerColor, chatColor};
} }
private String stripColor(String s) { private String stripColor(String s) {

View File

@@ -1,6 +1,6 @@
name: StatusAPI name: StatusAPI
main: net.viper.status.StatusAPI main: net.viper.status.StatusAPI
version: 4.0.1 version: 4.0.2
author: M_Viper author: M_Viper
description: StatusAPI für BungeeCord inkl. Update-Checker und Modul-System description: StatusAPI für BungeeCord inkl. Update-Checker und Modul-System

View File

@@ -1,39 +1,54 @@
# =========================== # ===========================
# GLOBALCHAT AKTIVIERUNG # GLOBALCHAT AKTIVIERUNG
# =========================== # ===========================
chat.enabled=false chat.enabled=false
# =========================== # ===========================
# NAVIGATION / SERVER SWITCHER # NAVIGATION / SERVER SWITCHER
# =========================== # ===========================
# Hier kannst du das interne Navigationssystem aktivieren/deaktivieren. # Hier kannst du das interne Navigationssystem aktivieren/deaktivieren.
# Wenn aktiviert, erstellt das Plugin automatisch Befehle basierend auf den Servernamen (z.B. /lobby, /survival). # Wenn aktiviert, erstellt das Plugin automatisch Befehle basierend auf den Servernamen (z.B. /lobby, /survival).
navigation.enabled=false navigation.enabled=false
# =========================== # ===========================
# WORDPRESS / VERIFY EINSTELLUNGEN # WORDPRESS / VERIFY EINSTELLUNGEN
# =========================== # ===========================
wp_verify_url=https://deine-wp-domain.tld wp_verify_url=https://deine-wp-domain.tld
# =========================== # ===========================
# SERVER KONFIGURATION # SERVER KONFIGURATION
# =========================== # ===========================
# Hier legst du für jeden Server alles fest: # Hier legst du für jeden Server alles fest:
# 1. Den Anzeigenamen für den Chat (z.B. &bLobby) # 1. Den Anzeigenamen für den Chat (z.B. &bLobby)
# 2. Die Server ID für WordPress (z.B. id=1) # 2. Die Server ID für WordPress (z.B. id=1)
# 3. Das Secret für WordPress (z.B. secret=...) # 3. Das Secret für WordPress (z.B. secret=...)
# Server 1: Lobby # Server 1: Lobby
server.lobby=&bLobby server.lobby=&bLobby
server.lobby.id=1 server.lobby.id=1
server.lobby.secret=GeheimesWortFuerLobby123 server.lobby.secret=GeheimesWortFuerLobby123
# Server 2: Survival # Server 2: Survival
server.survival=&aSurvival server.survival=&aSurvival
server.survival.id=2 server.survival.id=2
server.survival.secret=GeheimesWortFuerSurvival456 server.survival.secret=GeheimesWortFuerSurvival456
# Server 3: SkyBlock # Server 3: SkyBlock
server.skyblock=&dSkyBlock server.skyblock=&dSkyBlock
server.skyblock.id=3 server.skyblock.id=3
server.skyblock.secret=GeheimesWortFuerSkyBlock789 server.skyblock.secret=GeheimesWortFuerSkyBlock789
# ===========================
# Chat-Formate für Gruppen
# ===========================
# Der Name hinter dem Punkt (z.B. Owner) muss exakt mit der LuckPerms Gruppe übereinstimmen.
# Nutze & für Farbcodes.
# Ränge mit neuer Syntax: Rank || Spielerfarbe || Chatfarbe
# Beispiel: Rot (Rang) || Blau (Name) || Lila (Chat)
groupformat.Owner=&c[Owner] || &b || &d
groupformat.Admin=&4[Admin] || &9 || &c
groupformat.Developer=&b[Dev] || &3 || &a
groupformat.Premium=&6[Premium] || &e || &7
groupformat.Spieler=&f[Spieler] || &7 || &8