diff --git a/src/main/java/de/nexuslobby/modules/servers/ServerSwitcher.java b/src/main/java/de/nexuslobby/modules/servers/ServerSwitcher.java new file mode 100644 index 0000000..ae82cd7 --- /dev/null +++ b/src/main/java/de/nexuslobby/modules/servers/ServerSwitcher.java @@ -0,0 +1,74 @@ +package de.nexuslobby.modules.servers; + +import de.nexuslobby.NexusLobby; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class ServerSwitcher implements Listener { + + private final NexusLobby plugin; + private final Map serverDisplayNames = new LinkedHashMap<>(); // order preserved + + public ServerSwitcher(NexusLobby plugin) { + this.plugin = plugin; + initServersFromConfig(); + } + + private void initServersFromConfig() { + // Versuche Konfiguration auszulesen: config.serverswitcher.servers (yaml map) + if (plugin.getConfig().isConfigurationSection("serverswitcher.servers")) { + for (String key : plugin.getConfig().getConfigurationSection("serverswitcher.servers").getKeys(false)) { + String display = plugin.getConfig().getString("serverswitcher.servers." + key + ".display", key); + serverDisplayNames.put(key, display); + } + } else { + // Fallback (falls nichts in der Config): Beispielwerte + serverDisplayNames.put("Lobby", "Lobby"); + serverDisplayNames.put("PvP", "PvP"); + serverDisplayNames.put("Survival", "Survival"); + } + } + + /** + * Gibt dem Spieler den Kompass im Hotbar-Slot 5 (Index 4). + */ + public void giveServerCompass(Player player) { + // Inventar vorher nur leeren, wenn wirklich gewünscht + if (plugin.getConfig().getBoolean("lobby.clear-inventory-on-join", true)) { + player.getInventory().clear(); + } + + // Kompass erstellen + ItemStack compass = new ItemStack(Material.COMPASS, 1); + ItemMeta meta = compass.getItemMeta(); + if (meta != null) { + meta.setDisplayName("§6Server Switcher"); + compass.setItemMeta(meta); + } + + // Hotbar-Slot 5 = Index 4 (Zählung: 0, 1, 2, 3, 4, 5, 6, 7, 8) + int hotbarSlot = 4; + player.getInventory().setItem(hotbarSlot, compass); + } + + /** + * Öffnet die GUI für den Spieler. + */ + public void openServerGui(Player player) { + ServerSwitcherGUI gui = new ServerSwitcherGUI(plugin, serverDisplayNames); + Inventory inv = gui.createInventory(player); + player.openInventory(inv); + } + + public void onDisable() { + HandlerList.unregisterAll(this); + } +} \ No newline at end of file diff --git a/src/main/java/de/nexuslobby/modules/servers/ServerSwitcherGUI.java b/src/main/java/de/nexuslobby/modules/servers/ServerSwitcherGUI.java new file mode 100644 index 0000000..71a09ac --- /dev/null +++ b/src/main/java/de/nexuslobby/modules/servers/ServerSwitcherGUI.java @@ -0,0 +1,133 @@ +package de.nexuslobby.modules.servers; + +import de.nexuslobby.NexusLobby; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.Plugin; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Map; + +public class ServerSwitcherGUI { + + private final NexusLobby plugin; + private final Map servers; // key = server id / name, value = display name + private final String title; + + public ServerSwitcherGUI(NexusLobby plugin, Map servers) { + this.plugin = plugin; + this.servers = servers; + // Title kann aus config kommen, fallback auf Default + this.title = ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("serverswitcher.title", "&6Server auswählen")); + } + + /** + * Erzeugt Inventory, registriert Listener und gibt Inventory zurück. + * Der aufrufende Code sollte player.openInventory(inv) ausführen. + */ + public Inventory createInventory(Player player) { + int count = Math.max(1, servers.size()); + int size = ((count - 1) / 9 + 1) * 9; // nächstes Vielfaches von 9 + Inventory inv = Bukkit.createInventory(null, size, title); + + int i = 0; + for (Map.Entry entry : servers.entrySet()) { + String serverId = entry.getKey(); + String displayName = entry.getValue(); + + ItemStack item = new ItemStack(Material.PAPER); + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.RESET + displayName); + item.setItemMeta(meta); + } + inv.setItem(i, item); + i++; + } + + // Listener registrieren (als final variable damit wir ihn im close handler abmelden können) + final Listener listener = new Listener() { + + @EventHandler + public void onInventoryClick(InventoryClickEvent e) { + if (!(e.getWhoClicked() instanceof Player)) return; + if (e.getView() == null) return; + if (!e.getView().getTitle().equals(title)) return; + + e.setCancelled(true); + if (e.getCurrentItem() == null || e.getCurrentItem().getType() == Material.AIR) return; + + Player p = (Player) e.getWhoClicked(); + ItemMeta meta = e.getCurrentItem().getItemMeta(); + if (meta == null || meta.getDisplayName() == null) return; + + String clickedName = ChatColor.stripColor(meta.getDisplayName()).trim(); + + // Suche serverId nach displayName + String targetServer = null; + for (Map.Entry s : servers.entrySet()) { + if (s.getValue().equalsIgnoreCase(clickedName) || s.getValue().contains(clickedName)) { + targetServer = s.getKey(); + break; + } + } + + if (targetServer == null) { + // Fallback: nutze clickedName direkt + targetServer = clickedName; + } + + // Connect und Inventory schließen + connectToServer(p, targetServer, plugin); + p.closeInventory(); + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent e) { + // Beim Schließen Listener wieder entregistrieren + if (e.getView() != null && title.equals(e.getView().getTitle())) { + HandlerList.unregisterAll(this); + } + } + }; + + Bukkit.getPluginManager().registerEvents(listener, plugin); + return inv; + } + + private static void connectToServer(Player player, String serverName, Plugin plugin) { + try { + if (!Bukkit.getMessenger().isOutgoingChannelRegistered(plugin, "BungeeCord")) { + player.sendMessage(ChatColor.RED + "Proxy-Verbindung nicht möglich (BungeeCord Kanal nicht registriert)."); + return; + } + + ByteArrayOutputStream b = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(b); + out.writeUTF("Connect"); + out.writeUTF(serverName); + player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray()); + player.sendMessage(ChatColor.YELLOW + "Verbinde zu: " + ChatColor.WHITE + serverName); + } catch (IOException ex) { + ex.printStackTrace(); + player.sendMessage(ChatColor.RED + "Fehler beim Verbinden zum Server."); + } catch (RuntimeException ex) { + // Schutz gegen unerwartete RuntimeExceptions bei plugin messaging + player.sendMessage(ChatColor.RED + "Proxy-Verbindung nicht möglich."); + plugin.getLogger().warning("Fehler beim Senden der Plugin-Message: " + ex.getMessage()); + } + } +} diff --git a/src/main/java/de/nexuslobby/modules/servers/ServerSwitcherListener.java b/src/main/java/de/nexuslobby/modules/servers/ServerSwitcherListener.java new file mode 100644 index 0000000..5d56000 --- /dev/null +++ b/src/main/java/de/nexuslobby/modules/servers/ServerSwitcherListener.java @@ -0,0 +1,145 @@ +package de.nexuslobby.modules.servers; + +import de.nexuslobby.NexusLobby; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; + +public class ServerSwitcherListener implements Listener { + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e) { + Player p = e.getPlayer(); + + // Inventar leeren + if (NexusLobby.getInstance().getConfig().getBoolean("lobby.clear-inventory-on-join", true)) { + p.getInventory().clear(); + } + + // Kompass mittig ins Inventar (Slot 5 = Index 4) + if (NexusLobby.getInstance().getConfig().getBoolean("items.lobby-tools.compass.enabled", true)) { + ItemStack compass = new ItemStack(Material.COMPASS); + ItemMeta meta = compass.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', + NexusLobby.getInstance().getConfig().getString("items.lobby-tools.compass.displayname", "&eTeleporter"))); + compass.setItemMeta(meta); + } + + // WICHTIG: Slot 5 (mittig) = Index 4 + // Standard ist 4, nicht 0! + int slot = NexusLobby.getInstance().getConfig().getInt("items.lobby-tools.compass.slot", 4); + + // Debug-Ausgabe in die Konsole + // Bukkit.getLogger().info("[NexusLobby] Setze Kompass für " + p.getName() + " in Slot-Index: " + slot); + + p.getInventory().setItem(slot, compass); + } + } + + @EventHandler + public void onCompassClick(PlayerInteractEvent e) { + Player p = e.getPlayer(); + + if (e.getItem() == null || e.getItem().getType() != Material.COMPASS) return; + if (!(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK + || e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK)) return; + + openServerGUI(p); + e.setCancelled(true); + } + + private void openServerGUI(Player p) { + String title = ChatColor.translateAlternateColorCodes('&', + NexusLobby.getInstance().getConfig().getString("compass.title", "Server Switcher")); + int size = NexusLobby.getInstance().getConfig().getInt("compass.size", 27); + + Inventory inv = Bukkit.createInventory(null, size, title); + + ConfigurationSection serversSection = NexusLobby.getInstance().getConfig().getConfigurationSection("compass.servers"); + if (serversSection != null) { + for (String serverId : serversSection.getKeys(false)) { + String path = "compass.servers." + serverId; + + String displayName = ChatColor.translateAlternateColorCodes('&', + NexusLobby.getInstance().getConfig().getString(path + ".name", serverId)); + String materialName = NexusLobby.getInstance().getConfig().getString(path + ".material", "STONE"); + String command = NexusLobby.getInstance().getConfig().getString(path + ".command", ""); + int slot = NexusLobby.getInstance().getConfig().getInt(path + ".slot", 0); + + Material mat = Material.matchMaterial(materialName); + if (mat == null) mat = Material.STONE; + + ItemStack item = new ItemStack(mat); + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(displayName); + + if (NexusLobby.getInstance().getConfig().contains(path + ".lore")) { + List loreList = NexusLobby.getInstance().getConfig().getStringList(path + ".lore"); + List coloredLore = new ArrayList<>(); + for (String line : loreList) { + coloredLore.add(ChatColor.translateAlternateColorCodes('&', line)); + } + meta.setLore(coloredLore); + } + + item.setItemMeta(meta); + } + + inv.setItem(slot, item); + } + } + + p.openInventory(inv); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent e) { + if (!(e.getWhoClicked() instanceof Player)) return; + Player p = (Player) e.getWhoClicked(); + + String guiTitle = ChatColor.translateAlternateColorCodes('&', + NexusLobby.getInstance().getConfig().getString("compass.title", "Server Wähler")); + + if (!e.getView().getTitle().equals(guiTitle)) return; + + e.setCancelled(true); + + ItemStack clicked = e.getCurrentItem(); + if (clicked == null || !clicked.hasItemMeta()) return; + + int clickedSlot = e.getSlot(); + ConfigurationSection serversSection = NexusLobby.getInstance().getConfig().getConfigurationSection("compass.servers"); + + if (serversSection != null) { + for (String serverId : serversSection.getKeys(false)) { + String path = "compass.servers." + serverId; + int configSlot = NexusLobby.getInstance().getConfig().getInt(path + ".slot", -1); + + if (configSlot == clickedSlot) { + String command = NexusLobby.getInstance().getConfig().getString(path + ".command"); + if (command != null && !command.isEmpty()) { + p.closeInventory(); + p.chat("/" + command); + return; + } + } + } + } + } +} \ No newline at end of file