Upload via GUI (84 Dateien)

This commit is contained in:
2026-10-11 17:15:33 +00:00
parent 1a75a7db33
commit 3a8fe5cf66
28 changed files with 4113 additions and 3713 deletions
+400
View File
@@ -0,0 +1,400 @@
## 🌐 Mehrsprachigkeit & Texte
Alle Nachrichten, Hilfetexte und Fehler werden zentral über die Datei `lang.yml` im Ordner `src/main/resources` verwaltet. Dort kannst du für jede Sprache (z.B. Deutsch und Englisch) die Texte pflegen und beliebig erweitern.
**Beispiel für lang.yml:**
```yaml
welcome:
de: "Willkommen auf dem Server!"
en: "Welcome to the server!"
no_permission:
de: "§cKeine Berechtigung."
en: "§cNo permission."
```
**Sprache umstellen:**
Im Code kann die Sprache mit `LangManager.setLanguage("en")` gewechselt werden. Standard ist Deutsch (`de`).
**Texte ingame nutzen:**
Alle Texte werden im Plugin mit `LangManager.get("key")` abgerufen und sind direkt ingame sichtbar. Änderungen in der lang.yml wirken nach einem Reload sofort.
**Chat-Prefix anpassen:**
Der Prefix vor Plugin-Nachrichten wird in der Server-`config.yml` über `prefix` festgelegt. Farben können mit `&`-Codes angegeben werden:
```yaml
prefix: "&8[&6Nexus&8] "
```
Ändere den Text und die Farben nach Wunsch und lade das Plugin anschließend neu.
---
# NexusLobby
<p align="center">
<img src="https://m-viper.de/img/NexusLobby.png" width="500" alt="NexusLobby">
</p>
Ein umfassendes, modulares Lobby-Plugin für Minecraft Server (Paper/Spigot 1.21+) mit High-End NPC-System, umfangreichen Sicherheitsfunktionen, Soccer-Modul, Parkour-System und voller Konfigurierbarkeit.
![Minecraft](https://img.shields.io/badge/Minecraft-1.21+-green)
![Java](https://img.shields.io/badge/Java-21+-orange)
![License](https://img.shields.io/badge/License-Proprietary-red)
![Version](https://img.shields.io/badge/Version-1.1.0-blue)
---
## 🎯 Lizenz und Nutzungsbedingungen
**ALLE RECHTE VORBEHALTEN**
Dieses Plugin ist urheberrechtlich geschützt. Es gelten folgende Bedingungen:
# Scoreboard ausblenden (Opt-out)
Spieler können das Scoreboard per Befehl ein-/ausblenden. Standardmäßig wird das Scoreboard beim Join angezeigt. Über die Option
```yaml
scoreboard-default-visible: true
```
in der `config.yml` kann festgelegt werden, ob das Scoreboard für neue Spieler standardmäßig sichtbar ist. Bei `false` ist es für alle Spieler nach dem Join ausgeblendet, bis sie es selbst aktivieren.
- Die Weitergabe, Verbreitung oder Veröffentlichung des Plugins ist **strengstens untersagt**.
- Jegliche Änderung, Modifikation oder Dekompilierung des Codes ist **verboten**.
- Das Plugin darf nicht verkauft, vermietet oder anderweitig kommerziell genutzt werden.
- Eine Weitergabe an Dritte ist ohne ausdrückliche schriftliche Genehmigung nicht gestattet.
Bei Verstoß gegen diese Bedingungen behalten wir uns rechtliche Schritte vor.
---
## ✨ Features
### 🤖 High-End NPC & ArmorStand System
- **Conversation Manager** - Komplexe Dialoge zwischen NPCs mit Sprechblasen und Sound-Effekten
- **Dynamic KI** - NPCs reagieren auf Tageszeit (Fackel nachts) und ziehen bei Annäherung von Spielern das Schwert
- **LookAt-Logik** - NPCs verfolgen flüssig die Kopfbewegungen von Spielern in der Nähe
- **Command Binding** - Binde Spieler-, Konsolen- oder Bungee-Befehle an NPC-Slots (0-9)
- **Status-Backup** - Automatisches Speichern von NPC-Namen via PersistentDataContainer & Tags
### ⚽ Soccer/Fußball-System
- **Interaktiver Soccer-Ball** - Physics-basierter Ball mit realistischer Physik
- **Dribbling** - Ball folgt Spielern automatisch in der Nähe
- **Kick-Mechanik** - Schieße den Ball durch Schlagen oder Angriff
- **Wall-Bounce** - Realistische Wand-Abpraller mit Sound-Effekten
- **Partikel-System** - Geschwindigkeits-abhängige Partikel (SONIC_BOOM, CRIT, SMOKE)
- **Auto-Respawn** - Automatischer Respawn bei Inaktivität oder Void-Fall
- **Anti-Duplikat-System** - Verhindert mehrfache Ball-Instanzen
### 🏃 Parkour-System
- **Unsichtbare Checkpoints** - Partikel-basierte Checkpoint-Markierungen
- **Timer-System** - Präzise Zeitmessung mit ActionBar-Anzeige
- **Bestenliste** - Persistente Top-10 Bestzeiten-Speicherung
- **NPC-Trainer** - Interaktive NPCs zum Starten des Parkours
- **Fail-Safe** - Teleport zum letzten Checkpoint bei Fehler
### 🌍 Lobby-Management
- **Spawn-System** - Automatischer Teleport zum Spawn bei Join/Respawn
- **Portal-System** - BungeeCord-Portale für nahtlose Server-Wechsel mit Partikel-Effekten
- **Build-Modus** - Schnelles Umschalten zwischen Bau- und Spielmodus
- **Double-Jump** - Konfigurierbarer Doppelsprung mit Cooldown und Partikeln
- **Worldborder** - Unsichtbare Lobby-Begrenzung (Circle/Square)
- **Intro-Tour** - Cinematic Kamera-Tour für neue Spieler
### 🛡️ Sicherheit & Protection
- **VPN-Blocker** - Blockiert VPN/Proxy-Verbindungen via proxycheck.io API
- **Country-Blocker** - Geo-IP Filter (Whitelist/Blacklist für Länder)
- **Maintenance-Modus** - Vollständiger Wartungsmodus mit Whitelist-Funktion
- **World-Protection** - Schutz vor Griefing, Hunger, Fallschaden und PvP
- **Anti-Grief** - Verhindert Block-Break, Item-Drop und Explosionen
- **Security-Module** - Umfassende Sicherheitsprüfungen beim Join
### 📊 Visuelle Elemente
- **Scoreboard** - Vollständig animiert mit PlaceholderAPI-Support
- **Tablist** - Dynamische Header/Footer mit Permissions-Anzeige
- **BossBar** - Rotierende Nachrichten mit Farb-Effekten
- **ActionBar** - Typewriter-Effekt für permanente Status-Anzeigen
- **Hologramme** - Text-Displays mit flexibler Positionierung
- **MapArt** - Bild-Generator für Item-Frames aus URLs
### 🎮 Item-System
- **Compass** - Server-Switcher GUI
- **Player-Hider** - Sichtbarkeits-Toggle für andere Spieler
- **Gadgets** - Konfigurierbares Item-System mit Custom-Slots
- **Player-Inspector** - Detaillierte Spieler-Informationen per Click
---
## 📋 Befehle
### Haupt-Commands
| Befehl | Beschreibung | Berechtigung |
|--------|--------------|--------------|
| `/nexuslobby reload` | Lädt das Plugin neu | `nexuslobby.admin` |
| `/nexuslobby setspawn` | Setzt den Lobby-Spawn | `nexuslobby.admin` |
| `/nexuslobby silentjoin <on\|off>` | Versteckter Join/Quit | `nexuslobby.admin` |
| `/nexuslobby sb <on\|off\|admin\|spieler>` | Scoreboard-Kontrolle | `nexuslobby.admin` |
| `/spawn` | Teleport zum Spawn | `nexuslobby.spawn` |
### NPC & ArmorStand
| Befehl | Beschreibung | Berechtigung |
|--------|--------------|--------------|
| `/nexustools` | NPC Editor GUI (Rotation, KI) | `nexuslobby.armorstand.use` |
| `/nexuscmd add <slot> <prio> <type> [cmd]` | Bindet Command an NPC | `nexuslobby.armorstand.cmd` |
| `/nexuscmd remove <slot\|all>` | Entfernt Commands | `nexuslobby.armorstand.cmd` |
| `/nexuscmd conv select1-4` | Wählt NPCs für Dialog | `nexuslobby.armorstand.cmd` |
| `/nexuscmd conv link <id>` | Verknüpft Dialog | `nexuslobby.armorstand.cmd` |
| `/nexuscmd say <text>` | NPC-Sprechblase | `nexuslobby.armorstand.cmd` |
### Parkour
| Befehl | Beschreibung | Berechtigung |
|--------|--------------|--------------|
| `/nexuslobby parkour setstart` | Markiert Start-NPC | `nexuslobby.admin` |
| `/nexuslobby parkour setcheckpoint <n>` | Setzt Checkpoint | `nexuslobby.admin` |
| `/nexuslobby parkour setfinish` | Setzt Ziel | `nexuslobby.admin` |
| `/nexuslobby parkour reset` | Löscht eigene Zeit | `nexuslobby.admin` |
| `/nexuslobby parkour clear` | Löscht alle Zeiten | `nexuslobby.admin` |
| `/setstart` | Alias für setstart | `nexuslobby.admin` |
| `/setcheckpoint` | Alias für setcheckpoint | `nexuslobby.admin` |
| `/setfinish` | Alias für setfinish | `nexuslobby.admin` |
### Soccer/Fußball
| Befehl | Beschreibung | Berechtigung |
|--------|--------------|--------------|
| `/nexuslobby ball setspawn` | Setzt Ball-Spawn | `nexuslobby.admin` |
| `/nexuslobby ball respawn` | Spawnt Ball neu | `nexuslobby.admin` |
| `/nexuslobby ball remove` | Entfernt Ball | `nexuslobby.admin` |
### Portal & Server
| Befehl | Beschreibung | Berechtigung |
|--------|--------------|--------------|
| `/portal create <name> <type>` | Erstellt Portal | `nexuslobby.portal` |
| `/portal delete <name>` | Löscht Portal | `nexuslobby.portal` |
| `/portal list` | Zeigt alle Portale | `nexuslobby.portal` |
| `/giveportalwand` | Portal-Werkzeug | `nexuslobby.portal.give` |
| `/serverswitcher` | Öffnet Server-GUI | `nexuslobby.serverswitcher` |
### Sonstiges
| Befehl | Beschreibung | Berechtigung |
|--------|--------------|--------------|
| `/build` | Build-Modus toggle | `nexuslobby.build` |
| `/maintenance <on\|off>` | Wartungsmodus | `nexuslobby.maintenance` |
| `/settings` | Lobby-Einstellungen (Gamerules) | `nexuslobby.admin` |
| `/holo create <id> [text]` | Erstellt Hologramm | `nexuslobby.hologram` |
| `/holo delete <id>` | Löscht Hologramm | `nexuslobby.hologram` |
| `/mapart <URL> <BxH>` | Erstellt MapArt | `nexuslobby.mapart` |
| `/intro <add\|clear\|start>` | Intro-Tour-Verwaltung | `nexuslobby.admin` |
| `/border <circle\|square\|disable>` | Worldborder-Setup | `nexuslobby.admin` |
---
## ⚙️ Konfiguration
### config.yml (Auszug)
```yaml
# Spawn-Einstellungen
spawn:
world: "world"
x: 0.5
y: 64.0
z: 0.5
yaw: 0.0
pitch: 0.0
# Lobby-Einstellungen
lobby:
allow-fly: false
pvp-enabled: false
build-enabled: false
default-gamemode: Adventure
clear-inventory-on-join: true
# Server-Mapping (für Status-Check)
servers:
survival:
ip: "127.0.0.1"
port: 25566
skyblock:
ip: "127.0.0.1"
port: 25567
# Ball/Soccer-Einstellungen
ball:
respawn_delay: 60 # Sekunden bis Auto-Respawn
# Worldborder
worldborder:
enabled: true
type: "SQUARE" # SQUARE oder CIRCLE
radius: 50.0
```
### conversations.yml
```yaml
conversations:
willkommen:
dialogue:
- "&eWächter: &7Willkommen auf dem Server!"
- "&aBürger: &7Schön, dass du da bist!"
- "&eWächter: &7Viel Spaß beim Erkunden!"
quest_dialog:
dialogue:
- "&6Quest-Geber: &7Hast du meine Quest erledigt?"
- "&aHeld: &7Ja, ich habe alle Monster besiegt!"
links:
# UUID des ersten NPCs
"550e8400-e29b-41d4-a716-446655440000":
partner: "550e8400-e29b-41d4-a716-446655440001" # UUID des zweiten NPCs
dialog: willkommen
automated: true # Startet automatisch
```
### visuals.yml (Auszug)
```yaml
# ActionBar-Nachrichten
actionbar:
enabled: true
speed: 3
messages:
- "&6&lWillkommen &8» &eauf unserem Server!"
- "&b&lViel Spaß &8» &7in der Lobby!"
# BossBar
bossbar:
enabled: true
interval: 40
messages:
- text: "&6&lNexusLobby &8» &eVersion 1.1.0"
color: "YELLOW"
```
---
## 🔐 Berechtigungen
### Admin-Berechtigungen
| Berechtigung | Beschreibung |
|--------------|--------------|
| `nexuslobby.admin` | Voller Zugriff auf alle System-Einstellungen |
| `nexuslobby.armorstand.cmd` | NPCs konfigurieren und Dialoge verknüpfen |
| `nexuslobby.armorstand.use` | Zugriff auf die ArmorStand-Editor GUI |
| `nexuslobby.build` | Berechtigung für den Baumodus |
| `nexuslobby.portal` | Portale erstellen und löschen |
| `nexuslobby.portal.give` | Portal-Werkzeug erhalten |
| `nexuslobby.hologram` | Hologramme verwalten |
| `nexuslobby.mapart` | MapArt erstellen |
| `nexuslobby.maintenance` | Wartungsmodus togglen |
### Spieler-Berechtigungen
| Berechtigung | Beschreibung |
|--------------|--------------|
| `nexuslobby.spawn` | Spawn-Command nutzen |
| `nexuslobby.serverswitcher` | Server-Switcher GUI öffnen |
| `nexuslobby.scoreboard.admin` | Admin-Scoreboard sehen |
### Bypass-Berechtigungen
| Berechtigung | Beschreibung |
|--------------|--------------|
| `nexuslobby.bypass.maintenance` | Server trotz Wartungsmodus betreten |
| `nexuslobby.bypass.vpn` | VPN-Check überspringen |
| `nexuslobby.bypass.country` | Country-Check überspringen |
---
## 🔧 Technische Details
### Systemanforderungen
- **Minecraft**: Paper/Spigot 1.21+ (Spigot-kompatibel, Paper empfohlen)
- **Java**: Java 21 oder höher
- **Dependencies**: LuckPerms, PlaceholderAPI (optional)
### Verwendete Technologien
- **Build-Tool**: Maven 3.9+
- **JSON-Library**: Gson 2.10.1 (gegenüber json-simple 1.1.1 aktualisiert)
- **BungeeCord API**: Für Server-Wechsel und Messaging
- **PlaceholderAPI**: Für dynamische Platzhalter
### Code-Qualität
- ✅ Moderne Java 21 Features (Switch-Expressions, Pattern Matching)
- ✅ Proper Error-Handling (Logger statt printStackTrace)
- ✅ Memory-Management (Tasks & Listeners werden sauber disposed)
- ✅ Config-Validierung mit Default-Werten
- ✅ Optimiertes JSON-Parsing mit Gson
- ✅ Spigot-kompatible BungeeCord Chat API
### Performance-Optimierungen
- **Async-Processing** für API-Calls (Update-Check, VPN-Check)
- **Caching** für Spieler-Daten und Config-Werte
- **Optimierte Entity-Queries** (nur relevante Welten)
- **Effiziente Scheduler-Nutzung** (Tasks werden gecancelt)
---
## 📦 Installation
1. **Download** der neuesten `NexusLobby-1.1.0.jar` aus den [Releases](../../releases)
2. **Upload** der JAR-Datei in den `/plugins/` Ordner
3. **Server-Neustart** durchführen
4. **Konfiguration** anpassen (`config.yml`, `visuals.yml`, etc.)
5. **Permissions** mit LuckPerms oder einem anderen Permissions-Plugin setzen
6. **(Optional)** PlaceholderAPI installieren für erweiterte Platzhalter
---
## 🐛 Bekannte Issues & Lösungen
### Ball spawnt mehrfach
- **Lösung**: Nutze `/nexuslobby ball remove` gefolgt von `/nexuslobby ball setspawn`
- Das Anti-Duplikat-System sollte dies automatisch verhindern
### NPCs schauen nicht zu Spielern
- **Lösung**: Stelle sicher, dass der NPC mit `/nexustools` das LookAt-Feature aktiviert hat
- Prüfe, ob `ArmorStandLookAtModule` in den Logs geladen wird
### Server-Checker zeigt falsche Status
- **Lösung**: Überprüfe die IP/Port-Einstellungen in `config.yml` unter `servers:`
- Stelle sicher, dass die Server erreichbar sind (Firewall, Ports)
---
## 📚 Support & Dokumentation
- **Wiki**: Ausführliche Dokumentation im [Wiki](../../wiki)
- **Bug-Reports**: Erstelle ein [Issue](../../issues) bei technischen Problemen
- **Feature-Requests**: Vorschläge über [Issues](../../issues) mit Label "enhancement"
---
## 📝 Changelog
### Version 1.1.0 (Februar 2026)
- ✨ Soccer/Fußball-System mit realistischer Physik
- ✨ Parkour-System mit Bestenliste und Checkpoints
- ✨ Player-Inspector Modul
- ✨ Config-Validierung mit Auto-Defaults
- 🔧 JSON-Library auf Gson 2.10.1 aktualisiert
- 🔧 Alle printStackTrace() durch Logger ersetzt
- 🔧 Memory-Management verbessert (Tasks & Listeners)
- 🔧 UpdateChecker mit proper JSON-Parsing
- 🐛 Diverse Bug-Fixes und Performance-Optimierungen
---
**Copyright © 2026 - M_Viper - Alle Rechte vorbehalten**
Die unbefugte Vervielfältigung, Verbreitung oder Weitergabe dieses Plugins ist strafbar und wird rechtlich verfolgt.
@@ -238,18 +238,18 @@ public class NexusLobbyCommand implements CommandExecutor {
*/
private int parseTrack(String[] args, int index, Player player) {
if (args.length <= index) {
player.sendMessage("§8[§6Nexus§8] §cBitte gib eine Strecken-Nummer an: §e1 §7oder §e2");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cBitte gib eine Strecken-Nummer an: §e1 §7oder §e2");
return -1;
}
int track;
try {
track = Integer.parseInt(args[index]);
} catch (NumberFormatException e) {
player.sendMessage("§8[§6Nexus§8] §cUngültige Strecken-Nummer. Bitte §e1 §7oder §e2 §7verwenden.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cUngültige Strecken-Nummer. Bitte §e1 §7oder §e2 §7verwenden.");
return -1;
}
if (track < 1 || track > 2) {
player.sendMessage("§8[§6Nexus§8] §cNur Strecke §e1 §7oder §e2 §7sind erlaubt.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cNur Strecke §e1 §7oder §e2 §7sind erlaubt.");
return -1;
}
return track;
@@ -285,11 +285,11 @@ public class NexusLobbyCommand implements CommandExecutor {
de.nexuslobby.modules.armorstandtools.ConversationManager cm =
NexusLobby.getInstance().getConversationManager();
if (cm == null) {
player.sendMessage("§8[§6Nexus§8] §cConversationManager ist nicht aktiv.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cConversationManager ist nicht aktiv.");
return;
}
cm.clearHangingBubbles();
player.sendMessage("§8[§6Nexus§8] §aAlle hängengebliebenen Sprechblasen wurden entfernt.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aAlle hängengebliebenen Sprechblasen wurden entfernt.");
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 2f);
}
@@ -148,7 +148,7 @@ public class ASTListener implements Listener {
out.writeUTF("Connect");
out.writeUTF(server);
player.sendPluginMessage(NexusLobby.getInstance(), "BungeeCord", out.toByteArray());
player.sendMessage("§8[§6Nexus§8] §7Du wirst mit §e" + server + " §7verbunden...");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§7Du wirst mit §e" + server + " §7verbunden...");
}
@EventHandler(priority = EventPriority.LOW)
@@ -39,8 +39,8 @@ public class AnvilRenameGUI implements Listener {
"§7Schreibe den neuen Namen in den §eChat§7. §8(&-Codes erlaubt)",
10, 80, 20
);
player.sendMessage("§8[§6Nexus§8] §7Gib den neuen §eNamen §7in den Chat ein. §8(&-Farb-Codes erlaubt)");
player.sendMessage("§8[§6Nexus§8] §c'abbrechen' §7eingeben zum Abbrechen.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§7Gib den neuen §eNamen §7in den Chat ein. §8(&-Farb-Codes erlaubt)");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§c'abbrechen' §7eingeben zum Abbrechen.");
}
// ─────────────────────────────────────────────────────────────────────────
@@ -64,7 +64,7 @@ public class AnvilRenameGUI implements Listener {
if (input.equalsIgnoreCase("abbrechen")) {
player.sendTitle("§c§lAbgebrochen", "", 5, 30, 10);
player.sendMessage("§8[§6Nexus§8] §cNamensänderung abgebrochen.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cNamensänderung abgebrochen.");
} else {
// & → § Farb-Codes
String newName = ChatColor.translateAlternateColorCodes('&', input);
@@ -72,7 +72,7 @@ public class AnvilRenameGUI implements Listener {
armorStand.setCustomNameVisible(!ChatColor.stripColor(newName).isEmpty());
player.sendTitle("§a§lName gesetzt!", "§r" + newName, 5, 40, 10);
player.sendMessage("§8[§6Nexus§8] §aName gesetzt: " + newName);
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aName gesetzt: " + newName);
}
// Zurück zum ArmorStand-Editor
@@ -27,14 +27,14 @@ import java.util.UUID;
*/
public class ArmorStandCmdExecutor implements CommandExecutor {
private final String prefix = "§8[§6Nexus§8] ";
private String prefix() { return de.nexuslobby.utils.LangManager.getPrefix(); }
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player p)) return true;
if (!p.hasPermission("nexuslobby.armorstand.cmd")) {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("no_permission"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("no_permission"));
return true;
}
@@ -53,7 +53,7 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
case "select4":
ArmorStand target = getTargetArmorStand(p);
if (target == null) {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required"));
return true;
}
@@ -63,17 +63,17 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
UUID targetUUID = target.getUniqueId();
p.setMetadata(metaKey, new FixedMetadataValue(NexusLobby.getInstance(), targetUUID.toString()));
p.sendMessage(prefix + "§aNPC §e" + slotStr + " §amarkiert (§7" + targetUUID.toString().substring(0, 8) + "...§a)");
p.sendMessage(prefix() + "§aNPC §e" + slotStr + " §amarkiert (§7" + targetUUID.toString().substring(0, 8) + "...§a)");
p.spawnParticle(Particle.WITCH, target.getLocation().add(0, 1.0, 0), 15, 0.2, 0.2, 0.2, 0.05);
break;
case "link":
if (args.length < 3) {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_link_usage"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_link_usage"));
return true;
}
if (!p.hasMetadata("conv_npc1") || !p.hasMetadata("conv_npc2")) {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_mark_npcs"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_mark_npcs"));
return true;
}
@@ -101,8 +101,8 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
// Im Manager speichern (Nutzt die erweiterte Methode für Gruppen)
NexusLobby.getInstance().getConversationManager().saveLinkExtended(id1, id2, id3, id4, dialogId);
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_link_created"));
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_link_npcs").replace("{count}", (id3 == null ? "2" : (id4 == null ? "3" : "4"))));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_link_created"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_link_npcs").replace("{count}", (id3 == null ? "2" : (id4 == null ? "3" : "4"))));
p.spawnParticle(Particle.HAPPY_VILLAGER, as1.getLocation().add(0, 1.5, 0), 20, 0.4, 0.4, 0.4, 0.1);
// Metadaten nach dem Linken aufräumen
@@ -111,14 +111,14 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
p.removeMetadata("conv_npc3", NexusLobby.getInstance());
p.removeMetadata("conv_npc4", NexusLobby.getInstance());
} else {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_speaker_not_found"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_speaker_not_found"));
}
break;
case "unlink":
ArmorStand targetUnlink = getTargetArmorStand(p);
if (targetUnlink == null) {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_unlink_lookat"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_unlink_lookat"));
return true;
}
@@ -128,17 +128,17 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
// Aus Konfiguration löschen
NexusLobby.getInstance().getConversationManager().removeLink(targetUnlink.getUniqueId());
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_unlinked"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_unlinked"));
p.spawnParticle(Particle.SMOKE, targetUnlink.getLocation().add(0, 1.0, 0), 20, 0.2, 0.2, 0.2, 0.02);
break;
case "start":
if (args.length < 3) {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_start_usage"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_start_usage"));
return true;
}
if (!p.hasMetadata("conv_npc1") || !p.hasMetadata("conv_npc2")) {
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("conv_mark_two_npcs"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("conv_mark_two_npcs"));
return true;
}
@@ -163,7 +163,7 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
ArmorStand target = getTargetArmorStand(p);
if (args[0].equalsIgnoreCase("say") && args.length >= 2) {
if (target == null) { p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
if (target == null) { p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
String text = buildString(args, 1);
String colored = ChatColor.translateAlternateColorCodes('&', text);
@@ -171,25 +171,25 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
// Nutzt die showBubble-Logik aus dem ConversationManager (Ohne Partner-Zwang)
NexusLobby.getInstance().getConversationManager().showBubble(target, colored);
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("npc_bubble_sent"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("npc_bubble_sent"));
return true;
}
if (args[0].equalsIgnoreCase("lookat")) {
if (target == null) { p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
if (target == null) { p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
if (target.getScoreboardTags().contains("as_lookat")) {
target.removeScoreboardTag("as_lookat");
target.setHeadPose(new EulerAngle(0, 0, 0));
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("lookat_off"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("lookat_off"));
} else {
target.addScoreboardTag("as_lookat");
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("lookat_on"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("lookat_on"));
}
return true;
}
if (args[0].equalsIgnoreCase("name") && args.length >= 2) {
if (target == null) { p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
if (target == null) { p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
String nameInput = buildString(args, 1);
// Wichtig: Alle alten Namens-Tags entfernen für Konsistenz
@@ -198,7 +198,7 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
if (nameInput.equalsIgnoreCase("none")) {
target.setCustomName("");
target.setCustomNameVisible(false);
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("name_removed"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("name_removed"));
} else {
String colored = ChatColor.translateAlternateColorCodes('&', nameInput);
target.setCustomName(colored);
@@ -208,19 +208,19 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
// ":" wird durch "§§" ersetzt, um Probleme in Scoreboard-Tags zu vermeiden
target.addScoreboardTag("as_displayname:" + nameInput.replace(":", "§§"));
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("name_set").replace("{name}", colored));
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("status_backup_saved"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("name_set").replace("{name}", colored));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("status_backup_saved"));
}
return true;
}
if (args[0].equalsIgnoreCase("add") && args.length >= 5) {
if (target == null) { p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
if (target == null) { p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("armorstand_lookat_required")); return true; }
String slot1 = args[1], slot2 = args[2], type = args[3].toLowerCase();
String cmdStr = buildString(args, 4);
target.addScoreboardTag("ascmd:" + slot1 + ":" + slot2 + ":" + type + ":" + cmdStr);
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("command_bound"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("command_bound"));
return true;
}
@@ -234,18 +234,18 @@ public class ArmorStandCmdExecutor implements CommandExecutor {
if (args[0].equalsIgnoreCase("remove")) {
if (target == null) { p.sendMessage(de.nexuslobby.utils.LangManager.get("no_target")); return true; }
target.getScoreboardTags().removeIf(tag -> tag.startsWith("ascmd:"));
p.sendMessage(prefix + de.nexuslobby.utils.LangManager.get("commands_removed"));
p.sendMessage(prefix() + de.nexuslobby.utils.LangManager.get("commands_removed"));
return true;
}
if (args[0].equalsIgnoreCase("clearbubbles")) {
ConversationManager cm = NexusLobby.getInstance().getConversationManager();
if (cm == null) {
p.sendMessage(prefix + "§cConversationManager ist nicht aktiv.");
p.sendMessage(prefix() + "§cConversationManager ist nicht aktiv.");
return true;
}
cm.clearHangingBubbles();
p.sendMessage(prefix + "§aAlle hängenden Sprechblasen wurden entfernt.");
p.sendMessage(prefix() + "§aAlle hängenden Sprechblasen wurden entfernt.");
p.playSound(p.getLocation(), org.bukkit.Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 2f);
return true;
}
@@ -50,7 +50,7 @@ public class ArmorStandCommand implements CommandExecutor {
}
// Fester Prefix für maximale Build-Sicherheit
String prefix = "§8[§6Nexus§8] ";
String prefix = de.nexuslobby.utils.LangManager.getPrefix();
if (!p.hasPermission("nexuslobby.armorstand.use")) {
p.sendMessage(prefix + ChatColor.RED + "Dazu hast du keine Rechte!");
@@ -59,11 +59,11 @@ public enum ArmorStandTool {
// Automatisches Markieren via GUI
if (!p.hasMetadata("conv_npc1")) {
p.setMetadata("conv_npc1", new FixedMetadataValue(NexusLobby.getInstance(), as.getUniqueId().toString()));
p.sendMessage("§8[§6Nexus§8] §aNPC als Sprecher 1 markiert.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aNPC als Sprecher 1 markiert.");
} else {
p.setMetadata("conv_npc2", new FixedMetadataValue(NexusLobby.getInstance(), as.getUniqueId().toString()));
p.sendMessage("§8[§6Nexus§8] §aNPC als Sprecher 2 markiert.");
p.sendMessage("§8[§6Nexus§8] §7Nutze nun §e/nexuscmd conv start <ID>");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aNPC als Sprecher 2 markiert.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§7Nutze nun §e/nexuscmd conv start <ID>");
}
p.closeInventory();
}
@@ -16,7 +16,7 @@ public class BorderCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player p)) return true;
if (!p.hasPermission("nexuslobby.admin")) {
p.sendMessage("§8[§6Nexus§8] §cKeine Rechte.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cKeine Rechte.");
return true;
}
@@ -55,7 +55,7 @@ public class BorderCommand implements CommandExecutor {
config.set("worldborder.center.y", loc.getY());
config.set("worldborder.center.z", loc.getZ());
p.sendMessage("§8[§6Nexus§8] §aKreis-Grenze (Radius: " + radius + ") gesetzt.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aKreis-Grenze (Radius: " + radius + ") gesetzt.");
} catch (NumberFormatException e) {
p.sendMessage("§cUngültige Zahl.");
return true;
@@ -65,7 +65,7 @@ public class BorderCommand implements CommandExecutor {
Location l1 = PortalCommand.getSelection1(p);
Location l2 = PortalCommand.getSelection2(p);
if (l1 == null || l2 == null) {
p.sendMessage("§8[§6Nexus§8] §cBitte markiere erst 2 Punkte mit der Portalwand!");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cBitte markiere erst 2 Punkte mit der Portalwand!");
return true;
}
@@ -83,11 +83,11 @@ public class BorderCommand implements CommandExecutor {
config.set("worldborder.pos2.y", l2.getY());
config.set("worldborder.pos2.z", l2.getZ());
p.sendMessage("§8[§6Nexus§8] §aViereckige Grenze erfolgreich gesetzt.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aViereckige Grenze erfolgreich gesetzt.");
}
case "disable" -> {
config.set("worldborder.enabled", false);
p.sendMessage("§8[§6Nexus§8] §cGrenze wurde deaktiviert.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cGrenze wurde deaktiviert.");
}
default -> {
p.sendMessage("§cUnbekannter Unterbefehl.");
@@ -135,7 +135,7 @@ public class BorderModule implements Module, Listener {
if (spawnLocation != null) {
player.teleport(spawnLocation);
player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1.0f, 0.5f);
player.sendMessage("§8[§6Nexus§8] §cDu hast den Lobby-Bereich verlassen!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cDu hast den Lobby-Bereich verlassen!");
}
}
}
@@ -37,7 +37,7 @@ public class FreezeRay {
if (target != shooter) {
if (GadgetShield.isProtected(target)) {
String reason = GadgetShield.isAdminShielded(target) ? "Dieser Spieler hat Gadget-Schutz aktiviert." : "Dieser Spieler ist gerade im Parkour.";
shooter.sendMessage("§8[§6Nexus§8] §7" + reason);
shooter.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§7" + reason);
return;
}
@@ -58,7 +58,7 @@ public class FreezeRay {
if (!frozenPlayers.contains(target.getUniqueId())) {
frozenPlayers.add(target.getUniqueId());
final Location freezeLocation = target.getLocation();
target.sendMessage("§8[§6Nexus§8] §bDu wurdest eingefroren!");
target.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§bDu wurdest eingefroren!");
target.getWorld().playSound(target.getLocation(), Sound.BLOCK_GLASS_BREAK, 1.0F, 0.5F);
(new BukkitRunnable() {
int ticks = 0;
@@ -92,7 +92,7 @@ public class GadgetModule implements Module, Listener {
long remaining = durationMs - (now - last);
if (remaining > 0L) {
long secLeft = (long)Math.ceil((double)remaining / (double)1000.0F);
player.sendMessage("§8[§6Nexus§8] §c" + gadgetName + " §7hat noch §e" + secLeft + "s §7Cooldown.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§c" + gadgetName + " §7hat noch §e" + secLeft + "s §7Cooldown.");
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 0.5F, 0.8F);
return false;
} else {
@@ -142,7 +142,7 @@ public class GadgetModule implements Module, Listener {
} else {
if (GadgetShield.isAdminShielded(player)) {
player.sendMessage("§8[§6Nexus§8] §cDein Gadget-Schutz ist aktiv. Deaktiviere ihn mit §e/nexus gadgetshield§c.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cDein Gadget-Schutz ist aktiv. Deaktiviere ihn mit §e/nexus gadgetshield§c.");
} else {
player.sendMessage("§8[§6Parkour§8] §cGadgets können während des Parkours nicht benutzt werden.");
}
@@ -165,7 +165,7 @@ public class GadgetModule implements Module, Listener {
}
if (GadgetShield.isProtected(player)) {
player.sendMessage("§8[§6Nexus§8] §cDer Enterhaken ist gerade nicht verfügbar.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cDer Enterhaken ist gerade nicht verfügbar.");
return;
}
@@ -498,7 +498,7 @@ public class GadgetModule implements Module, Listener {
}
if (spawned) {
player.sendMessage("§8[§6Nexus§8] §dDein Pet wurde gerufen!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§dDein Pet wurde gerufen!");
player.closeInventory();
}
} else if (title.equals("§b§lGadgets §8- §dBegleiter §7(2)")) {
@@ -513,7 +513,7 @@ public class GadgetModule implements Module, Listener {
}
if (spawned) {
player.sendMessage("§8[§6Nexus§8] §dDein Pet wurde gerufen!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§dDein Pet wurde gerufen!");
player.closeInventory();
}
} else if (title.equals("§b§lGadgets §8- §dBegleiter §7(3)")) {
@@ -530,7 +530,7 @@ public class GadgetModule implements Module, Listener {
}
if (spawned) {
player.sendMessage("§8[§6Nexus§8] §dDein Pet wurde gerufen!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§dDein Pet wurde gerufen!");
player.closeInventory();
}
} else if (title.equals("§b§lGadgets §8- §eBallons")) {
@@ -540,7 +540,7 @@ public class GadgetModule implements Module, Listener {
}
this.activeBalloons.put(player.getUniqueId(), new Balloon(player, item.getType()));
player.sendMessage("§8[§6Nexus§8] §aBallon aktiviert!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aBallon aktiviert!");
player.closeInventory();
}
} else if (title.equals("§b§lGadgets §8- §dPartikel")) {
@@ -552,12 +552,12 @@ public class GadgetModule implements Module, Listener {
this.activeEffects.put(player.getUniqueId(), new ParticleEffect("cloud"));
}
player.sendMessage("§8[§6Nexus§8] §aPartikel aktiviert!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aPartikel aktiviert!");
player.closeInventory();
} else if (title.equals("§b§lGadgets §8- §6Lustiges")) {
if (item.getType() == Material.EGG) {
ChickenRain.start(player);
player.sendMessage("§8[§6Nexus§8] §fHühnerregen gestartet!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§fHühnerregen gestartet!");
player.closeInventory();
} else if (item.getType() == Material.FISHING_ROD) {
player.getInventory().addItem(new ItemStack[]{this.createItem(Material.FISHING_ROD, "§b§lEnterhaken", "§7Rechtsklick zum Katapultieren §8(3s CD)")});
@@ -574,10 +574,10 @@ public class GadgetModule implements Module, Listener {
} else if (item.getType() == Material.SHIELD) {
if (this.activeShields.contains(player.getUniqueId())) {
this.activeShields.remove(player.getUniqueId());
player.sendMessage("§8[§6Nexus§8] §cSchutzzone deaktiviert.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cSchutzzone deaktiviert.");
} else {
this.activeShields.add(player.getUniqueId());
player.sendMessage("§8[§6Nexus§8] §5Schutzzone aktiviert!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§5Schutzzone aktiviert!");
}
player.closeInventory();
@@ -599,7 +599,7 @@ public class GadgetModule implements Module, Listener {
}
}, 0L, 1L);
player.playSound(player.getLocation(), Sound.ENTITY_PHANTOM_FLAP, 1.0F, 1.2F);
player.sendMessage("§8[§6Nexus§8] §fMini-Tornado: Du wirbelst herum!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§fMini-Tornado: Du wirbelst herum!");
player.closeInventory();
} else if (item.getType() == Material.TNT) {
Location tntLoc = player.getLocation().add((double)0.0F, (double)0.5F, (double)0.0F);
@@ -609,7 +609,7 @@ public class GadgetModule implements Module, Listener {
player.getWorld().spawnParticle(Particle.EXPLOSION, tntLoc, 2, (double)0.5F, 0.2, (double)0.5F, 0.1);
player.getWorld().playSound(tntLoc, Sound.ENTITY_GENERIC_EXPLODE, 1.0F, 1.1F);
}, 30L);
player.sendMessage("§8[§6Nexus§8] §cFake-TNT gezündet! Keine Sorge, alles harmlos.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cFake-TNT gezündet! Keine Sorge, alles harmlos.");
player.closeInventory();
} else if (item.getType() == Material.SLIME_BALL) {
World world = player.getWorld();
@@ -662,7 +662,7 @@ public class GadgetModule implements Module, Listener {
}
}, 0L, 2L);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_CELEBRATE, 1.0F, 1.2F);
player.sendMessage("§8[§6Nexus§8] §aMob-Party gestartet! Die Mobs tanzen um dich.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aMob-Party gestartet! Die Mobs tanzen um dich.");
player.closeInventory();
} else if (item.getType() == Material.FIREWORK_ROCKET) {
for(int i = 0; i < 3; ++i) {
@@ -673,7 +673,7 @@ public class GadgetModule implements Module, Listener {
}, (long)i * 6L);
}
player.sendMessage("§8[§6Nexus§8] §cKonfetti-Kanone: Buntes Konfetti überall!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cKonfetti-Kanone: Buntes Konfetti überall!");
player.closeInventory();
} else if (item.getType() == Material.NOTE_BLOCK) {
Bukkit.getScheduler().runTaskTimer(NexusLobby.getInstance(), new Runnable() {
@@ -691,7 +691,7 @@ public class GadgetModule implements Module, Listener {
}
}
}, 0L, 2L);
player.sendMessage("§8[§6Nexus§8] §dTanz-Emote: Du beginnst zu tanzen!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§dTanz-Emote: Du beginnst zu tanzen!");
player.closeInventory();
}
}
@@ -721,7 +721,7 @@ public class GadgetModule implements Module, Listener {
player.getInventory().remove(Material.PACKED_ICE);
player.getInventory().remove(Material.GOLDEN_HOE);
player.getInventory().remove(Material.FIRE_CHARGE);
player.sendMessage("§8[§6Nexus§8] §cAlle Gadgets abgelegt.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cAlle Gadgets abgelegt.");
}
private void fillEdges(Inventory inv) {
@@ -15,12 +15,12 @@ public class GadgetShield {
UUID uuid = player.getUniqueId();
if (shielded.contains(uuid)) {
shielded.remove(uuid);
player.sendMessage("§8[§6Nexus§8] §cGadget-Schutz §7deaktiviert.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cGadget-Schutz §7deaktiviert.");
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1.0F, 1.0F);
return false;
} else {
shielded.add(uuid);
player.sendMessage("§8[§6Nexus§8] §aGadget-Schutz §7aktiviert. §8Du bist nun immun gegen Gadgets.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aGadget-Schutz §7aktiviert. §8Du bist nun immun gegen Gadgets.");
player.playSound(player.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_CHIME, 1.0F, 1.5F);
return true;
}
@@ -15,7 +15,7 @@ public class HatManager {
}
player.getInventory().setHelmet(hat);
player.sendMessage("§8[§6Nexus§8] §aDu trägst nun: " + name);
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aDu trägst nun: " + name);
}
public static void removeHat(Player player) {
@@ -26,7 +26,7 @@ public class MeteorStrike {
if (target != null) {
Location finalTarget = target.clone().add((double)0.0F, (double)0.5F, (double)0.0F);
finalTarget.getWorld().spawnParticle(Particle.FLAME, finalTarget, 20, (double)0.5F, 0.1, (double)0.5F, 0.05);
shooter.sendMessage("§8[§6Nexus§8] §cMeteorit im Anflug...");
shooter.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cMeteorit im Anflug...");
Bukkit.getScheduler().runTaskLater(NexusLobby.getInstance(), () -> {
finalTarget.getWorld().spawnParticle(Particle.EXPLOSION_EMITTER, finalTarget, 1);
finalTarget.getWorld().spawnParticle(Particle.LAVA, finalTarget, 30, (double)0.5F, (double)0.5F, (double)0.5F, 0.1);
@@ -36,7 +36,7 @@ public class MeteorStrike {
if (entity instanceof Player p) {
if (GadgetShield.isProtected(p)) {
if (GadgetShield.isAdminShielded(p)) {
p.sendMessage("§8[§6Nexus§8] §7Dein Gadget-Schutzschild hat den Meteoriten abgelenkt!");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§7Dein Gadget-Schutzschild hat den Meteoriten abgelenkt!");
} else {
p.sendMessage("§8[§6Parkour§8] §7Dein Parkour-Schutzschild hat den Meteoriten abgelenkt!");
}
@@ -23,7 +23,7 @@ public class HoloCommand implements CommandExecutor {
if (!(sender instanceof Player player)) return true;
if (!player.hasPermission("nexuslobby.hologram")) {
player.sendMessage("§8[§6Nexus§8] §cKeine Rechte.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cKeine Rechte.");
return true;
}
@@ -59,7 +59,7 @@ public class HoloCommand implements CommandExecutor {
// Aufruf der neuen Methode mit List<String>
module.createHologram(id, player.getLocation(), pages);
player.sendMessage("§8[§6Nexus§8] §aHologramm §e" + id + " §aerstellt (" + pages.size() + " Seiten).");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aHologramm §e" + id + " §aerstellt (" + pages.size() + " Seiten).");
}
else if (args[0].equalsIgnoreCase("delete")) {
if (args.length < 2) {
@@ -67,11 +67,11 @@ public class HoloCommand implements CommandExecutor {
return true;
}
module.removeHologram(args[1]);
player.sendMessage("§8[§6Nexus§8] §cHologramm §e" + args[1] + " §agelöscht.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cHologramm §e" + args[1] + " §agelöscht.");
}
else if (args[0].equalsIgnoreCase("reload")) {
module.reloadHolograms();
player.sendMessage("§8[§6Nexus§8] §aHologramme neu geladen.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aHologramme neu geladen.");
} else {
sendHelp(player);
}
@@ -165,9 +165,9 @@ public class IntroModule implements Module, Listener, CommandExecutor {
labels.add(pointLabel);
saveConfig();
if (pointLabel.isEmpty()) {
p.sendMessage("§8[§6Nexus§8] §aPunkt §e#" + points.size() + " §awurde gesetzt.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aPunkt §e#" + points.size() + " §awurde gesetzt.");
} else {
p.sendMessage("§8[§6Nexus§8] §aPunkt §e#" + points.size() + " §amit Text §e\"" + pointLabel + "\" §agesetzt.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aPunkt §e#" + points.size() + " §amit Text §e\"" + pointLabel + "\" §agesetzt.");
}
}
@@ -175,12 +175,12 @@ public class IntroModule implements Module, Listener, CommandExecutor {
points.clear();
labels.clear();
saveConfig();
p.sendMessage("§8[§6Nexus§8] §cAlle Intro-Punkte wurden gelöscht.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cAlle Intro-Punkte wurden gelöscht.");
}
case "list" -> {
if (points.isEmpty()) {
p.sendMessage("§8[§6Nexus§8] §cKeine Punkte vorhanden.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cKeine Punkte vorhanden.");
return true;
}
p.sendMessage("§8§m------------------------------------");
@@ -199,7 +199,7 @@ public class IntroModule implements Module, Listener, CommandExecutor {
case "start" -> {
if (points.size() < 2) {
p.sendMessage("§8[§6Nexus§8] §cDu brauchst mindestens 2 Punkte für eine Fahrt.");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cDu brauchst mindestens 2 Punkte für eine Fahrt.");
} else {
startIntro(p);
}
@@ -208,13 +208,13 @@ public class IntroModule implements Module, Listener, CommandExecutor {
// /intro setendtitle <Text> — setzt den großen Abschluss-Titel
case "setendtitle" -> {
if (args.length < 2) {
p.sendMessage("§8[§6Nexus§8] §cBenutzung: §e/intro setendtitle <Text>");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cBenutzung: §e/intro setendtitle <Text>");
p.sendMessage("§7Farbcodes mit §e& §7möglich. Beispiel: §e/intro setendtitle &a&lWillkommen!");
return true;
}
endTitle = colorize(String.join(" ", Arrays.copyOfRange(args, 1, args.length)));
saveConfig();
p.sendMessage("§8[§6Nexus§8] §aAbschluss-Titel gesetzt: " + endTitle);
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aAbschluss-Titel gesetzt: " + endTitle);
// Vorschau
p.sendTitle(endTitle, endSubtitle, TITLE_FADE_IN, TITLE_STAY, TITLE_FADE_OUT);
}
@@ -222,13 +222,13 @@ public class IntroModule implements Module, Listener, CommandExecutor {
// /intro setendsubtitle <Text> — setzt den kleinen Abschluss-Untertitel
case "setendsubtitle" -> {
if (args.length < 2) {
p.sendMessage("§8[§6Nexus§8] §cBenutzung: §e/intro setendsubtitle <Text>");
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cBenutzung: §e/intro setendsubtitle <Text>");
p.sendMessage("§7Farbcodes mit §e& §7möglich. Beispiel: §e/intro setendsubtitle &7Viel Spaß!");
return true;
}
endSubtitle = colorize(String.join(" ", Arrays.copyOfRange(args, 1, args.length)));
saveConfig();
p.sendMessage("§8[§6Nexus§8] §aAbschluss-Untertitel gesetzt: " + endSubtitle);
p.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aAbschluss-Untertitel gesetzt: " + endSubtitle);
// Vorschau
p.sendTitle(endTitle, endSubtitle, TITLE_FADE_IN, TITLE_STAY, TITLE_FADE_OUT);
}
@@ -119,7 +119,7 @@ public class MapArtModule implements Module, CommandExecutor {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (!(sender instanceof Player player)) return true;
if (!player.hasPermission("nexuslobby.mapart")) {
player.sendMessage("§8[§6Nexus§8] §cKeine Rechte.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cKeine Rechte.");
return true;
}
@@ -134,7 +134,7 @@ public class MapArtModule implements Module, CommandExecutor {
try {
radius = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
player.sendMessage("§8[§6Nexus§8] §cUngültiger Radius.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cUngültiger Radius.");
return true;
}
}
@@ -149,7 +149,7 @@ public class MapArtModule implements Module, CommandExecutor {
RayTraceResult rayTrace = player.rayTraceBlocks(5);
if (rayTrace == null || rayTrace.getHitBlock() == null || rayTrace.getHitBlockFace() == null) {
player.sendMessage("§8[§6Nexus§8] §cBitte schaue eine Wand direkt an.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cBitte schaue eine Wand direkt an.");
return true;
}
@@ -157,7 +157,7 @@ public class MapArtModule implements Module, CommandExecutor {
BlockFace hitFace = rayTrace.getHitBlockFace();
if (hitFace == BlockFace.UP || hitFace == BlockFace.DOWN) {
player.sendMessage("§8[§6Nexus§8] §cAktuell nur an vertikalen Wänden möglich.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cAktuell nur an vertikalen Wänden möglich.");
return true;
}
@@ -168,11 +168,11 @@ public class MapArtModule implements Module, CommandExecutor {
width = Integer.parseInt(parts[0]);
height = Integer.parseInt(parts[1]);
} catch (Exception e) {
player.sendMessage("§8[§6Nexus§8] §cUngültiges Format (z.B. 6x4).");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§cUngültiges Format (z.B. 6x4).");
return true;
}
player.sendMessage("§8[§6Nexus§8] §7Bild wird verarbeitet...");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§7Bild wird verarbeitet...");
createRaster(player, targetBlock, hitFace, url, width, height);
return true;
@@ -204,7 +204,7 @@ public class MapArtModule implements Module, CommandExecutor {
}
});
saveStorage();
player.sendMessage("§8[§6Nexus§8] §aErfolgreich §e" + count.get() + " §aKartenelemente gelöscht.");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aErfolgreich §e" + count.get() + " §aKartenelemente gelöscht.");
}
private void createRaster(Player player, Block startBlock, BlockFace face, String url, int gridW, int gridH) {
@@ -225,7 +225,7 @@ public class MapArtModule implements Module, CommandExecutor {
spawnPersistentFrame(player, currentPos, face, url, x, y, gridW, gridH);
}
}
player.sendMessage("§8[§6Nexus§8] §aBild-Raster wurde permanent platziert!");
player.sendMessage(de.nexuslobby.utils.LangManager.getPrefix() + "§aBild-Raster wurde permanent platziert!");
}
private void spawnPersistentFrame(Player player, Block pos, BlockFace face, String url, int x, int y, int totalW, int totalH) {