From 657a83e182957f18e2e21d03b90650d9f06a0df1 Mon Sep 17 00:00:00 2001 From: M_Viper Date: Mon, 25 Aug 2025 08:20:16 +0200 Subject: [PATCH] Update Projekt - ohne .zip und target --- .gitignore | 5 + pom.xml | 3 +- .../survivalplus/Manager/CommandBlocker.java | 193 ++++++++++ .../survivalplus/Manager/TablistManager.java | 298 ++++++++++++--- .../de/viper/survivalplus/SurvivalPlus.java | 73 +++- src/main/resources/blockedcommands.yml | 4 + src/main/resources/help.yml | 227 ++++++++---- src/main/resources/plugin.yml | 349 +++++++++--------- 8 files changed, 862 insertions(+), 290 deletions(-) create mode 100644 .gitignore create mode 100644 src/main/java/de/viper/survivalplus/Manager/CommandBlocker.java create mode 100644 src/main/resources/blockedcommands.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..856359f --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Ignoriere Build-Ordner +target/ + +# Ignoriere ZIP-Dateien +*.zip diff --git a/pom.xml b/pom.xml index c314278..03ede6d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ de.viper SurvivalPlus - 1.0.5-Beta + 1.0.7-Beta jar SurvivalPlus @@ -111,6 +111,7 @@ shop.yml warps.yml tablist.yml + blockedcommands.yml diff --git a/src/main/java/de/viper/survivalplus/Manager/CommandBlocker.java b/src/main/java/de/viper/survivalplus/Manager/CommandBlocker.java new file mode 100644 index 0000000..44915ca --- /dev/null +++ b/src/main/java/de/viper/survivalplus/Manager/CommandBlocker.java @@ -0,0 +1,193 @@ +package de.viper.survivalplus.Manager; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class CommandBlocker implements Listener, CommandExecutor { + + private final SurvivalPlus plugin; + private FileConfiguration blockedCommandsConfig; + private File blockedCommandsFile; + private List blockedCommands; + + public CommandBlocker(SurvivalPlus plugin) { + this.plugin = plugin; + + // Lade blockedcommands.yml + try { + blockedCommandsFile = new File(plugin.getDataFolder(), "blockedcommands.yml"); + if (!blockedCommandsFile.exists()) { + plugin.saveResource("blockedcommands.yml", false); + } + blockedCommandsConfig = YamlConfiguration.loadConfiguration(blockedCommandsFile); + blockedCommands = blockedCommandsConfig.getStringList("blocked-commands"); + if (blockedCommands == null) { + blockedCommands = new ArrayList<>(); + } + } catch (Exception ignored) { + blockedCommands = new ArrayList<>(); + } + + // Registriere Listener und Command + plugin.getServer().getPluginManager().registerEvents(this, plugin); + plugin.getCommand("sp").setExecutor(this); + } + + /** + * Verarbeitet /sp cb Befehle + */ + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length < 2 || !args[0].equalsIgnoreCase("cb")) { + return false; // Wird von anderen /sp Subcommands behandelt + } + + String subCommand = args[1].toLowerCase(); + + switch (subCommand) { + case "add": + return handleAddCommand(sender, args); + case "remove": + return handleRemoveCommand(sender, args); + case "list": + return handleListCommand(sender); + default: + sender.sendMessage("§cUnbekannter Subcommand! Verfügbare Subcommands: add, remove, list"); + return true; + } + } + + /** + * /sp cb add + */ + private boolean handleAddCommand(CommandSender sender, String[] args) { + if (!sender.hasPermission("survivalplus.commandblocker.add")) { + sender.sendMessage("§cDu hast keine Berechtigung für diesen Befehl!"); + return true; + } + + if (args.length < 3) { + sender.sendMessage("§eBenutzung: /sp cb add "); + return true; + } + + String commandToBlock = args[2].toLowerCase().replaceFirst("^/", "").trim(); + if (commandToBlock.isEmpty()) { + sender.sendMessage("§cBitte gib einen gültigen Befehl an!"); + return true; + } + + try { + if (blockedCommands.contains(commandToBlock)) { + sender.sendMessage("§cDer Befehl §e/" + commandToBlock + "§c ist bereits blockiert!"); + return true; + } + + blockedCommands.add(commandToBlock); + blockedCommandsConfig.set("blocked-commands", blockedCommands); + blockedCommandsConfig.save(blockedCommandsFile); + sender.sendMessage("§aDer Befehl §e/" + commandToBlock + "§a wurde zur Blockierliste hinzugefügt."); + } catch (Exception ignored) { + sender.sendMessage("§cFehler beim Hinzufügen des Befehls!"); + } + return true; + } + + /** + * /sp cb remove + */ + private boolean handleRemoveCommand(CommandSender sender, String[] args) { + if (!sender.hasPermission("survivalplus.commandblocker.remove")) { + sender.sendMessage("§cDu hast keine Berechtigung für diesen Befehl!"); + return true; + } + + if (args.length < 3) { + sender.sendMessage("§eBenutzung: /sp cb remove "); + return true; + } + + String commandToUnblock = args[2].toLowerCase().replaceFirst("^/", "").trim(); + if (commandToUnblock.isEmpty()) { + sender.sendMessage("§cBitte gib einen gültigen Befehl an!"); + return true; + } + + try { + if (!blockedCommands.contains(commandToUnblock)) { + sender.sendMessage("§cDer Befehl §e/" + commandToUnblock + "§c ist nicht blockiert!"); + return true; + } + + blockedCommands.remove(commandToUnblock); + blockedCommandsConfig.set("blocked-commands", blockedCommands); + blockedCommandsConfig.save(blockedCommandsFile); + sender.sendMessage("§aDer Befehl §e/" + commandToUnblock + "§a wurde aus der Blockierliste entfernt."); + } catch (Exception ignored) { + sender.sendMessage("§cFehler beim Entfernen des Befehls!"); + } + return true; + } + + /** + * /sp cb list + */ + private boolean handleListCommand(CommandSender sender) { + if (!sender.hasPermission("survivalplus.commandblocker.list")) { + sender.sendMessage("§cDu hast keine Berechtigung für diesen Befehl!"); + return true; + } + + try { + if (blockedCommands.isEmpty()) { + sender.sendMessage("§eEs sind keine Befehle blockiert."); + return true; + } + + sender.sendMessage("§6=== Blockierte Befehle ==="); + for (String cmd : blockedCommands) { + sender.sendMessage("§e- /" + cmd); + } + sender.sendMessage("§6====================="); + } catch (Exception ignored) { + sender.sendMessage("§cFehler beim Abrufen der Blockierliste!"); + } + return true; + } + + /** + * Blockiere Befehle, wenn sie in der Liste sind + */ + @EventHandler + public void onPlayerCommand(PlayerCommandPreprocessEvent event) { + Player player = event.getPlayer(); + if (player.hasPermission("survivalplus.commandblocker.bypass")) { + return; // Spieler mit Bypass-Berechtigung ignorieren + } + + try { + String command = event.getMessage().toLowerCase().replaceFirst("^/", "").trim(); + // Extrahiere den Hauptbefehl (ohne Argumente) + String mainCommand = command.split("\\s+")[0]; + + if (blockedCommands.contains(mainCommand)) { + event.setCancelled(true); + player.sendMessage("§cDieser Befehl ist blockiert!"); + } + } catch (Exception ignored) { + // Keine Konsolenausgabe + } + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/Manager/TablistManager.java b/src/main/java/de/viper/survivalplus/Manager/TablistManager.java index 9a3d117..b20e371 100644 --- a/src/main/java/de/viper/survivalplus/Manager/TablistManager.java +++ b/src/main/java/de/viper/survivalplus/Manager/TablistManager.java @@ -3,21 +3,30 @@ package de.viper.survivalplus.Manager; import de.viper.survivalplus.SurvivalPlus; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.ScoreboardManager; +import org.bukkit.scoreboard.Team; import me.clip.placeholderapi.PlaceholderAPI; import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPermsProvider; import net.luckperms.api.model.user.User; +import java.io.File; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; -import java.util.logging.Level; +import java.util.Map; -public class TablistManager { +public class TablistManager implements Listener { private final SurvivalPlus plugin; private final List headerAnim = new ArrayList<>(); @@ -34,15 +43,39 @@ public class TablistManager { private String staffPermission; private String separatorLine; private LuckPerms luckPerms; + private boolean hasPlaceholderAPI; + private final Scoreboard scoreboard; + private final Map prefixTeams; + private FileConfiguration nicknameConfig; public TablistManager(SurvivalPlus plugin) { this.plugin = plugin; + this.prefixTeams = new HashMap<>(); + + // Scoreboard initialisieren + ScoreboardManager scoreboardManager = Bukkit.getScoreboardManager(); + this.scoreboard = scoreboardManager != null ? scoreboardManager.getMainScoreboard() : null; // Resource sicherstellen, Config laden - try { plugin.saveResource("tablist.yml", false); } catch (Exception ignored) {} - try { plugin.reloadTablistConfig(); } catch (Throwable ignored) {} + try { + plugin.saveResource("tablist.yml", false); + } catch (Exception ignored) {} + try { + plugin.reloadTablistConfig(); + } catch (Exception ignored) {} FileConfiguration config = plugin.getTablistConfig(); + // Nicknames.yml laden + try { + File nicknameFile = new File(plugin.getDataFolder(), "nicknames.yml"); + if (!nicknameFile.exists()) { + plugin.saveResource("nicknames.yml", false); + } + this.nicknameConfig = YamlConfiguration.loadConfiguration(nicknameFile); + } catch (Exception ignored) { + this.nicknameConfig = null; // Keine Konsolenausgabe + } + // Konfigurationswerte laden this.enabled = config.getBoolean("enabled", true); this.serverName = config.getString("server-name", "SurvivalPlus"); @@ -57,13 +90,16 @@ public class TablistManager { // LuckPerms API initialisieren try { this.luckPerms = LuckPermsProvider.get(); - } catch (IllegalStateException e) { - plugin.getLogger().warning("LuckPerms nicht gefunden! Versuche Fallback auf PlaceholderAPI."); + } catch (Throwable e) { + luckPerms = null; // Keine Konsolenausgabe } // Prüfen, ob PlaceholderAPI verfügbar ist - if (!Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { - plugin.getLogger().warning("PlaceholderAPI nicht gefunden! Verwende Standard-Prefix als Fallback."); + this.hasPlaceholderAPI = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"); + + // Chat-Listener registrieren + if (enabled) { + Bukkit.getPluginManager().registerEvents(this, plugin); } if (!enabled) { @@ -112,17 +148,29 @@ public class TablistManager { for (Player player : Bukkit.getOnlinePlayers()) { try { - // Spieler-Prefix abrufen (LuckPerms primär, PlaceholderAPI als Fallback) - String prefix = getPlayerPrefix(player); - int ping = getPlayerPing(player); - // Korrigierte Formatierung: Gesamten String durch color-Methode leiten - String prefixedName = color(prefix + player.getName() + "&8 | &e" + ping + "ms"); - player.setPlayerListName(prefixedName); + // Nickname oder Spielername verwenden + String displayName = getNickname(player); + if (displayName == null || displayName.trim().isEmpty()) { + displayName = player.getName(); + } - // Header mit Spielername und Statistiken + // Spielername für die Tablist setzen + String playerListName; + String prefix = getPlayerPrefix(player); + if (luckPerms == null && !hasPlaceholderAPI) { + playerListName = displayName; + updateNametag(player, "", displayName); + } else { + int ping = getPlayerPing(player); + playerListName = color(prefix + displayName + (ping >= 0 ? "&8 | &e" + ping + "ms" : "")); + updateNametag(player, prefix, displayName); + } + player.setPlayerListName(playerListName); + + // Header mit Spielername/Nickname und Statistiken String headerRaw = headerAnim.get(headerIndex) .replace("{server}", serverName) - .replace("{player}", player.getName()) + .replace("{player}", displayName) .replace("{online}", String.valueOf(onlinePlayers)) .replace("{staff}", String.valueOf(onlineStaff)); String footerRaw = footerAnim.get(footerIndex); @@ -131,7 +179,7 @@ public class TablistManager { StringBuilder footerBuilder = new StringBuilder(); footerBuilder.append("\n"); // Extra Abstand footerBuilder.append(color(footerRaw)).append("\n"); - + footerBuilder.append(color(separatorLine)).append("\n"); if (showTeamspeak || showDiscord) { StringBuilder socialLine = new StringBuilder(); @@ -161,12 +209,9 @@ public class TablistManager { done = tryStringMethod(player, header, footer); } - // 3) Wenn alles fehlschlägt -> Log - if (!done) { - plugin.getLogger().warning("Tablist: Keine geeignete Methode gefunden für Spieler " + player.getName()); - } - } catch (Throwable t) { - plugin.getLogger().log(Level.FINE, "Fehler beim Setzen der Tablist für Spieler " + player.getName(), t); + // 3) Keine Warnung bei Fehlschlag, da dies normal sein kann + } catch (Exception ignored) { + // Keine Konsolenausgabe für Fehler bei der Tablist } } @@ -176,28 +221,170 @@ public class TablistManager { }.runTaskTimer(plugin, 0L, interval); } + /** + * Nickname aus nicknames.yml abrufen + */ + private String getNickname(Player player) { + if (nicknameConfig == null) return null; + try { + String uuid = player.getUniqueId().toString(); + String nickname = nicknameConfig.getString(uuid); + if (nickname != null && !nickname.trim().isEmpty()) { + try { + File debugFile = new File(plugin.getDataFolder(), "debug.yml"); + FileConfiguration debugConfig = YamlConfiguration.loadConfiguration(debugFile); + debugConfig.set(player.getUniqueId().toString() + ".nickname", nickname); + debugConfig.save(debugFile); + } catch (Exception ignored) {} + return nickname; + } + } catch (Exception ignored) { + // Keine Konsolenausgabe + } + return null; + } + + /** + * Nametag über dem Kopf aktualisieren + */ + private void updateNametag(Player player, String prefix, String displayName) { + if (scoreboard == null) return; + + try { + String teamName = generateTeamName(player, prefix); + Team team = scoreboard.getTeam(teamName); + + // Team erstellen oder aktualisieren + if (team == null) { + team = scoreboard.registerNewTeam(teamName); + } + + // Prefix zwingend setzen, wenn LuckPerms installiert ist + String coloredPrefix = color(prefix != null && !prefix.trim().isEmpty() ? prefix : (luckPerms != null ? "&7[Spieler] " : "")); + team.setPrefix(coloredPrefix); + + // Spieler dem Team hinzufügen + String entry = displayName != null && !displayName.trim().isEmpty() ? displayName : player.getName(); + if (!team.hasEntry(entry)) { + // Spieler aus anderen Teams entfernen, um Konflikte zu vermeiden + for (Team existingTeam : scoreboard.getTeams()) { + if (!existingTeam.getName().equals(teamName)) { + existingTeam.removeEntry(entry); + existingTeam.removeEntry(player.getName()); + } + } + team.addEntry(entry); + } + + // Team für alle Spieler sichtbar machen + for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { + if (onlinePlayer.getScoreboard() != scoreboard) { + onlinePlayer.setScoreboard(scoreboard); + } + } + + // Debug-Ausgabe für Nametag + try { + File debugFile = new File(plugin.getDataFolder(), "debug.yml"); + FileConfiguration debugConfig = YamlConfiguration.loadConfiguration(debugFile); + debugConfig.set(player.getUniqueId().toString() + ".nametag_prefix", coloredPrefix); + debugConfig.set(player.getUniqueId().toString() + ".nametag_entry", entry); + debugConfig.save(debugFile); + } catch (Exception ignored) {} + } catch (Exception ignored) { + // Keine Konsolenausgabe + } + } + + /** + * Eindeutigen Teamnamen generieren + */ + private String generateTeamName(Player player, String prefix) { + // Verwende UUID für eindeutige Teamnamen, falls kein Prefix vorhanden + if (prefix == null || prefix.trim().isEmpty()) { + return "nametag_" + player.getUniqueId().toString().substring(0, 8); + } + // Verwende Prefix für Teamnamen, max 16 Zeichen (Bukkit-Beschränkung) + String sanitizedPrefix = prefix.replaceAll("[^a-zA-Z0-9]", "").toLowerCase(); + return "prefix_" + sanitizedPrefix.substring(0, Math.min(sanitizedPrefix.length(), 12)); + } + /** * Spieler-Prefix abrufen (LuckPerms primär, PlaceholderAPI als Fallback) */ private String getPlayerPrefix(Player player) { - // Versuche LuckPerms-API zuerst + // Wenn LuckPerms installiert ist, Prefix zwingend abrufen if (luckPerms != null) { + // Versuche LuckPerms-API zuerst try { User user = luckPerms.getPlayerAdapter(Player.class).getUser(player); String prefix = user.getCachedData().getMetaData().getPrefix(); - return (prefix == null || prefix.isEmpty()) ? "&7[Spieler] " : prefix + " "; - } catch (Exception e) { - plugin.getLogger().log(Level.FINE, "Fehler beim Abrufen des Prefix aus LuckPerms für Spieler " + player.getName(), e); + if (prefix != null && !prefix.trim().isEmpty()) { + try { + File debugFile = new File(plugin.getDataFolder(), "debug.yml"); + FileConfiguration debugConfig = YamlConfiguration.loadConfiguration(debugFile); + debugConfig.set(player.getUniqueId().toString() + ".prefix", prefix); + debugConfig.save(debugFile); + } catch (Exception ignored) {} + return prefix + " "; + } + } catch (Exception ignored) { + // Keine Konsolenausgabe + } + + // Fallback auf PlaceholderAPI, wenn LuckPerms installiert ist + if (hasPlaceholderAPI) { + try { + String prefix = PlaceholderAPI.setPlaceholders(player, "%luckperms_prefix%"); + if (prefix != null && !prefix.trim().isEmpty()) { + try { + File debugFile = new File(plugin.getDataFolder(), "debug.yml"); + FileConfiguration debugConfig = YamlConfiguration.loadConfiguration(debugFile); + debugConfig.set(player.getUniqueId().toString() + ".prefix", prefix); + debugConfig.save(debugFile); + } catch (Exception ignored) {} + return prefix + " "; + } + } catch (Exception ignored) { + // Keine Konsolenausgabe + } + } + + // Standard-Prefix, wenn LuckPerms installiert ist, aber kein Prefix definiert + try { + File debugFile = new File(plugin.getDataFolder(), "debug.yml"); + FileConfiguration debugConfig = YamlConfiguration.loadConfiguration(debugFile); + debugConfig.set(player.getUniqueId().toString() + ".prefix", "&7[Spieler]"); + debugConfig.save(debugFile); + } catch (Exception ignored) {} + return "&7[Spieler] "; + } + + // Wenn LuckPerms nicht installiert ist, aber PlaceholderAPI vorhanden ist + if (hasPlaceholderAPI) { + try { + String prefix = PlaceholderAPI.setPlaceholders(player, "%luckperms_prefix%"); + if (prefix != null && !prefix.trim().isEmpty()) { + try { + File debugFile = new File(plugin.getDataFolder(), "debug.yml"); + FileConfiguration debugConfig = YamlConfiguration.loadConfiguration(debugFile); + debugConfig.set(player.getUniqueId().toString() + ".prefix", prefix); + debugConfig.save(debugFile); + } catch (Exception ignored) {} + return prefix + " "; + } + } catch (Exception ignored) { + // Keine Konsolenausgabe } } - // Fallback auf PlaceholderAPI - if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { - String prefix = PlaceholderAPI.setPlaceholders(player, "%luckperms_prefix%"); - return (prefix == null || prefix.isEmpty()) ? "&7[Spieler] " : prefix + " "; - } - - // Letzter Fallback: Standard-Prefix + // Standard-Prefix, wenn weder LuckPerms noch PlaceholderAPI einen Prefix liefern + try { + File debugFile = new File(plugin.getDataFolder(), "debug.yml"); + FileConfiguration debugConfig = YamlConfiguration.loadConfiguration(debugFile); + debugConfig.set(player.getUniqueId().toString() + ".prefix", "&7[Spieler]"); + debugConfig.save(debugFile); + } catch (Exception ignored) {} return "&7[Spieler] "; } @@ -209,9 +396,28 @@ public class TablistManager { Method getHandle = player.getClass().getMethod("getHandle"); Object entityPlayer = getHandle.invoke(player); return entityPlayer.getClass().getField("ping").getInt(entityPlayer); - } catch (Exception e) { - plugin.getLogger().log(Level.FINE, "Fehler beim Abrufen des Pings für Spieler " + player.getName(), e); - return -1; + } catch (Exception ignored) { + return -1; // Keine Konsolenausgabe + } + } + + /** + * Chat-Format modifizieren + */ + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent event) { + try { + Player player = event.getPlayer(); + String displayName = getNickname(player); + if (displayName == null || displayName.trim().isEmpty()) { + displayName = player.getName(); + } + + String prefix = getPlayerPrefix(player); + String format = color(prefix + displayName + "&7: &f") + "%2$s"; + event.setFormat(format); + } catch (Exception ignored) { + // Keine Konsolenausgabe } } @@ -225,7 +431,9 @@ public class TablistManager { try { textMethod = compClass.getMethod("text", CharSequence.class); } catch (NoSuchMethodException ignored) { - try { textMethod = compClass.getMethod("text", String.class); } catch (NoSuchMethodException ignored2) {} + try { + textMethod = compClass.getMethod("text", String.class); + } catch (NoSuchMethodException ignored2) {} } Object headerComp = null; @@ -243,8 +451,8 @@ public class TablistManager { Method deserialize = miniMsgClass.getMethod("deserialize", String.class); headerComp = deserialize.invoke(miniMsg, headerRaw); footerComp = deserialize.invoke(miniMsg, footerRaw); - } catch (Throwable t) { - // kein MiniMessage + } catch (Exception ignored) { + // Kein MiniMessage } } @@ -265,10 +473,7 @@ public class TablistManager { return true; } } - } catch (ClassNotFoundException cnf) { - return false; - } catch (Throwable t) { - plugin.getLogger().log(Level.FINER, "Adventure-Variante fehlgeschlagen: " + t.getMessage()); + } catch (Exception ignored) { return false; } return false; @@ -295,8 +500,7 @@ public class TablistManager { mf.invoke(player, footer); return true; } - } catch (Throwable t) { - plugin.getLogger().log(Level.FINER, "String-Variante fehlgeschlagen: " + t.getMessage()); + } catch (Exception ignored) { return false; } return false; @@ -311,7 +515,7 @@ public class TablistManager { try { Method m = current.getMethod(name, paramTypes); if (m != null) return m; - } catch (NoSuchMethodException ignored) { } + } catch (NoSuchMethodException ignored) {} current = current.getSuperclass(); } return null; diff --git a/src/main/java/de/viper/survivalplus/SurvivalPlus.java b/src/main/java/de/viper/survivalplus/SurvivalPlus.java index 9cdf3f1..da2850b 100644 --- a/src/main/java/de/viper/survivalplus/SurvivalPlus.java +++ b/src/main/java/de/viper/survivalplus/SurvivalPlus.java @@ -34,7 +34,7 @@ import de.viper.survivalplus.commands.ReportCommand; import de.viper.survivalplus.Manager.ShopManager; import de.viper.survivalplus.commands.HealCommand; import de.viper.survivalplus.Manager.TablistManager; - +import de.viper.survivalplus.Manager.CommandBlocker; import de.viper.survivalplus.Manager.WarpManager; import de.viper.survivalplus.commands.SetWarpCommand; import de.viper.survivalplus.commands.WarpsCommand; @@ -65,7 +65,9 @@ import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; - +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; public class SurvivalPlus extends JavaPlugin { @@ -114,6 +116,13 @@ public class SurvivalPlus extends JavaPlugin { // FunChallengeManager als Feld private FunChallengeManager funChallengeManager; + private File blockedCommandsFile; + private FileConfiguration blockedCommandsConfig; + + // Felder für Executor-Instanzen + private LockSystem lockSystem; + private PluginCommand pluginCommand; + // ------------------- Tablist Config ------------------- public void reloadTablistConfig() { // Lädt die tablist.yml aus dem Plugin-Ordner neu @@ -132,6 +141,38 @@ public class SurvivalPlus extends JavaPlugin { return tablistConfig; } + public void reloadBlockedCommandsConfig() { + if (blockedCommandsFile == null) blockedCommandsFile = new File(getDataFolder(), "blockedcommands.yml"); + if (!blockedCommandsFile.exists()) { + try { + saveResource("blockedcommands.yml", false); + } catch (IllegalArgumentException e) { + getLogger().warning("Die Ressource 'blockedcommands.yml' wurde nicht gefunden. Erstelle eine leere Konfiguration."); + blockedCommandsConfig = new YamlConfiguration(); + blockedCommandsConfig.createSection("blocked-commands"); + try { + blockedCommandsConfig.save(blockedCommandsFile); + } catch (IOException ex) { + getLogger().log(Level.SEVERE, "Fehler beim Speichern der blockedcommands.yml", ex); + } + return; + } + } + blockedCommandsConfig = YamlConfiguration.loadConfiguration(blockedCommandsFile); + } + + public FileConfiguration getBlockedCommandsConfig() { + if (blockedCommandsConfig == null) { + reloadBlockedCommandsConfig(); + } + return blockedCommandsConfig; + } + + public void saveBlockedCommandsConfig() { + try { + blockedCommandsConfig.save(blockedCommandsFile); + } catch (IOException ignored) {} + } @Override public void onEnable() { @@ -164,6 +205,7 @@ public void onEnable() { createLeashesFile(); createMobCapFile(); createNicknamesFile(); + reloadBlockedCommandsConfig(); // PluginManager holen (vor Listener-Registrierung!) PluginManager pluginManager = getServer().getPluginManager(); @@ -196,6 +238,10 @@ public void onEnable() { getCommand("day").setExecutor(new DayCommand(this)); getCommand("night").setExecutor(new NightCommand(this)); + CommandBlocker commandBlocker = new CommandBlocker(this); + pluginCommand = new PluginCommand(this); + getCommand("sp").setExecutor(pluginCommand); + // TradeManager und ReportManager initialisieren TradeManager tradeManager = new TradeManager(this); ReportManager reportManager = new ReportManager(this); @@ -262,6 +308,7 @@ public void onEnable() { getCommand("startchallenge").setExecutor(new StartFunChallengeCommand(this, funChallengeManager)); getCommand("kit").setExecutor(new KitCommand(this)); getCommand("heal").setExecutor(new HealCommand(this)); + getCommand("sp").setExecutor(commandBlocker); // LootChestManager + Befehle LootChestManager lootChestManager = new LootChestManager(this); @@ -298,10 +345,30 @@ public void onEnable() { pluginManager.registerEvents(new ChallengeSmeltListener(funChallengeManager), this); pluginManager.registerEvents(new BlockDetectionListener(this), this); - LockSystem lockSystem = new LockSystem(this); + lockSystem = new LockSystem(this); pluginManager.registerEvents(lockSystem, this); getCommand("sp").setExecutor(lockSystem); + // Kombinierter Executor für /sp, um alle Subcommands zu handhaben + getCommand("sp").setExecutor(new CommandExecutor() { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!command.getName().equalsIgnoreCase("sp")) { + return false; + } + if (args.length == 0) { + return pluginCommand.onCommand(sender, command, label, args); + } + String subCommand = args[0].toLowerCase(); + if (subCommand.equals("cb")) { + return commandBlocker.onCommand(sender, command, label, args); + } else if (subCommand.equals("lock") || subCommand.equals("unlock") || + subCommand.equals("friendadd") || subCommand.equals("friendremove")) { + return lockSystem.onCommand(sender, command, label, args); + } + return pluginCommand.onCommand(sender, command, label, args); + } + }); pluginManager.registerEvents(new RepairSignListener(getConfig(), getLangConfig()), this); pluginManager.registerEvents(new ToolUpgradeListener(this), this); diff --git a/src/main/resources/blockedcommands.yml b/src/main/resources/blockedcommands.yml new file mode 100644 index 0000000..e2a92c2 --- /dev/null +++ b/src/main/resources/blockedcommands.yml @@ -0,0 +1,4 @@ +blocked-commands: + - op + - ban + - kick \ No newline at end of file diff --git a/src/main/resources/help.yml b/src/main/resources/help.yml index 36b687a..2939797 100644 --- a/src/main/resources/help.yml +++ b/src/main/resources/help.yml @@ -3,17 +3,57 @@ footer: "&6===========================" commands: gm: - description: "&eWechselt den Spielmodus (survival, creative, adventure, spectator)." - usage: "&b/gm [spieler]" + description: "&eÄndert den Spielmodus eines Spielers (survival, creative, adventure, spectator)." + usage: "&b/gm [spieler]" sp: description: "&eHauptbefehl für SurvivalPlus mit Unterbefehlen." - usage: "&b/sp " + usage: "&b/sp [reload | help | info | share | lock]" - share: - description: "&eTeilt deine aktuellen Koordinaten nach Bestätigung mit allen Spielern." + sp_reload: + description: "&eLädt das Plugin neu." + usage: "&b/sp reload" + + sp_help: + description: "&eZeigt die Hilfe für SurvivalPlus-Befehle an." + usage: "&b/sp help" + + sp_info: + description: "&eZeigt Informationen über das Plugin an." + usage: "&b/sp info" + + sp_share: + description: "&eTeilt deine Koordinaten nach Bestätigung mit allen Spielern." usage: "&b/sp share" + sp_cb_add: + description: "&eFügt einen Befehl zur Blockierliste hinzu." + usage: "&b/sp cb add " + + sp_cb_remove: + description: "&eEntfernt einen Befehl aus der Blockierliste." + usage: "&b/sp cb remove " + + sp_cb_list: + description: "&eZeigt die Liste der blockierten Befehle an." + usage: "&b/sp cb list" + + sp_lock_lock: + description: "&eSperrt einen Container (z.B. Kiste oder Tür)." + usage: "&b/sp lock " + + sp_lock_unlock: + description: "&eEntsperrt einen Container (z.B. Kiste oder Tür)." + usage: "&b/sp lock " + + sp_lock_friendadd: + description: "&eFügt einen Freund zum Container-Sperrsystem hinzu." + usage: "&b/sp lock friendadd " + + sp_lock_friendremove: + description: "&eEntfernt einen Freund aus dem Container-Sperrsystem." + usage: "&b/sp lock friendremove " + shareconfirm: description: "&eBestätigt das Teilen deiner Koordinaten mit allen Spielern." usage: "&b/sp shareconfirm" @@ -23,71 +63,90 @@ commands: usage: "&b/sp sharecancel" sethome: - description: "&eSetzt einen neuen Homepunkt." - usage: "&b/sethome " + description: "&eSetzt ein Home mit dem angegebenen Namen." + usage: "&b/sethome " delhome: - description: "&eLöscht einen Homepunkt." - usage: "&b/delhome " + description: "&eLöscht ein Home mit dem angegebenen Namen." + usage: "&b/delhome " homelist: - description: "&eZeigt alle deine Homes." + description: "&eÖffnet eine GUI mit allen Homes." usage: "&b/homelist" home: - description: "&eTeleportiert dich zu einem gespeicherten Home." - usage: "&b/home " + description: "&eTeleportiert zu einem Home." + usage: "&b/home " inv: - description: "&eÖffnet dein Inventar oder das eines anderen Spielers." - usage: "&b/inv " + description: "&eÖffnet das Inventar (eigenes oder das eines anderen Spielers)." + usage: "&b/inv [spieler]" ec: - description: "&eÖffnet deine Endertruhe oder die eines anderen Spielers." + description: "&eÖffnet die Endertruhe (eigene oder die eines anderen Spielers)." usage: "&b/ec [spieler]" - setspawn: - description: "&eSetzt den Spawnpunkt der Welt." - usage: "&b/setspawn" - setworldspawn: - description: "&eSetzt den globalen Weltspawnpunkt." + description: "&eSetzt den Weltspawnpunkt auf die Position des Spielers." usage: "&b/setworldspawn" + setspawn: + description: "&eSetzt den Server-Spawnpunkt auf die Position des Spielers." + usage: "&b/setspawn" + clearchat: description: "&eLöscht den Chat für alle Spieler." usage: "&b/clearchat" clearitems: - description: "&eEntfernt alle Items auf dem Boden." + description: "&eLöscht alle herumliegenden Items." usage: "&b/clearitems" closedoors: description: "&eSchließt alle Türen im angegebenen Radius." - usage: "&b/closedoors " + usage: "&b/closedoors " sit: - description: "&eSetzt dich hin oder steht wieder auf." + description: "&eLässt den Spieler sich hinsetzen oder aufstehen." usage: "&b/sit" back: - description: "&eTeleportiert dich zurück zum letzten Todespunkt." + description: "&eTeleportiert zum letzten Todespunkt." usage: "&b/back" friend: - description: "&eVerwalte deine Freundesliste (hinzufügen, entfernen, anzeigen, teleportieren). Unterstützt anklickbare Anfragen und Bestätigungen." - usage: "&b/friend [Spieler]" + description: "&eVerwaltet die Freundesliste (hinzufügen, entfernen, anzeigen, teleportieren)." + usage: "&b/friend [add | accept | deny | list | del | tp] [Spieler]" + subcommands: + add: + description: "&eFügt einen Spieler zur Freundesliste hinzu." + usage: "&b/friend add " + accept: + description: "&eAkzeptiert eine Freundschaftsanfrage." + usage: "&b/friend accept " + deny: + description: "&eLehnt eine Freundschaftsanfrage ab." + usage: "&b/friend deny " + list: + description: "&eZeigt die Freundesliste an." + usage: "&b/friend list" + del: + description: "&eEntfernt einen Spieler aus der Freundesliste." + usage: "&b/friend del " + tp: + description: "&eTeleportiert dich zu einem Freund." + usage: "&b/friend tp " ir: - description: "&eBenennt Items um." - usage: "&b/ir " + description: "&eBenennt das Item in der Hand um." + usage: "&b/ir " showarmorstands: - description: "&eZeigt unsichtbare ArmorStands an." + description: "&eMacht alle unsichtbaren Armor Stands sichtbar." usage: "&b/showarmorstands" cleardebugarmorstands: - description: "&eLöscht alle Debug ArmorStands." + description: "&eEntfernt alle Debug-ArmorStands." usage: "&b/cleardebugarmorstands" trash: @@ -95,76 +154,72 @@ commands: usage: "&b/trash" workbench: - description: "&eÖffnet eine Werkbank GUI." + description: "&eÖffnet eine Werkbank-GUI." usage: "&b/workbench" anvil: - description: "&eÖffnet eine Amboss GUI." + description: "&eÖffnet eine Amboss-GUI." usage: "&b/anvil" stats: - description: "&eZeigt deine persönlichen Statistiken an." + description: "&eZeigt deine Statistiken an." usage: "&b/stats" spawn: - description: "&eTeleportiert dich zum Welt-Spawnpunkt." + description: "&eTeleportiert dich zum Weltspawnpunkt." usage: "&b/spawn" - lock: - description: "&eSchützt Container mit dem LockSystem." - usage: "&b/lock [Spieler]" - tp: - description: "&eTeleportiert dich zu einem anderen Spieler." - usage: "&b/tp " + description: "&eTeleportiert dich zu einem Spieler." + usage: "&b/tp " tphere: description: "&eTeleportiert einen Spieler zu dir." - usage: "&b/tphere " + usage: "&b/tphere " tpa: - description: "&eSendet eine Teleport-Anfrage an einen Spieler." - usage: "&b/tpa " + description: "&eSendet eine Teleportanfrage an einen Spieler." + usage: "&b/tpa " tpaccept: - description: "&eAkzeptiert eine Teleport-Anfrage." + description: "&eAkzeptiert eine Teleportanfrage." usage: "&b/tpaccept" tpdeny: - description: "&eLehnt eine Teleport-Anfrage ab." + description: "&eLehnt eine Teleportanfrage ab." usage: "&b/tpdeny" block: - description: "&eBlockiert Nachrichten eines Spielers." - usage: "&b/block " + description: "&eBlockiert einen Spieler." + usage: "&b/block " unblock: - description: "&eHebt eine Blockierung auf." - usage: "&b/unblock " + description: "&eEntblockt einen Spieler." + usage: "&b/unblock " blocklist: - description: "&eZeigt eine Liste blockierter Spieler." + description: "&eZeigt eine Liste der blockierten Spieler." usage: "&b/blocklist" kit: - description: "&eErhalte dein Starterkit." + description: "&eHolt das Starterkit." usage: "&b/kit" leashcount: - description: "&eZeigt die Anzahl der angeleinten Tiere an." + description: "&eZeigt die Anzahl der geleinten Tiere an." usage: "&b/leashcount" nick: - description: "&eÄndert deinen angezeigten Namen mit Farben (&) und Hex-Farben (#RRGGBB)." - usage: "&b/nick " + description: "&eÄndert deinen Nicknamen mit Farb- und Hex-Support." + usage: "&b/nick " - trade: - description: "&eStartet einen Handel mit einem Spieler." - usage: "&b/trade " + lootchests: + description: "&eZeigt eine Liste aller aktiven Loot-Kisten an. Admins können per Klick teleportieren." + usage: "&b/lootchests" - tradeaccept: - description: "&eAkzeptiert eine Handelsanfrage." - usage: "&b/tradeaccept " + tploot: + description: "&eTeleportiert dich zu einer Loot-Kiste (nur Admins)." + usage: "&b/tploot " day: description: "&eSetzt die Zeit auf Tag." @@ -174,33 +229,61 @@ commands: description: "&eSetzt die Zeit auf Nacht." usage: "&b/night" + trade: + description: "&eStartet einen Handel mit einem Spieler." + usage: "&b/trade " + + tradeaccept: + description: "&eAkzeptiert eine Handelsanfrage." + usage: "&b/tradeaccept " + report: description: "&eMeldet einen Spieler an die Admins." - usage: "&b/report [Grund]" + usage: "&b/report [Grund]" showreport: description: "&eZeigt alle Reports eines Spielers an." - usage: "&b/showreport " + usage: "&b/showreport " clearreport: description: "&eLöscht alle Reports eines Spielers." - usage: "&b/clearreport " + usage: "&b/clearreport " shop: description: "&eVerwaltet den Server-Shop (z.B. Items hinzufügen)." - usage: "&b/shop add " + usage: "&b/shop add " + + setwarp: + description: "&eSetzt einen persönlichen Warp mit dem Item in der Hand." + usage: "&b/setwarp " + + delwarp: + description: "&eLöscht einen persönlichen Warp." + usage: "&b/delwarp " + + warps: + description: "&eÖffnet die GUI mit allen Spieler-Warps." + usage: "&b/warps" + + startchallenge: + description: "&eStartet eine Fun-Challenge." + usage: "&b/startchallenge " + + heal: + description: "&eHeilt einen Spieler vollständig." + usage: "&b/heal [spieler]" messages: header: "&6=== Befehle ===" footer: "&6================" navigation: - prev: "&7« Vorherige " - next: "&7 Nächste »" - prev-disabled: "&8« " - next-disabled: "&8 »" - page: "&fSeite {current} von {total} " + prev: "&7« Vorherige Seite" + next: "&7Nächste Seite »" + prev-disabled: "&8« Vorherige Seite" + next-disabled: "&8Nächste Seite »" + page: "&fSeite {current} von {total}" sp: - invalid-subcommand: "&cUngültiger Unterbefehl! Verwendung: /sp [reload|help|info|share]" + invalid-subcommand: "&cUngültiger Unterbefehl! Verwendung: /sp [reload|help|info|share|lock]" no-permission: "&cDu hast keine Berechtigung für diesen Befehl!" plugin: reloaded: "&aSurvivalPlus wurde erfolgreich neu geladen!" @@ -215,9 +298,9 @@ messages: preview-title: "&aDeine aktuellen Koordinaten wären:" preview-format: "&e%player% &7teilt Koordinaten: &eX: %x%, Y: %y%, Z: %z% &7in Welt &e%world%" send-button: "&a[✅ Senden]" - cancel-button: "&c [❌ Abbrechen]" + cancel-button: "&c[❌ Abbrechen]" send-hover: "&aKlicke, um deine Koordinaten an alle zu senden." cancel-hover: "&cKlicke, um das Senden abzubrechen." sent: "&aKoordinaten gesendet." cancelled: "&eSenden der Koordinaten abgebrochen." - help-not-found: "&cHilfedatei (help.yml) konnte nicht geladen werden!" + help-not-found: "&cHilfedatei (help.yml) konnte nicht geladen werden!" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 84ee1af..f8cad79 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: SurvivalPlus -version: 1.0.5 +version: 1.0.7 main: de.viper.survivalplus.SurvivalPlus api-version: 1.21 softdepend: [LuckPerms, PlaceholderAPI] @@ -7,284 +7,272 @@ author: Viper description: A plugin for enhancing survival gameplay in Minecraft. commands: + sp: + description: Hauptbefehl für SurvivalPlus (Command-Blocker, Reload, Info, etc.) + usage: / [cb add|cb remove|cb list|reload|help|info|share] [args] + permission: survivalplus.sp + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." ir: description: Benennt das Item in der Hand um. - usage: /ir + usage: / permission: survivalplus.itemrename permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - gm: description: Ändert den Spielmodus eines Spielers usage: / [spieler] aliases: [gamemode] permission: survivalplus.gamemode - - sp: - description: Zeigt Plugin-Informationen oder führt weitere Befehle aus - usage: / [reload|help|info|share] [seite] - permission: survivalplus.sp - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." sethome: description: Setzt ein Home mit dem angegebenen Namen usage: / permission: survivalplus.homes.set - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." delhome: description: Löscht ein Home mit dem angegebenen Namen usage: / permission: survivalplus.homes.delete - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." homelist: description: Öffnet eine GUI mit allen Homes usage: / permission: survivalplus.homes.list - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." home: description: Teleportiert zu einem Home usage: / permission: survivalplus.homes - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." inv: description: Öffnet das Inventar (eigenes oder das eines anderen Spielers) usage: / [spieler] permission: survivalplus.inventory.own - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." ec: description: Öffnet die Endertruhe (eigene oder die eines anderen Spielers) usage: / [spieler] permission: survivalplus.enderchest.own - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." setworldspawn: description: Setzt den Weltspawnpunkt auf die Position des Spielers usage: / permission: survivalplus.setworldspawn - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." setspawn: description: Setzt den Server-Spawnpunkt auf die Position des Spielers usage: / permission: survivalplus.setspawn - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." clearchat: description: Löscht den Chat für alle Spieler usage: / permission: survivalplus.clearchat - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." clearitems: description: Löscht alle herumliegenden Items usage: / permission: survivalplus.clearitems - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." closedoors: description: Schließt alle Türen im angegebenen Radius usage: / permission: survivalplus.closedoors - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." sit: description: Lässt den Spieler sich hinsetzen usage: / permission: survivalplus.sit - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." back: description: Teleportiert zum letzten Todespunkt usage: / permission: survivalplus.back - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." friend: description: Verwaltet die Freundesliste usage: / [add|accept|deny|list|del|tp] [Spielername] permission: survivalplus.friend - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." stats: description: Zeigt deine Statistiken an - usage: /stats + usage: / permission: survivalplus.stats - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." showarmorstands: description: Macht alle unsichtbaren Armor Stands sichtbar. - usage: /showarmorstands + usage: / permission: survivalplus.showarmorstands permission-message: "§cDu hast keine Rechte für diesen Befehl." - cleardebugarmorstands: description: Entfernt alle Debug-ArmorStands - usage: /cleardebugarmorstands + usage: / permission: survivalplus.cleardebugarmorstands permission-message: "§cDu hast keine Rechte für diesen Befehl." - trash: description: Öffnet den Mülleimer - usage: /trash + usage: / permission: survivalplus.trash permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - workbench: description: Öffnet eine Werkbank GUI - usage: /workbench + usage: / permission: survivalplus.workbench permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - anvil: description: Öffnet eine Amboss GUI - usage: /anvil + usage: / permission: survivalplus.anvil permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - leashcount: description: Zeigt die Anzahl der geleinten Tiere an. - usage: /leashcount + usage: / permission: survivalplus.leashcount permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - splock: description: Verwaltet das Sperrsystem für Kisten und Türen - usage: /sp lock|unlock|friendadd|friendremove [Spieler] + usage: / lock|unlock|friendadd|friendremove [Spieler] permission: survivalplus.lock permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - tp: description: Teleportiere dich zu einem Spieler - usage: /tp - + usage: / + permission: survivalplus.tp + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." tphere: description: Teleportiere einen Spieler zu dir - usage: /tphere - + usage: / + permission: survivalplus.tphere + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." tpa: description: Sende eine Teleportanfrage an einen Spieler - usage: /tpa - + usage: / + permission: survivalplus.tpa + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." tpaccept: description: Akzeptiere eine Teleportanfrage - usage: /tpaccept - + usage: / + permission: survivalplus.tpaccept + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." tpdeny: description: Lehne eine Teleportanfrage ab - usage: /tpdeny - + usage: / + permission: survivalplus.tpdeny + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." block: description: Blockiere einen Spieler - usage: /block + usage: / permission: survivalplus.block - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." unblock: description: Entblocke einen Spieler - usage: /unblock - permission: survivalplus.unlock - + usage: / + permission: survivalplus.unblock + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." blocklist: description: Zeige eine Liste der blockierten Spieler - usage: /blocklist + usage: / permission: survivalplus.blocklist - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." kit: description: Hol dir das Starterkit! - usage: /kit + usage: / permission: survivalplus.kit - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." nick: description: Ändert deinen Nicknamen mit Farb- und Hex-Support. - usage: /nick + usage: / permission: survivalplus.nick permission-message: "§cDu hast keine Berechtigung, deinen Nick zu ändern!" - lootchests: description: Zeigt eine Liste aller aktiven Loot-Kisten an. Admins können per Klick zu einer Kiste teleportieren. - usage: /lootchests + usage: / permission: survivalplus.lootchests permission-message: "§cDu hast keine Berechtigung für diesen Befehl!" - tploot: description: Teleportiere dich zu einer Loot-Kiste (nur Admins) - usage: /tploot + usage: / permission: survivalplus.lootchests permission-message: "§cDu hast keine Berechtigung für diesen Befehl!" - day: description: Setzt die Zeit auf Tag - usage: /day + usage: / permission: survivalplus.day - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." night: description: Setzt die Zeit auf Nacht - usage: /night + usage: / permission: survivalplus.night - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." trade: description: Startet einen Handel mit einem Spieler - usage: /trade + usage: / permission: survivalplus.trade - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." tradeaccept: description: Akzeptiert eine Handelsanfrage - usage: /tradeaccept + usage: / permission: survivalplus.tradeaccept - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." report: description: Meldet einen Spieler an die Admins - usage: /report [Grund] + usage: / [Grund] permission: survivalplus.report - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." showreport: description: Zeigt alle Reports eines Spielers an - usage: /showreport + usage: / permission: survivalplus.report.show - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." clearreport: description: Löscht alle Reports eines Spielers - usage: /clearreport + usage: / permission: survivalplus.report.clear - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." shop: description: Verwalten des Server-Shops (z.B. Items hinzufügen) - usage: /shop add + usage: / add permission: survivalplus.shop - permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." spawn: description: Teleportiert dich zum Weltspawnpunkt. - usage: /spawn + usage: / permission: survivalplus.spawn - permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." setwarp: description: Setzt einen persönlichen Warp mit dem Item in der Hand. - usage: /setwarp + usage: / permission: survivalplus.setwarp permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - delwarp: - description: Löscht einen persönlichen Warp . - usage: /delwarp + description: Löscht einen persönlichen Warp. + usage: / permission: survivalplus.delwarp permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - warps: description: Öffnet die GUI mit allen Spieler-Warps. - usage: /warps + usage: / permission: survivalplus.warps - permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." startchallenge: description: Startet eine Fun-Challenge - usage: /startchallenge + usage: / permission: survivalplus.startchallenge - permission-message: "§cDu hast keine Berechtigung für diesen Befehl." - + permission-message: "§cDu hast keine Berechtigung für diesen Befehl." heal: description: Heilt einen Spieler vollständig - usage: /heal [spieler] + usage: / [spieler] permission: survivalplus.heal - permission-message: "§cDu hast keine Berechtigung, Spieler zu heilen!" - - survivalplus.notify: - description: Erhält Benachrichtigungen, wenn ein Spieler einen Command- oder Structure-Block besitzt - default: op + permission-message: "§cDu hast keine Berechtigung, Spieler zu heilen!" permissions: survivalplus.*: description: Gibt Zugriff auf alle SurvivalPlus-Befehle default: op children: + survivalplus.commandblocker.add: true + survivalplus.commandblocker.remove: true + survivalplus.commandblocker.list: true + survivalplus.commandblocker.bypass: true survivalplus.gamemode: true survivalplus.gamemode.others: true survivalplus.sp: true @@ -315,194 +303,221 @@ permissions: survivalplus.workbench: true survivalplus.anvil: true survivalplus.leashcount: true + survivalplus.lock: true + survivalplus.tp: true + survivalplus.tphere: true + survivalplus.tpa: true + survivalplus.tpaccept: true + survivalplus.tpdeny: true + survivalplus.block: true + survivalplus.unblock: true + survivalplus.blocklist: true + survivalplus.kit: true survivalplus.nick: true survivalplus.lootchests: true + survivalplus.day: true + survivalplus.night: true + survivalplus.trade: true + survivalplus.tradeaccept: true + survivalplus.report: true + survivalplus.report.show: true + survivalplus.report.clear: true + survivalplus.shop: true + survivalplus.spawn: true + survivalplus.setwarp: true + survivalplus.delwarp: true + survivalplus.warps: true survivalplus.startchallenge: true survivalplus.heal: true survivalplus.heal.others: true survivalplus.notify: true - - survivalplus.lootchests: - description: Erlaubt das Verwalten und Teleportieren zu Loot-Kisten + survivalplus.chunkanimals: true + survivalplus.commandblocker.add: + description: Erlaubt das Hinzufügen von Befehlen zur Blockierliste + default: op + survivalplus.commandblocker.remove: + description: Erlaubt das Entfernen von Befehlen aus der Blockierliste + default: op + survivalplus.commandblocker.list: + description: Erlaubt das Anzeigen der Blockierliste + default: op + survivalplus.commandblocker.bypass: + description: Erlaubt das Umgehen blockierter Befehle default: op - survivalplus.gamemode: description: Erlaubt das Ändern des eigenen Spielmodus default: op - survivalplus.gamemode.others: description: Erlaubt das Ändern des Spielmodus anderer Spieler default: op - survivalplus.sp: description: Erlaubt den Zugriff auf den /sp-Befehl default: op - survivalplus.share: description: Erlaubt das Teilen der eigenen Koordinaten mit /sp share default: true - survivalplus.homes.set: description: Erlaubt das Setzen von Homes default: true - survivalplus.homes.delete: description: Erlaubt das Löschen von Homes default: true - survivalplus.homes.list: description: Erlaubt das Öffnen der Home-Liste GUI default: true - survivalplus.homes: description: Erlaubt das Teleportieren zu Homes default: true - survivalplus.homes.unlimited: description: Erlaubt unbegrenzte Homes default: op - survivalplus.inventory.own: description: Erlaubt das Ansehen des eigenen Inventars default: true - survivalplus.inventory.others: description: Erlaubt das Ansehen des Inventars anderer Spieler default: op - survivalplus.enderchest.own: description: Erlaubt das Ansehen der eigenen Endertruhe default: true - survivalplus.enderchest.others: description: Erlaubt das Ansehen der Endertruhen anderer Spieler default: op - survivalplus.setworldspawn: description: Erlaubt das Setzen des Weltspawnpunkts default: op - survivalplus.setspawn: description: Erlaubt das Setzen des Server-Spawnpunkts default: op - survivalplus.clearchat: description: Erlaubt das Löschen des Chats default: op - survivalplus.clearitems: description: Erlaubt das manuelle Löschen der herumliegenden Items default: op - survivalplus.closedoors: description: Erlaubt das Schließen von Türen mit /closedoors default: op - survivalplus.sit: description: Erlaubt das Sitzen auf Treppen oder mit /sit default: true - - survivalplus.graves: - description: Erlaubt das Erstellen von Gräbern bei Tod - default: true - survivalplus.back: description: Erlaubt das Teleportieren zum letzten Todespunkt default: true - + survivalplus.graves: + description: Erlaubt das Erstellen von Gräbern bei Tod + default: true survivalplus.friend: description: Erlaubt die Verwaltung der Freundesliste default: true - survivalplus.itemrename: description: Erlaubt das Umbenennen von Items mit /ir default: true - survivalplus.stats: description: Erlaubt den Zugriff auf den /stats-Befehl default: true - survivalplus.showarmorstands: description: Erlaubt das Sichtbarmachen von Armor Stands mit /showarmorstands default: op - survivalplus.cleardebugarmorstands: description: Erlaubt das Entfernen von Debug-ArmorStands default: op - survivalplus.trash: description: Erlaubt die Nutzung von /trash default: true - survivalplus.workbench: description: Erlaubt die Nutzung von /workbench default: true - survivalplus.anvil: description: Erlaubt die Nutzung von /anvil default: true - survivalplus.leashcount: description: Erlaubt die Nutzung von /leashcount default: true - - survivalplus.chunkanimals: - description: Erlaubt das Anzeigen der Anzahl der Tiere im aktuellen Chunk - default: op - survivalplus.lock: description: Erlaubt das Verwenden von /lock-Befehlen default: true - survivalplus.tp: - description: Erlaube das Teleportieren zu anderen Spielern + description: Erlaubt das Teleportieren zu anderen Spielern default: op - survivalplus.tphere: - description: Erlaube das Teleportieren anderer Spieler zu dir + description: Erlaubt das Teleportieren anderer Spieler zu dir default: op - survivalplus.tpa: - description: Erlaube das Senden von Teleportanfragen + description: Erlaubt das Senden von Teleportanfragen default: true - survivalplus.tpaccept: - description: Erlaube das Annehmen von Teleportanfragen + description: Erlaubt das Annehmen von Teleportanfragen default: true - survivalplus.tpdeny: - description: Erlaube das Ablehnen von Teleportanfragen + description: Erlaubt das Ablehnen von Teleportanfragen default: true - survivalplus.block: description: Erlaubt das Blockieren anderer Spieler im Chat default: true - - survivalplus.info: - description: Erlaubt den Zugriff auf /sp info + survivalplus.unblock: + description: Erlaubt das Entblocken anderer Spieler im Chat + default: true + survivalplus.blocklist: + description: Erlaubt das Anzeigen der blockierten Spieler + default: true + survivalplus.kit: + description: Erlaubt das Abrufen des Starterkits default: true - survivalplus.nick: - description: Erlaubt es, den eigenen Nicknamen zu ändern (mit Farben & Hex) + description: Erlaubt das Ändern des eigenen Nicknamens (mit Farben & Hex) + default: op + survivalplus.lootchests: + description: Erlaubt das Verwalten und Teleportieren zu Loot-Kisten + default: op + survivalplus.day: + description: Erlaubt das Setzen der Zeit auf Tag + default: op + survivalplus.night: + description: Erlaubt das Setzen der Zeit auf Nacht + default: op + survivalplus.trade: + description: Erlaubt das Starten eines Handels + default: true + survivalplus.tradeaccept: + description: Erlaubt das Akzeptieren eines Handels + default: true + survivalplus.report: + description: Erlaubt das Melden von Spielern + default: true + survivalplus.report.show: + description: Erlaubt das Anzeigen von Spieler-Reports + default: op + survivalplus.report.clear: + description: Erlaubt das Löschen von Spieler-Reports default: op - survivalplus.shop: description: Erlaubt die Nutzung des Shop-Befehls default: op - survivalplus.spawn: description: Erlaubt die Nutzung des /spawn Befehls default: true - survivalplus.setwarp: description: Erlaubt das Setzen von persönlichen Warps default: true - + survivalplus.delwarp: + description: Erlaubt das Löschen von persönlichen Warps + default: true survivalplus.warps: description: Erlaubt das Öffnen der Warps-GUI default: true - - delwarp: - description: Erlaubt das Löschen von persönlichen Warps - default: true - \ No newline at end of file + survivalplus.startchallenge: + description: Erlaubt das Starten von Fun-Challenges + default: op + survivalplus.heal: + description: Erlaubt das Heilen des eigenen Spielers + default: op + survivalplus.heal.others: + description: Erlaubt das Heilen anderer Spieler + default: op + survivalplus.notify: + description: Erhält Benachrichtigungen, wenn ein Spieler einen Command- oder Structure-Block besitzt + default: op + survivalplus.chunkanimals: + description: Erlaubt das Anzeigen der Anzahl der Tiere im aktuellen Chunk + default: op \ No newline at end of file