diff --git a/src/main/java/de/viper/survivalplus/commands/AnvilCommand.java b/src/main/java/de/viper/survivalplus/commands/AnvilCommand.java new file mode 100644 index 0000000..6500d49 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/AnvilCommand.java @@ -0,0 +1,24 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; + +public class AnvilCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage("Nur Spieler können diesen Befehl ausführen."); + return true; + } + + Inventory anvil = Bukkit.createInventory(player, InventoryType.ANVIL, "Amboss"); + player.openInventory(anvil); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/BackCommand.java b/src/main/java/de/viper/survivalplus/commands/BackCommand.java new file mode 100644 index 0000000..fd8346a --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/BackCommand.java @@ -0,0 +1,66 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.configuration.file.FileConfiguration; + +public class BackCommand implements CommandExecutor { + private final SurvivalPlus plugin; + + public BackCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getLangConfig().getString("player-only", "§cDieser Befehl ist nur für Spieler!")); + return true; + } + + Player player = (Player) sender; + FileConfiguration lang = plugin.getLangConfig(); + FileConfiguration gravesConfig = plugin.getGravesConfig(); + + if (!player.hasPermission("survivalplus.back")) { + player.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + if (args.length != 0) { + player.sendMessage(lang.getString("back.usage", "§cVerwendung: /back")); + return true; + } + + // Lade Todesposition + String path = "graves." + player.getUniqueId(); + if (!gravesConfig.contains(path)) { + player.sendMessage(lang.getString("back.no-death-point", "§cDu hast keinen Todespunkt!")); + return true; + } + + String worldName = gravesConfig.getString(path + ".world"); + double x = gravesConfig.getDouble(path + ".x"); + double y = gravesConfig.getDouble(path + ".y"); + double z = gravesConfig.getDouble(path + ".z"); + + World world = plugin.getServer().getWorld(worldName); + if (world == null) { + player.sendMessage(lang.getString("back.no-death-point", "§cDu hast keinen Todespunkt!")); + return true; + } + + Location location = new Location(world, x, y, z); + player.teleport(location); + player.sendMessage(String.format( + lang.getString("back.success", "§aTeleportiert zum Todespunkt bei x=%.2f, y=%.2f, z=%.2f!"), + x, y, z + )); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/commands/ClearChatCommand.java b/src/main/java/de/viper/survivalplus/commands/ClearChatCommand.java new file mode 100644 index 0000000..9b8bc1a --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/ClearChatCommand.java @@ -0,0 +1,26 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class ClearChatCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!sender.hasPermission("survivalplus.clearchat")) { + sender.sendMessage("§cDu hast keine Rechte, den Chat zu löschen."); + return true; + } + + // Chat für alle "leeren" (100 leere Zeilen senden) + for (int i = 0; i < 100; i++) { + Bukkit.broadcastMessage(" "); + } + + Bukkit.broadcastMessage("§aDer Chat wurde von §e" + sender.getName() + " §agelöscht."); + + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/ClearDebugArmorStandsCommand.java b/src/main/java/de/viper/survivalplus/commands/ClearDebugArmorStandsCommand.java new file mode 100644 index 0000000..2c4a82b --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/ClearDebugArmorStandsCommand.java @@ -0,0 +1,43 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class ClearDebugArmorStandsCommand implements CommandExecutor { + + private final SurvivalPlus plugin; + + public ClearDebugArmorStandsCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("Dieser Befehl kann nur von einem Spieler ausgeführt werden."); + return true; + } + + Player player = (Player) sender; + int removedCount = 0; + + for (Entity entity : player.getWorld().getEntities()) { + if (entity instanceof ArmorStand) { + ArmorStand armorStand = (ArmorStand) entity; + armorStand.setInvulnerable(false); + armorStand.setMarker(false); + armorStand.setGravity(true); + armorStand.remove(); + removedCount++; + } + } + + player.sendMessage("Es wurden " + removedCount + " ArmorStands entfernt."); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/ClearItemsCommand.java b/src/main/java/de/viper/survivalplus/commands/ClearItemsCommand.java new file mode 100644 index 0000000..176a0e2 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/ClearItemsCommand.java @@ -0,0 +1,32 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Item; + +public class ClearItemsCommand implements CommandExecutor { + + private final SurvivalPlus plugin; + + public ClearItemsCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + int totalRemoved = 0; + for (World world : Bukkit.getWorlds()) { + for (Item item : world.getEntitiesByClass(Item.class)) { + item.remove(); + totalRemoved++; + } + } + sender.sendMessage(ChatColor.RED + "Alle Items wurden entfernt (" + totalRemoved + " Stück)."); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/CloseDoorsCommand.java b/src/main/java/de/viper/survivalplus/commands/CloseDoorsCommand.java new file mode 100644 index 0000000..33a8fa7 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/CloseDoorsCommand.java @@ -0,0 +1,88 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.Openable; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import de.viper.survivalplus.SurvivalPlus; + +public class CloseDoorsCommand implements CommandExecutor { + + private final SurvivalPlus plugin; + + public CloseDoorsCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage(plugin.getLangConfig().getString("commands.closedoors.noplayer", "Nur Spieler können diesen Befehl nutzen!")); + return true; + } + + if (!player.hasPermission("survivalplus.closedoors")) { + player.sendMessage(plugin.getLangConfig().getString("commands.closedoors.nopermission", "Dafür hast du keine Rechte!")); + return true; + } + + if (args.length != 1) { + player.sendMessage(plugin.getLangConfig().getString("commands.closedoors.usage", "Benutzung: /closedoors ")); + return true; + } + + int radius; + try { + radius = Integer.parseInt(args[0]); + if (radius <= 0) { + player.sendMessage(plugin.getLangConfig().getString("commands.closedoors.invalidradius", "Der Radius muss größer als 0 sein!")); + return true; + } + } catch (NumberFormatException e) { + player.sendMessage(plugin.getLangConfig().getString("commands.closedoors.invalidradius", "Der Radius muss eine Zahl sein!")); + return true; + } + + int closedCount = 0; + var center = player.getLocation().getBlock(); + + for (int x = -radius; x <= radius; x++) { + for (int y = -radius; y <= radius; y++) { + for (int z = -radius; z <= radius; z++) { + Block block = center.getRelative(x, y, z); + Material type = block.getType(); + + if (type == Material.OAK_DOOR || + type == Material.SPRUCE_DOOR || + type == Material.BIRCH_DOOR || + type == Material.JUNGLE_DOOR || + type == Material.ACACIA_DOOR || + type == Material.DARK_OAK_DOOR || + type == Material.CRIMSON_DOOR || + type == Material.WARPED_DOOR || + type == Material.IRON_DOOR) { + + var blockData = block.getBlockData(); + if (blockData instanceof Openable openable) { + if (openable.isOpen()) { + openable.setOpen(false); + block.setBlockData(openable); + closedCount++; + } + } + } + } + } + } + + player.sendMessage(plugin.getLangConfig() + .getString("commands.closedoors.success", "Es wurden %count% Türen geschlossen.") + .replace("%count%", String.valueOf(closedCount))); + + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/EnderchestCommand.java b/src/main/java/de/viper/survivalplus/commands/EnderchestCommand.java new file mode 100644 index 0000000..ebf30a0 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/EnderchestCommand.java @@ -0,0 +1,123 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.configuration.file.FileConfiguration; +import java.io.File; +import java.util.UUID; +import java.util.logging.Level; + +public class EnderchestCommand implements CommandExecutor { + private final SurvivalPlus plugin; + + public EnderchestCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getLangConfig().getString("player-only", "§cDieser Befehl ist nur für Spieler!")); + return true; + } + + Player player = (Player) sender; + FileConfiguration lang = plugin.getLangConfig(); + + if (!player.hasPermission("survivalplus.enderchest.own")) { + player.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + OfflinePlayer target; + String targetName; + + if (args.length == 0) { + // Öffne die eigene Enderchest + target = player; + targetName = player.getName(); + } else if (args.length == 1) { + // Öffne die Enderchest eines anderen Spielers + if (!player.hasPermission("survivalplus.enderchest.others")) { + player.sendMessage(lang.getString("no-permission-others-ec", "§cDu hast keine Berechtigung, die Enderchest anderer Spieler anzusehen!")); + return true; + } + targetName = args[0]; + Player onlineTarget = Bukkit.getPlayerExact(targetName); + if (onlineTarget != null) { + target = onlineTarget; + } else { + target = Bukkit.getOfflinePlayer(targetName); + if (target.getName() == null || !target.hasPlayedBefore()) { + player.sendMessage(lang.getString("player-not-found", "§cSpieler nicht gefunden!")); + return true; + } + } + } else { + player.sendMessage(lang.getString("enderchest.usage", "§cVerwendung: /ec [spieler]")); + return true; + } + + // Erstelle die GUI + Inventory gui = Bukkit.createInventory(null, 27, lang.getString("enderchest.gui-title", "Enderchest von ") + targetName); + + // Lade die Enderchest + if (target.isOnline()) { + Player onlineTarget = target.getPlayer(); + Inventory enderChest = onlineTarget.getEnderChest(); + for (int i = 0; i < 27; i++) { + gui.setItem(i, enderChest.getItem(i)); + } + plugin.getLogger().log(Level.INFO, "Enderchest für " + targetName + " (online) erfolgreich geladen"); + } else { + UUID uuid = target.getUniqueId(); + try { + // Lade Offline-Spieler-Enderchest aus playerdata + File dataFolder = new File(plugin.getServer().getWorlds().get(0).getWorldFolder(), "playerdata"); + File playerFile = new File(dataFolder, uuid.toString() + ".dat"); + + if (!playerFile.exists()) { + player.sendMessage(lang.getString("enderchest.data-not-found", "§cDie Enderchest-Daten des Spielers konnten nicht gefunden werden! Der Spieler war möglicherweise nie auf diesem Server.")); + return true; + } + + String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + plugin.getLogger().log(Level.INFO, "Versuche, Enderchest für " + targetName + " zu laden (UUID: " + uuid + ", Version: " + version + ")"); + + // Verwende Reflection, um die Enderchest-Daten zu laden + Class nbtIoClass = Class.forName("net.minecraft.nbt.NbtIo"); + Class nbtCompoundClass = Class.forName("net.minecraft.nbt.NbtCompound"); + Class nbtListClass = Class.forName("net.minecraft.nbt.NbtList"); + Class craftInventoryClass = Class.forName("org.bukkit.craftbukkit." + version + ".inventory.CraftInventory"); + + Object nbtCompound = nbtIoClass.getMethod("readCompressed", java.nio.file.Path.class).invoke(null, playerFile.toPath()); + Object enderItemsList = nbtCompoundClass.getMethod("getList", String.class, int.class).invoke(nbtCompound, "EnderItems", 10); + Object craftInventory = craftInventoryClass.getConstructor(nbtListClass).newInstance(enderItemsList); + + ItemStack[] items = (ItemStack[]) craftInventoryClass.getMethod("getContents").invoke(craftInventory); + for (int i = 0; i < Math.min(items.length, 27); i++) { + gui.setItem(i, items[i]); + } + plugin.getLogger().log(Level.INFO, "Enderchest für " + targetName + " erfolgreich geladen"); + } catch (Exception e) { + plugin.getLogger().log(Level.SEVERE, "Fehler beim Laden der Enderchest für " + targetName + " (UUID: " + uuid + ")", e); + String errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + player.sendMessage(lang.getString("enderchest.load-error", "§cFehler beim Laden der Enderchest: %error%") + .replace("%error%", errorMessage)); + return true; + } + } + + player.openInventory(gui); + player.sendMessage(lang.getString("enderchest.opened", "§aEnderchest von %player% geöffnet!") + .replace("%player%", targetName)); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/commands/FriendCommand.java b/src/main/java/de/viper/survivalplus/commands/FriendCommand.java new file mode 100644 index 0000000..92e6dbe --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/FriendCommand.java @@ -0,0 +1,343 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; + +public class FriendCommand implements CommandExecutor { + private final JavaPlugin plugin; + private final FileConfiguration friendsConfig; + private final FileConfiguration langConfig; + private final Logger logger; + + public FriendCommand(JavaPlugin plugin, FileConfiguration friendsConfig, FileConfiguration langConfig, Logger logger) { + this.plugin = plugin; + this.friendsConfig = friendsConfig; + this.langConfig = langConfig; + this.logger = logger; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.player-only", "&cDieser Befehl ist nur für Spieler!"))); + return true; + } + + Player player = (Player) sender; + UUID playerUUID = player.getUniqueId(); + + if (args.length == 0) { + sendHelpMessage(player); + return true; + } + + String subCommand = args[0].toLowerCase(); + + switch (subCommand) { + case "add": + if (args.length != 2) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.add-usage", "&cVerwendung: /friend add "))); + return true; + } + handleFriendAdd(player, args[1]); + break; + + case "accept": + if (args.length != 2) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.accept-usage", "&cVerwendung: /friend accept "))); + return true; + } + handleFriendAccept(player, args[1]); + break; + + case "deny": + if (args.length != 2) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.deny-usage", "&cVerwendung: /friend deny "))); + return true; + } + handleFriendDeny(player, args[1]); + break; + + case "list": + if (args.length != 1) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.list-usage", "&cVerwendung: /friend list"))); + return true; + } + handleFriendList(player); + break; + + case "del": + if (args.length != 2) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.del-usage", "&cVerwendung: /friend del "))); + return true; + } + handleFriendDelete(player, args[1]); + break; + + case "tp": + if (args.length != 2) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.tp-usage", "&cVerwendung: /friend tp "))); + return true; + } + handleFriendTeleport(player, args[1]); + break; + + default: + sendHelpMessage(player); + break; + } + + return true; + } + + private void sendHelpMessage(Player player) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.header", "&6=== Freundesliste Hilfe ==="))); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.add", "&e/friend add &7- Freundschaftsanfrage senden"))); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.accept", "&e/friend accept &7- Freundschaftsanfrage akzeptieren"))); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.deny", "&e/friend deny &7- Freundschaftsanfrage ablehnen"))); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.list", "&e/friend list &7- Liste deiner Freunde anzeigen"))); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.del", "&e/friend del &7- Freund aus der Liste entfernen"))); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.tp", "&e/friend tp &7- Zu einem Freund teleportieren"))); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.help.footer", "&6====================="))); + } + + private void handleFriendAdd(Player player, String targetName) { + Player target = Bukkit.getPlayerExact(targetName); + if (target == null) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.player-not-found", "&cSpieler %s nicht gefunden!").replace("%s", targetName))); + return; + } + if (target.getUniqueId().equals(player.getUniqueId())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.self", "&cDu kannst dich nicht selbst hinzufügen!"))); + return; + } + + UUID playerUUID = player.getUniqueId(); + UUID targetUUID = target.getUniqueId(); + List playerFriends = friendsConfig.getStringList(playerUUID + ".friends"); + List pendingRequests = friendsConfig.getStringList(targetUUID + ".pending_requests"); + + if (playerFriends.contains(targetUUID.toString())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.already-friends", "&cDu bist bereits mit %s befreundet!").replace("%s", targetName))); + return; + } + + if (pendingRequests.contains(playerUUID.toString())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.request-pending", "&cDu hast bereits eine Anfrage an %s gesendet!").replace("%s", targetName))); + return; + } + + pendingRequests.add(playerUUID.toString()); + friendsConfig.set(targetUUID + ".pending_requests", pendingRequests); + friendsConfig.set(targetUUID + ".name", targetName); // Speichere den Namen für Offline-Lookups + saveFriendsConfig(); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.add.sent", "&aFreundschaftsanfrage an %s gesendet!").replace("%s", targetName))); + target.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.add.received", "&aDu hast eine Freundschaftsanfrage von %s erhalten! Verwende /friend accept %s oder /friend deny %s.").replace("%s", player.getName()))); + logger.info("Freundschaftsanfrage von " + player.getName() + " an " + targetName + " gesendet."); + } + + private void handleFriendAccept(Player player, String requesterName) { + Player requester = Bukkit.getPlayerExact(requesterName); + if (requester == null) { + UUID requesterUUID = getUUIDFromName(requesterName); + if (requesterUUID == null) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.player-not-found", "&cSpieler %s nicht gefunden!").replace("%s", requesterName))); + return; + } + acceptFriendRequest(player, requesterUUID, requesterName); + } else { + acceptFriendRequest(player, requester.getUniqueId(), requesterName); + } + } + + private void acceptFriendRequest(Player player, UUID requesterUUID, String requesterName) { + UUID playerUUID = player.getUniqueId(); + List pendingRequests = friendsConfig.getStringList(playerUUID + ".pending_requests"); + + if (!pendingRequests.contains(requesterUUID.toString())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.no-request", "&cKeine Anfrage von %s gefunden!").replace("%s", requesterName))); + return; + } + + pendingRequests.remove(requesterUUID.toString()); + friendsConfig.set(playerUUID + ".pending_requests", pendingRequests); + + List playerFriends = friendsConfig.getStringList(playerUUID + ".friends"); + List requesterFriends = friendsConfig.getStringList(requesterUUID + ".friends"); + + playerFriends.add(requesterUUID.toString()); + requesterFriends.add(playerUUID.toString()); + + friendsConfig.set(playerUUID + ".friends", playerFriends); + friendsConfig.set(playerUUID + ".name", player.getName()); // Speichere den Namen für Offline-Lookups + friendsConfig.set(requesterUUID + ".friends", requesterFriends); + friendsConfig.set(requesterUUID + ".name", requesterName); // Speichere den Namen für Offline-Lookups + + saveFriendsConfig(); + + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.accept.success", "&aDu bist jetzt mit %s befreundet!").replace("%s", requesterName))); + Player requester = Bukkit.getPlayer(requesterUUID); + if (requester != null) { + requester.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.accept.notify", "&a%s hat deine Freundschaftsanfrage akzeptiert!").replace("%s", player.getName()))); + } + logger.info(player.getName() + " hat die Freundschaftsanfrage von " + requesterName + " akzeptiert."); + } + + private void handleFriendDeny(Player player, String requesterName) { + UUID requesterUUID = getUUIDFromName(requesterName); + if (requesterUUID == null) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.player-not-found", "&cSpieler %s nicht gefunden!").replace("%s", requesterName))); + return; + } + + UUID playerUUID = player.getUniqueId(); + List pendingRequests = friendsConfig.getStringList(playerUUID + ".pending_requests"); + + if (!pendingRequests.contains(requesterUUID.toString())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.no-request", "&cKeine Anfrage von %s gefunden!").replace("%s", requesterName))); + return; + } + + pendingRequests.remove(requesterUUID.toString()); + friendsConfig.set(playerUUID + ".pending_requests", pendingRequests); + saveFriendsConfig(); + + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.deny.success", "&aFreundschaftsanfrage von %s abgelehnt.").replace("%s", requesterName))); + Player requester = Bukkit.getPlayer(requesterUUID); + if (requester != null) { + requester.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.deny.notify", "&c%s hat deine Freundschaftsanfrage abgelehnt.").replace("%s", player.getName()))); + } + logger.info(player.getName() + " hat die Freundschaftsanfrage von " + requesterName + " abgelehnt."); + } + + private void handleFriendList(Player player) { + UUID playerUUID = player.getUniqueId(); + List friendUUIDs = friendsConfig.getStringList(playerUUID + ".friends"); + + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.list.header", "&6=== Deine Freundesliste ==="))); + if (friendUUIDs.isEmpty()) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.list.empty", "&7Du hast keine Freunde."))); + } else { + for (String friendUUID : friendUUIDs) { + String friendName = getNameFromUUID(UUID.fromString(friendUUID)); + Player friend = Bukkit.getPlayer(UUID.fromString(friendUUID)); + String status = friend != null ? langConfig.getString("friend.list.online", "&aOnline") : langConfig.getString("friend.list.offline", "&7Offline"); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.list.entry", "&e%s: %s").replaceFirst("%s", friendName).replaceFirst("%s", status))); + } + } + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.list.footer", "&6====================="))); + logger.info("Freundesliste für " + player.getName() + " angezeigt."); + } + + private void handleFriendDelete(Player player, String friendName) { + UUID friendUUID = getUUIDFromName(friendName); + if (friendUUID == null) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.player-not-found", "&cSpieler %s nicht gefunden!").replace("%s", friendName))); + return; + } + + UUID playerUUID = player.getUniqueId(); + List playerFriends = friendsConfig.getStringList(playerUUID + ".friends"); + List friendFriends = friendsConfig.getStringList(friendUUID + ".friends"); + + if (!playerFriends.contains(friendUUID.toString())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.not-friends", "&c%s ist nicht in deiner Freundesliste!").replace("%s", friendName))); + return; + } + + playerFriends.remove(friendUUID.toString()); + friendFriends.remove(playerUUID.toString()); + + friendsConfig.set(playerUUID + ".friends", playerFriends); + friendsConfig.set(friendUUID + ".friends", friendFriends); + saveFriendsConfig(); + + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.del.success", "&a%s wurde aus deiner Freundesliste entfernt.").replace("%s", friendName))); + Player friend = Bukkit.getPlayer(friendUUID); + if (friend != null) { + friend.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.del.notify", "&c%s hat dich aus seiner Freundesliste entfernt.").replace("%s", player.getName()))); + } + logger.info(player.getName() + " hat " + friendName + " aus der Freundesliste entfernt."); + } + + private void handleFriendTeleport(Player player, String friendName) { + Player friend = Bukkit.getPlayerExact(friendName); + if (friend == null) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.player-not-found", "&cSpieler %s nicht gefunden!").replace("%s", friendName))); + return; + } + + UUID playerUUID = player.getUniqueId(); + UUID friendUUID = friend.getUniqueId(); + List playerFriends = friendsConfig.getStringList(playerUUID + ".friends"); + + if (!playerFriends.contains(friendUUID.toString())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.not-friends", "&c%s ist nicht in deiner Freundesliste!").replace("%s", friendName))); + return; + } + + if (!player.getWorld().equals(friend.getWorld())) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.error.different-world", "&cIhr müsst in derselben Welt sein, um zu teleportieren!"))); + return; + } + + player.teleport(friend.getLocation()); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.tp.success", "&aDu wurdest zu %s teleportiert!").replace("%s", friendName))); + friend.sendMessage(ChatColor.translateAlternateColorCodes('&', langConfig.getString("friend.tp.notify", "&a%s hat sich zu dir teleportiert.").replace("%s", player.getName()))); + logger.info(player.getName() + " hat sich zu " + friendName + " teleportiert."); + } + + private UUID getUUIDFromName(String name) { + Player target = Bukkit.getPlayerExact(name); + if (target != null) { + return target.getUniqueId(); + } + // Fallback für Offline-Spieler + for (String key : friendsConfig.getKeys(false)) { + try { + UUID uuid = UUID.fromString(key); + String storedName = friendsConfig.getString(key + ".name"); + if (storedName != null && storedName.equalsIgnoreCase(name)) { + return uuid; + } + } catch (IllegalArgumentException ignored) { + } + } + return null; + } + + private String getNameFromUUID(UUID uuid) { + Player player = Bukkit.getPlayer(uuid); + if (player != null) { + return player.getName(); + } + String storedName = friendsConfig.getString(uuid + ".name"); + if (storedName != null) { + return storedName; + } + return uuid.toString(); // Fallback auf UUID, falls Name nicht gefunden + } + + private void saveFriendsConfig() { + try { + friendsConfig.save(new File(plugin.getDataFolder(), "friends.yml")); + logger.fine("friends.yml erfolgreich gespeichert."); + } catch (IOException e) { + logger.severe("Fehler beim Speichern der friends.yml: " + e.getMessage()); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/commands/GamemodeCommand.java b/src/main/java/de/viper/survivalplus/commands/GamemodeCommand.java new file mode 100644 index 0000000..eb2ca8f --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/GamemodeCommand.java @@ -0,0 +1,83 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.GameMode; +import org.bukkit.configuration.file.FileConfiguration; + +public class GamemodeCommand implements CommandExecutor { + private final SurvivalPlus plugin; + + public GamemodeCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + FileConfiguration lang = plugin.getLangConfig(); + + if (!sender.hasPermission("survivalplus.gamemode")) { + sender.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + if (args.length == 0) { + sender.sendMessage(lang.getString("gamemode.usage", "§cVerwendung: /gm <0|1|2|3> [spieler]")); + return true; + } + + Player target = (args.length > 1) ? plugin.getServer().getPlayer(args[1]) : (sender instanceof Player ? (Player) sender : null); + + if (args.length > 1 && !sender.hasPermission("survivalplus.gamemode.others")) { + sender.sendMessage(lang.getString("no-permission-others", "§cDu hast keine Berechtigung, den Spielmodus anderer zu ändern!")); + return true; + } + + if (target == null) { + sender.sendMessage(lang.getString("player-not-found", "§cSpieler nicht gefunden!")); + return true; + } + + GameMode gameMode; + String modeName; + switch (args[0].toLowerCase()) { + case "0": + case "survival": + gameMode = GameMode.SURVIVAL; + modeName = lang.getString("gamemode.survival", "Überleben"); + break; + case "1": + case "creative": + gameMode = GameMode.CREATIVE; + modeName = lang.getString("gamemode.creative", "Kreativ"); + break; + case "2": + case "adventure": + gameMode = GameMode.ADVENTURE; + modeName = lang.getString("gamemode.adventure", "Abenteuer"); + break; + case "3": + case "spectator": + gameMode = GameMode.SPECTATOR; + modeName = lang.getString("gamemode.spectator", "Zuschauer"); + break; + default: + sender.sendMessage(lang.getString("invalid-gamemode", "§cUngültiger Spielmodus! Verwende 0, 1, 2 oder 3")); + return true; + } + + target.setGameMode(gameMode); + String message = sender == target ? + lang.getString("gamemode.changed-self", "§aDein Spielmodus wurde zu %mode% geändert!") + .replace("%mode%", modeName) : + lang.getString("gamemode.changed-other", "§aSpielmodus von %player% zu %mode% geändert!") + .replace("%player%", target.getName()) + .replace("%mode%", modeName); + + sender.sendMessage(message); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/commands/HomeCommand.java b/src/main/java/de/viper/survivalplus/commands/HomeCommand.java new file mode 100644 index 0000000..624bda3 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/HomeCommand.java @@ -0,0 +1,146 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.Material; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.ArrayList; +import java.util.List; + +public class HomeCommand implements CommandExecutor { + private final SurvivalPlus plugin; + + public HomeCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getLangConfig().getString("player-only", "§cDieser Befehl ist nur für Spieler!")); + return true; + } + + Player player = (Player) sender; + FileConfiguration lang = plugin.getLangConfig(); + FileConfiguration homes = plugin.getHomesConfig(); + String commandName = command.getName().toLowerCase(); + + if (commandName.equals("sethome")) { + if (!player.hasPermission("survivalplus.homes.set")) { + player.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + if (args.length != 1) { + player.sendMessage(lang.getString("sethome.usage", "§cVerwendung: /sethome ")); + return true; + } + + String homeName = args[0].toLowerCase(); + if (!homeName.matches("[a-z0-9_]+")) { + player.sendMessage(lang.getString("sethome.invalid-name", "§cDer Home-Name darf nur Buchstaben, Zahlen und Unterstriche enthalten!")); + return true; + } + + String path = "homes." + player.getUniqueId() + "." + homeName; + if (homes.contains(path)) { + player.sendMessage(lang.getString("sethome.already-exists", "§cEin Home mit diesem Namen existiert bereits!")); + return true; + } + + int maxHomes = player.hasPermission("survivalplus.homes.unlimited") ? Integer.MAX_VALUE : plugin.getConfig().getInt("max-homes", 3); + int currentHomes = homes.getConfigurationSection("homes." + player.getUniqueId()) != null ? + homes.getConfigurationSection("homes." + player.getUniqueId()).getKeys(false).size() : 0; + + if (currentHomes >= maxHomes) { + player.sendMessage(lang.getString("sethome.limit-reached", "§cDu hast die maximale Anzahl an Homes erreicht!")); + return true; + } + + Location loc = player.getLocation(); + homes.set(path + ".world", loc.getWorld().getName()); + homes.set(path + ".x", loc.getX()); + homes.set(path + ".y", loc.getY()); + homes.set(path + ".z", loc.getZ()); + homes.set(path + ".yaw", loc.getYaw()); + homes.set(path + ".pitch", loc.getPitch()); + plugin.saveHomesConfig(); + + player.sendMessage(lang.getString("sethome.success", "§aHome %name% wurde gesetzt!") + .replace("%name%", homeName)); + return true; + } + + if (commandName.equals("delhome")) { + if (!player.hasPermission("survivalplus.homes.delete")) { + player.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + if (args.length != 1) { + player.sendMessage(lang.getString("delhome.usage", "§cVerwendung: /delhome ")); + return true; + } + + String homeName = args[0].toLowerCase(); + String path = "homes." + player.getUniqueId() + "." + homeName; + if (!homes.contains(path)) { + player.sendMessage(lang.getString("delhome.not-found", "§cDieses Home existiert nicht!")); + return true; + } + + homes.set(path, null); + plugin.saveHomesConfig(); + player.sendMessage(lang.getString("delhome.success", "§aHome %name% wurde gelöscht!") + .replace("%name%", homeName)); + return true; + } + + if (commandName.equals("homelist")) { + if (!player.hasPermission("survivalplus.homes.list")) { + player.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + String path = "homes." + player.getUniqueId(); + if (!homes.contains(path) || homes.getConfigurationSection(path).getKeys(false).isEmpty()) { + player.sendMessage(lang.getString("homelist.no-homes", "§cDu hast keine Homes gesetzt!")); + return true; + } + + Inventory gui = Bukkit.createInventory(null, 27, lang.getString("homelist.gui-title", "Deine Homes")); + List homeNames = new ArrayList<>(homes.getConfigurationSection(path).getKeys(false)); + + for (int i = 0; i < Math.min(homeNames.size(), 27); i++) { + String homeName = homeNames.get(i); + String homePath = path + "." + homeName; + ItemStack item = new ItemStack(Material.RED_BED); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName("§a" + homeName); + List lore = new ArrayList<>(); + lore.add("§7Welt: " + homes.getString(homePath + ".world")); + lore.add("§7X: " + String.format("%.2f", homes.getDouble(homePath + ".x"))); + lore.add("§7Y: " + String.format("%.2f", homes.getDouble(homePath + ".y"))); + lore.add("§7Z: " + String.format("%.2f", homes.getDouble(homePath + ".z"))); + meta.setLore(lore); + item.setItemMeta(meta); + gui.setItem(i, item); + } + + player.openInventory(gui); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/commands/InventoryCommand.java b/src/main/java/de/viper/survivalplus/commands/InventoryCommand.java new file mode 100644 index 0000000..a3b91d2 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/InventoryCommand.java @@ -0,0 +1,135 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.configuration.file.FileConfiguration; +import java.io.File; +import java.util.UUID; +import java.util.logging.Level; + +public class InventoryCommand implements CommandExecutor { + private final SurvivalPlus plugin; + + public InventoryCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getLangConfig().getString("player-only", "§cDieser Befehl ist nur für Spieler!")); + return true; + } + + Player player = (Player) sender; + FileConfiguration lang = plugin.getLangConfig(); + + if (!player.hasPermission("survivalplus.inventory.own")) { + player.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + if (args.length != 1) { + player.sendMessage(lang.getString("inventory.usage", "§cVerwendung: /inv ")); + return true; + } + + String targetName = args[0]; + OfflinePlayer target; + + // Versuche zuerst, den Spieler online zu finden + Player onlineTarget = Bukkit.getPlayerExact(targetName); + if (onlineTarget != null) { + target = onlineTarget; + plugin.getLogger().log(Level.INFO, "Spieler " + targetName + " ist online, verwende Online-Pfad"); + } else { + // Fallback auf Offline-Spieler + target = Bukkit.getOfflinePlayer(targetName); + if (target.getName() == null || !target.hasPlayedBefore()) { + player.sendMessage(lang.getString("player-not-found", "§cSpieler nicht gefunden!")); + return true; + } + plugin.getLogger().log(Level.INFO, "Spieler " + targetName + " ist offline, verwende Offline-Pfad"); + } + + // Prüfe, ob der Spieler sein eigenes Inventar ansieht oder die Berechtigung für fremde Inventare hat + if (!player.getName().equalsIgnoreCase(targetName) && !player.hasPermission("survivalplus.inventory.others")) { + player.sendMessage(lang.getString("no-permission-others-inv", "§cDu hast keine Berechtigung, das Inventar anderer Spieler anzusehen!")); + return true; + } + + // Erstelle die GUI + String guiTitle = lang.getString("inventory.gui-title", "Inventar von ") + targetName; + Inventory gui = Bukkit.createInventory(null, 45, guiTitle); + + // Lade das Inventar + if (target.isOnline()) { + Player onlineTargetPlayer = target.getPlayer(); + PlayerInventory inv = onlineTargetPlayer.getInventory(); + for (int i = 0; i < 36; i++) { + gui.setItem(i, inv.getItem(i)); + } + gui.setItem(36, inv.getHelmet()); + gui.setItem(37, inv.getChestplate()); + gui.setItem(38, inv.getLeggings()); + gui.setItem(39, inv.getBoots()); + gui.setItem(40, inv.getItemInOffHand()); + plugin.getLogger().log(Level.INFO, "Inventar für " + targetName + " (online) erfolgreich geladen"); + } else { + UUID uuid = target.getUniqueId(); + try { + // Lade Offline-Spieler-Inventar aus playerdata + File dataFolder = new File(plugin.getServer().getWorlds().get(0).getWorldFolder(), "playerdata"); + File playerFile = new File(dataFolder, uuid.toString() + ".dat"); + + if (!playerFile.exists()) { + player.sendMessage(lang.getString("inventory.data-not-found", "§cDie Inventardaten des Spielers konnten nicht gefunden werden! Der Spieler war möglicherweise nie auf diesem Server.")); + return true; + } + + String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + plugin.getLogger().log(Level.INFO, "Versuche, Inventar für " + targetName + " zu laden (UUID: " + uuid + ", Version: " + version + ")"); + + // Verwende Bukkit-API für Offline-Spieler + Object playerProfile = Bukkit.createPlayerProfile(uuid, targetName); + String craftVersion = "org.bukkit.craftbukkit." + version; + Class craftServerClass = Class.forName(craftVersion + ".CraftServer"); + Class craftPlayerClass = Class.forName(craftVersion + ".entity.CraftPlayer"); + Object craftServer = craftServerClass.cast(Bukkit.getServer()); + Object craftPlayer = craftPlayerClass.getConstructor(craftServerClass, playerProfile.getClass()).newInstance(craftServer, playerProfile); + + // Lade die Spieler-Daten + craftPlayerClass.getMethod("loadData").invoke(craftPlayer); + PlayerInventory inv = (PlayerInventory) craftPlayerClass.getMethod("getInventory").invoke(craftPlayer); + for (int i = 0; i < 36; i++) { + gui.setItem(i, inv.getItem(i)); + } + gui.setItem(36, inv.getHelmet()); + gui.setItem(37, inv.getChestplate()); + gui.setItem(38, inv.getLeggings()); + gui.setItem(39, inv.getBoots()); + gui.setItem(40, inv.getItemInOffHand()); + plugin.getLogger().log(Level.INFO, "Inventar für " + targetName + " erfolgreich geladen"); + } catch (Exception e) { + plugin.getLogger().log(Level.SEVERE, "Fehler beim Laden des Inventars für " + targetName + " (UUID: " + uuid + ")", e); + String errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + player.sendMessage(lang.getString("inventory.load-error", "§cFehler beim Laden des Inventars: %error%") + .replace("%error%", errorMessage)); + return true; + } + } + + player.openInventory(gui); + player.sendMessage(lang.getString("inventory.opened", "§aInventar von %player% geöffnet!") + .replace("%player%", targetName)); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/commands/ItemRenameCommand.java b/src/main/java/de/viper/survivalplus/commands/ItemRenameCommand.java new file mode 100644 index 0000000..6067c79 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/ItemRenameCommand.java @@ -0,0 +1,63 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class ItemRenameCommand implements CommandExecutor { + + private final SurvivalPlus plugin; + + public ItemRenameCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage(ChatColor.RED + plugin.getMessage("ir.only-player")); + return true; + } + + if (!player.hasPermission("survivalplus.itemrename")) { + player.sendMessage(ChatColor.RED + plugin.getMessage("ir.no-permission")); + return true; + } + + if (args.length == 0) { + player.sendMessage(ChatColor.RED + plugin.getMessage("ir.no-name")); + player.sendMessage(ChatColor.YELLOW + plugin.getMessage("ir.usage")); + return true; + } + + ItemStack item = player.getInventory().getItemInMainHand(); + if (item == null || item.getType().isAir()) { + player.sendMessage(ChatColor.RED + plugin.getMessage("ir.no-item")); + return true; + } + + StringBuilder newNameBuilder = new StringBuilder(); + for (String arg : args) { + newNameBuilder.append(arg).append(" "); + } + String newName = newNameBuilder.toString().trim(); + newName = ChatColor.translateAlternateColorCodes('&', newName); + + ItemMeta meta = item.getItemMeta(); + if (meta == null) { + player.sendMessage(ChatColor.RED + plugin.getMessage("ir.cant-rename")); + return true; + } + + meta.setDisplayName(newName); + item.setItemMeta(meta); + + player.sendMessage(ChatColor.GREEN + plugin.getMessage("ir.success").replace("{name}", newName)); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/LeashCountCommand.java b/src/main/java/de/viper/survivalplus/commands/LeashCountCommand.java new file mode 100644 index 0000000..74358ce --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/LeashCountCommand.java @@ -0,0 +1,30 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import de.viper.survivalplus.listeners.MobLeashLimitListener; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class LeashCountCommand implements CommandExecutor { + private final SurvivalPlus plugin; + private final MobLeashLimitListener listener; + + public LeashCountCommand(SurvivalPlus plugin, MobLeashLimitListener listener) { + this.plugin = plugin; + this.listener = listener; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getMessage("player-only")); + return true; + } + Player player = (Player) sender; + int count = listener.getLeashCount(player); + player.sendMessage(plugin.getMessage("leashcount.message").replace("%count%", String.valueOf(count))); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/PluginCommand.java b/src/main/java/de/viper/survivalplus/commands/PluginCommand.java new file mode 100644 index 0000000..85212e8 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/PluginCommand.java @@ -0,0 +1,127 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class PluginCommand implements CommandExecutor { + private final SurvivalPlus plugin; + private static final int COMMANDS_PER_PAGE = 5; + + public PluginCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + FileConfiguration lang = plugin.getLangConfig(); + + if (args.length == 0 || args[0].equalsIgnoreCase("help")) { + int page = 1; + if (args.length > 1 && args[0].equalsIgnoreCase("help")) { + try { + page = Integer.parseInt(args[1]); + if (page < 1) page = 1; + } catch (NumberFormatException e) { + sender.sendMessage(color(lang.getString("sp.invalid-subcommand", "§cUngültiger Unterbefehl! Verwendung: /sp [reload|help]"))); + return true; + } + } + showHelp(sender, page); + return true; + } + + if (args[0].equalsIgnoreCase("reload")) { + if (!sender.hasPermission("survivalplus.reload")) { + sender.sendMessage(color(lang.getString("no-permission", "&cKeine Berechtigung!"))); + return true; + } + plugin.reloadPlugin(); + sender.sendMessage(color(lang.getString("plugin.reloaded", "&aPlugin neu geladen."))); + return true; + } + + sender.sendMessage(color(lang.getString("sp.invalid-subcommand", "&cUngültiger Unterbefehl!"))); + return true; + } + + private void showHelp(CommandSender sender, int page) { + FileConfiguration help = plugin.getHelpConfig(); + FileConfiguration lang = plugin.getLangConfig(); + + if (help == null || help.getConfigurationSection("commands") == null) { + sender.sendMessage(color(lang.getString("sp.help-not-found", "&cHilfe nicht gefunden."))); + return; + } + + List commands = new ArrayList<>(help.getConfigurationSection("commands").getKeys(false)); + if (commands.isEmpty()) { + sender.sendMessage(color(lang.getString("sp.help-not-found", "&cKeine Befehle verfügbar."))); + return; + } + + int totalPages = (int) Math.ceil((double) commands.size() / COMMANDS_PER_PAGE); + if (page > totalPages) page = totalPages; + if (page < 1) page = 1; + + sender.sendMessage(color(help.getString("header", "&7===== &eSurvivalPlus Hilfe &7====="))); + + int startIndex = (page - 1) * COMMANDS_PER_PAGE; + int endIndex = Math.min(startIndex + COMMANDS_PER_PAGE, commands.size()); + + for (int i = startIndex; i < endIndex; i++) { + String cmd = commands.get(i); + String usage = help.getString("commands." + cmd + ".usage", ""); + String description = help.getString("commands." + cmd + ".description", ""); + sender.sendMessage(color(usage + " §7- " + description)); + } + + if (sender instanceof Player player) { + TextComponent navigation = new TextComponent(); + + if (page > 1) { + TextComponent prev = new TextComponent(color(help.getString("navigation.prev", "« Vorherige "))); + prev.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/sp help " + (page - 1))); + navigation.addExtra(prev); + } else { + navigation.addExtra(color(help.getString("navigation.prev-disabled", "« "))); + } + + TextComponent pageInfo = new TextComponent(color(help.getString("navigation.page", " §fSeite {current} von {total} ")) + .replace("{current}", String.valueOf(page)) + .replace("{total}", String.valueOf(totalPages))); + navigation.addExtra(pageInfo); + + if (page < totalPages) { + TextComponent next = new TextComponent(color(help.getString("navigation.next", " Nächste »"))); + next.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/sp help " + (page + 1))); + navigation.addExtra(next); + } else { + navigation.addExtra(color(help.getString("navigation.next-disabled", " »"))); + } + + player.spigot().sendMessage(navigation); + } else { + for (String cmd : commands) { + String usage = help.getString("commands." + cmd + ".usage", ""); + String description = help.getString("commands." + cmd + ".description", ""); + sender.sendMessage(color(usage + " §7- " + description)); + } + } + + sender.sendMessage(color(help.getString("footer", "&7=========================="))); + } + + private String color(String input) { + return ChatColor.translateAlternateColorCodes('&', input); + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/SetSpawnCommand.java b/src/main/java/de/viper/survivalplus/commands/SetSpawnCommand.java new file mode 100644 index 0000000..15fc31c --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/SetSpawnCommand.java @@ -0,0 +1,41 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import de.viper.survivalplus.SurvivalPlus; + +public class SetSpawnCommand implements CommandExecutor { + private final SurvivalPlus plugin; + + public SetSpawnCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage("Nur Spieler können diesen Befehl verwenden!"); + return true; + } + + if (!player.hasPermission("survivalplus.setspawn")) { + player.sendMessage("§cDu hast keine Rechte für diesen Befehl."); + return true; + } + + Location loc = player.getLocation(); + plugin.getConfig().set("spawn.world", loc.getWorld().getName()); + plugin.getConfig().set("spawn.x", loc.getX()); + plugin.getConfig().set("spawn.y", loc.getY()); + plugin.getConfig().set("spawn.z", loc.getZ()); + plugin.getConfig().set("spawn.yaw", loc.getYaw()); + plugin.getConfig().set("spawn.pitch", loc.getPitch()); + plugin.saveConfig(); + + player.sendMessage("§aSpawnpunkt erfolgreich gesetzt!"); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/SetWorldSpawnCommand.java b/src/main/java/de/viper/survivalplus/commands/SetWorldSpawnCommand.java new file mode 100644 index 0000000..f3e098c --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/SetWorldSpawnCommand.java @@ -0,0 +1,40 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SetWorldSpawnCommand implements CommandExecutor { + + private final SurvivalPlus plugin; + + public SetWorldSpawnCommand(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage(ChatColor.RED + "Dieser Befehl kann nur von einem Spieler verwendet werden."); + return true; + } + + if (!player.hasPermission("survivalplus.setworldspawn")) { + player.sendMessage(ChatColor.RED + "Du hast keine Rechte für diesen Befehl."); + return true; + } + + Location loc = player.getLocation(); + World world = player.getWorld(); + world.setSpawnLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + player.sendMessage(ChatColor.GREEN + "Spawnpunkt gesetzt bei §e" + + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ()); + + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/ShowArmorStandsCommand.java b/src/main/java/de/viper/survivalplus/commands/ShowArmorStandsCommand.java new file mode 100644 index 0000000..54590d0 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/ShowArmorStandsCommand.java @@ -0,0 +1,43 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.plugin.java.JavaPlugin; + +public class ShowArmorStandsCommand implements CommandExecutor { + + private final JavaPlugin plugin; + + public ShowArmorStandsCommand(JavaPlugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!sender.hasPermission("survivalplus.showarmorstands")) { + sender.sendMessage("§cDu hast keine Rechte für diesen Befehl."); + return true; + } + + int count = 0; + for (World world : Bukkit.getWorlds()) { + for (Entity entity : world.getEntities()) { + if (entity instanceof ArmorStand) { + ArmorStand armorStand = (ArmorStand) entity; + if (!armorStand.isVisible()) { + armorStand.setVisible(true); + count++; + } + } + } + } + + sender.sendMessage("§a" + count + " unsichtbare Armor Stands wurden sichtbar gemacht."); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/SitCommand.java b/src/main/java/de/viper/survivalplus/commands/SitCommand.java new file mode 100644 index 0000000..a0fed10 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/SitCommand.java @@ -0,0 +1,54 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import de.viper.survivalplus.listeners.SitListener; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.configuration.file.FileConfiguration; + +public class SitCommand implements CommandExecutor { + private final SurvivalPlus plugin; + private final SitListener sitListener; + + public SitCommand(SurvivalPlus plugin, SitListener sitListener) { + this.plugin = plugin; + this.sitListener = sitListener; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getLangConfig().getString("player-only", "§cDieser Befehl ist nur für Spieler!")); + return true; + } + + Player player = (Player) sender; + FileConfiguration lang = plugin.getLangConfig(); + + if (!player.hasPermission("survivalplus.sit")) { + player.sendMessage(lang.getString("no-permission", "§cDu hast keine Berechtigung für diesen Befehl!")); + return true; + } + + if (args.length != 0) { + player.sendMessage(lang.getString("sit.usage", "§cVerwendung: /sit")); + return true; + } + + // Prüfe, ob der Spieler bereits sitzt + if (sitListener.isSitting(player)) { + sitListener.standUp(player); + player.sendMessage(lang.getString("sit.stand-up", "§aDu bist aufgestanden!")); + return true; + } + + // Setze den Spieler direkt auf dem Block + Location location = player.getLocation(); + location.setY(location.getBlockY()); // Direkt auf dem Block (keine Y-Verschiebung) + sitListener.sitPlayer(player, location); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/viper/survivalplus/commands/StatsCommand.java b/src/main/java/de/viper/survivalplus/commands/StatsCommand.java new file mode 100644 index 0000000..f56a943 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/StatsCommand.java @@ -0,0 +1,58 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.Manager.StatsManager; +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class StatsCommand implements CommandExecutor { + + private final SurvivalPlus plugin; + private final StatsManager statsManager; + + public StatsCommand(SurvivalPlus plugin, StatsManager statsManager) { + this.plugin = plugin; + this.statsManager = statsManager; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getMessage("stats.only_player")); + return true; + } + + Player player = (Player) sender; + + long time = statsManager.getPlayTime(player.getUniqueId()); + int kills = statsManager.getKills(player.getUniqueId()); + int deaths = statsManager.getDeaths(player.getUniqueId()); + int placed = statsManager.getBlocksPlaced(player.getUniqueId()); + int broken = statsManager.getBlocksBroken(player.getUniqueId()); + + if (time == 0 && kills == 0 && deaths == 0 && placed == 0 && broken == 0) { + player.sendMessage(plugin.getMessage("stats.no_stats")); + return true; + } + + player.sendMessage(plugin.getMessage("stats.header").replace("{player}", player.getName())); + player.sendMessage(plugin.getMessage("stats.playtime").replace("{time}", formatPlayTime(time))); + player.sendMessage(plugin.getMessage("stats.kills").replace("{kills}", String.valueOf(kills))); + player.sendMessage(plugin.getMessage("stats.deaths").replace("{deaths}", String.valueOf(deaths))); + player.sendMessage(plugin.getMessage("stats.blocks_placed").replace("{placed}", String.valueOf(placed))); + player.sendMessage(plugin.getMessage("stats.blocks_broken").replace("{broken}", String.valueOf(broken))); + + return true; + } + + private String formatPlayTime(long seconds) { + long hours = seconds / 3600; + long minutes = (seconds % 3600) / 60; + long secs = seconds % 60; + + return String.format("%02dh %02dm %02ds", hours, minutes, secs); + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/TeleportCommands.java b/src/main/java/de/viper/survivalplus/commands/TeleportCommands.java new file mode 100644 index 0000000..3ea5068 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/TeleportCommands.java @@ -0,0 +1,157 @@ +package de.viper.survivalplus.commands; + +import de.viper.survivalplus.SurvivalPlus; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class TeleportCommands implements CommandExecutor { + + private final SurvivalPlus plugin; + private final Map teleportRequests = new HashMap<>(); + + public TeleportCommands(SurvivalPlus plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.getMessage("only-players")); + return true; + } + + Player player = (Player) sender; + String cmd = label.toLowerCase(); + + switch (cmd) { + case "tp": + return handleTp(player, args); + case "tphere": + return handleTphere(player, args); + case "tpa": + return handleTpa(player, args); + case "tpaccept": + return handleTpAccept(player); + case "tpdeny": + return handleTpDeny(player); + default: + return false; + } + } + + private boolean handleTp(Player sender, String[] args) { + if (!sender.hasPermission("survivalplus.tp")) { + sender.sendMessage(plugin.getMessage("no-permission")); + return true; + } + if (args.length != 1) { + sender.sendMessage(plugin.getMessage("teleport-usage")); + return true; + } + + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + sender.sendMessage(plugin.getMessage("player-not-found").replace("%player%", args[0])); + return true; + } + + sender.teleport(target); + sender.sendMessage(plugin.getMessage("teleport-success").replace("%player%", target.getName())); + return true; + } + + private boolean handleTphere(Player sender, String[] args) { + if (!sender.hasPermission("survivalplus.tphere")) { + sender.sendMessage(plugin.getMessage("no-permission")); + return true; + } + if (args.length != 1) { + sender.sendMessage(plugin.getMessage("tphere-usage")); + return true; + } + + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + sender.sendMessage(plugin.getMessage("player-not-found").replace("%player%", args[0])); + return true; + } + + target.teleport(sender); + sender.sendMessage(plugin.getMessage("tphere-success").replace("%player%", target.getName())); + return true; + } + + private boolean handleTpa(Player sender, String[] args) { + if (!sender.hasPermission("survivalplus.tpa")) { + sender.sendMessage(plugin.getMessage("no-permission")); + return true; + } + if (args.length != 1) { + sender.sendMessage(plugin.getMessage("tpa-usage")); + return true; + } + + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { + sender.sendMessage(plugin.getMessage("player-not-found").replace("%player%", args[0])); + return true; + } + + teleportRequests.put(target.getUniqueId(), sender.getUniqueId()); + sender.sendMessage(plugin.getMessage("tpa-sent").replace("%player%", target.getName())); + target.sendMessage(plugin.getMessage("tpa-received").replace("%player%", sender.getName())); + return true; + } + + private boolean handleTpAccept(Player target) { + if (!target.hasPermission("survivalplus.tpaccept")) { + target.sendMessage(plugin.getMessage("no-permission")); + return true; + } + + UUID senderId = teleportRequests.remove(target.getUniqueId()); + if (senderId == null) { + target.sendMessage(plugin.getMessage("no-tpa-request")); + return true; + } + + Player sender = Bukkit.getPlayer(senderId); + if (sender == null) { + target.sendMessage(plugin.getMessage("player-not-found")); + return true; + } + + sender.teleport(target); + sender.sendMessage(plugin.getMessage("tpa-accepted").replace("%player%", target.getName())); + target.sendMessage(plugin.getMessage("tpaccept-success").replace("%player%", sender.getName())); + return true; + } + + private boolean handleTpDeny(Player target) { + if (!target.hasPermission("survivalplus.tpdeny")) { + target.sendMessage(plugin.getMessage("no-permission")); + return true; + } + + UUID senderId = teleportRequests.remove(target.getUniqueId()); + if (senderId == null) { + target.sendMessage(plugin.getMessage("no-tpa-request")); + return true; + } + + Player sender = Bukkit.getPlayer(senderId); + if (sender != null) { + sender.sendMessage(plugin.getMessage("tpa-denied").replace("%player%", target.getName())); + } + + target.sendMessage(plugin.getMessage("tpdeny-success")); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/TrashCommand.java b/src/main/java/de/viper/survivalplus/commands/TrashCommand.java new file mode 100644 index 0000000..b49ab66 --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/TrashCommand.java @@ -0,0 +1,23 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +public class TrashCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage("Nur Spieler können diesen Befehl ausführen."); + return true; + } + + Inventory trash = Bukkit.createInventory(player, 9 * 3, "Trash"); + player.openInventory(trash); + return true; + } +} diff --git a/src/main/java/de/viper/survivalplus/commands/WorkbenchCommand.java b/src/main/java/de/viper/survivalplus/commands/WorkbenchCommand.java new file mode 100644 index 0000000..cda68de --- /dev/null +++ b/src/main/java/de/viper/survivalplus/commands/WorkbenchCommand.java @@ -0,0 +1,20 @@ +package de.viper.survivalplus.commands; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class WorkbenchCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage("Nur Spieler können diesen Befehl ausführen."); + return true; + } + + player.openWorkbench(null, true); // Öffnet die Werkbank-GUI für den Spieler + return true; + } +}