package de.nexuslobby; import de.nexuslobby.api.ModuleManager; import de.nexuslobby.commands.*; import de.nexuslobby.modules.ProtectionModule; import de.nexuslobby.modules.ScoreboardModule; import de.nexuslobby.modules.ItemsModule; import de.nexuslobby.modules.security.SecurityModule; import de.nexuslobby.modules.tablist.TablistModule; import de.nexuslobby.modules.bossbar.BossBarModule; import de.nexuslobby.modules.actionbar.ActionBarModule; import de.nexuslobby.modules.settings.LobbySettingsModule; import de.nexuslobby.modules.portal.PortalManager; import de.nexuslobby.modules.portal.PortalCommand; import de.nexuslobby.modules.servers.ServerSwitcherListener; import de.nexuslobby.modules.servers.ServerChecker; import de.nexuslobby.modules.armorstandtools.*; import de.nexuslobby.modules.gadgets.GadgetModule; import de.nexuslobby.modules.hologram.HologramModule; import de.nexuslobby.modules.mapart.MapArtModule; import de.nexuslobby.modules.intro.IntroModule; import de.nexuslobby.modules.border.BorderModule; import de.nexuslobby.modules.parkour.ParkourManager; import de.nexuslobby.modules.parkour.ParkourListener; import de.nexuslobby.modules.player.PlayerInspectModule; import de.nexuslobby.modules.ball.SoccerModule; import de.nexuslobby.utils.*; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.HashSet; import java.util.Set; import java.util.UUID; public class NexusLobby extends JavaPlugin implements Listener { private static NexusLobby instance; private ModuleManager moduleManager; private PortalManager portalManager; private TablistModule tablistModule; private LobbySettingsModule lobbySettingsModule; private ItemsModule itemsModule; private GadgetModule gadgetModule; private HologramModule hologramModule; private DynamicArmorStandModule dynamicArmorStandModule; private MapArtModule mapArtModule; private IntroModule introModule; private BorderModule borderModule; private ParkourManager parkourManager; private SoccerModule soccerModule; private ArmorStandLookAtModule armorStandLookAtModule; private ConversationManager conversationManager; private File visualsFile; private FileConfiguration visualsConfig; private boolean updateAvailable = false; private String latestVersion = ""; private final Set silentPlayers = new HashSet<>(); public static NexusLobby getInstance() { return instance; } public Set getSilentPlayers() { return silentPlayers; } public ConversationManager getConversationManager() { return conversationManager; } public ParkourManager getParkourManager() { return parkourManager; } public SoccerModule getSoccerModule() { return soccerModule; } @Override public void onEnable() { getLogger().info(""); getLogger().info("[NexusLobby] _ __ __ __ __ "); getLogger().info("[NexusLobby] / | / /__ _ ____ _______/ / ____ / /_ / /_ __ __"); getLogger().info("[NexusLobby] / |/ / _ \\| |/_/ / / / ___/ / / __ \\ / __ \\/ __ \\/ / / /"); getLogger().info("[NexusLobby] / /| / __/> { String currentVersion = this.getDescription().getVersion(); if (isRemoteVersionNewer(currentVersion, version)) { this.updateAvailable = true; this.latestVersion = version; getLogger().warning("===================================================="); getLogger().warning("Update gefunden! v" + currentVersion + " -> v" + version); getLogger().warning("===================================================="); } else { this.updateAvailable = false; this.latestVersion = ""; getLogger().info("NexusLobby ist aktuell/neu genug (lokal v" + currentVersion + ", remote v" + version + ")."); } }); } private boolean isRemoteVersionNewer(String localVersion, String remoteVersion) { int[] local = extractVersionNumbers(localVersion); int[] remote = extractVersionNumbers(remoteVersion); int max = Math.max(local.length, remote.length); for (int i = 0; i < max; i++) { int l = i < local.length ? local[i] : 0; int r = i < remote.length ? remote[i] : 0; if (r > l) return true; if (r < l) return false; } return false; } private int[] extractVersionNumbers(String version) { if (version == null || version.isBlank()) return new int[0]; java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("\\\\d+").matcher(version); java.util.List parts = new java.util.ArrayList<>(); while (matcher.find()) { try { parts.add(Integer.parseInt(matcher.group())); } catch (NumberFormatException ignored) { parts.add(0); } } int[] result = new int[parts.size()]; for (int i = 0; i < parts.size(); i++) { result[i] = parts.get(i); } return result; } private void registerModules() { moduleManager.registerModule(new ProtectionModule()); moduleManager.registerModule(new ScoreboardModule()); this.itemsModule = new ItemsModule(); moduleManager.registerModule(this.itemsModule); this.gadgetModule = new GadgetModule(); moduleManager.registerModule(this.gadgetModule); this.hologramModule = new HologramModule(); moduleManager.registerModule(this.hologramModule); this.dynamicArmorStandModule = new DynamicArmorStandModule(); moduleManager.registerModule(this.dynamicArmorStandModule); moduleManager.registerModule(new ArmorStandStatusModule()); this.mapArtModule = new MapArtModule(); moduleManager.registerModule(this.mapArtModule); this.introModule = new IntroModule(); moduleManager.registerModule(this.introModule); this.borderModule = new BorderModule(); moduleManager.registerModule(this.borderModule); moduleManager.registerModule(new SecurityModule()); moduleManager.registerModule(new BossBarModule()); moduleManager.registerModule(new ActionBarModule()); this.lobbySettingsModule = new LobbySettingsModule(); moduleManager.registerModule(lobbySettingsModule); this.tablistModule = new TablistModule(); moduleManager.registerModule(tablistModule); // Player Inspect Modul registrieren moduleManager.registerModule(new PlayerInspectModule()); // Soccer Modul registrieren this.soccerModule = new SoccerModule(); moduleManager.registerModule(this.soccerModule); this.portalManager = new PortalManager(this); moduleManager.registerModule(portalManager); } private void registerListeners() { getServer().getPluginManager().registerEvents(this, this); getServer().getPluginManager().registerEvents(new ServerSwitcherListener(), this); getServer().getPluginManager().registerEvents(new VoidProtection(), this); getServer().getPluginManager().registerEvents(new DoubleJump(), this); getServer().getPluginManager().registerEvents(new PlayerHider(), this); getServer().getPluginManager().registerEvents(new MaintenanceListener(), this); getServer().getPluginManager().registerEvents(new ASTListener(), this); getServer().getPluginManager().registerEvents(new ParkourListener(this.parkourManager), this); getServer().getPluginManager().registerEvents(new NPCClickListener(), this); } private void validateConfig() { ConfigValidator validator = new ConfigValidator(this, getConfig()); validator.validate(); } public class NPCClickListener implements Listener { @EventHandler public void onNPCClick(PlayerInteractAtEntityEvent event) { Entity entity = event.getRightClicked(); Player player = event.getPlayer(); if (entity instanceof ArmorStand as) { if (as.getScoreboardTags().contains("parkour_trainer")) { player.performCommand("warp parkour"); player.sendMessage("§6§lTrainer §8» §aViel Erfolg beim Parkour! Gib dein Bestes!"); } } } } @EventHandler(priority = EventPriority.LOWEST) public void onJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); if (silentPlayers.contains(player.getUniqueId())) { event.setJoinMessage(null); } teleportToSpawn(player); player.getInventory().clear(); player.getInventory().setArmorContents(null); BuildCommand.removePlayerFromBuildMode(player); String defaultGmName = getConfig().getString("lobby.default-gamemode", "Adventure"); try { player.setGameMode(GameMode.valueOf(defaultGmName.toUpperCase())); } catch (IllegalArgumentException e) { player.setGameMode(GameMode.ADVENTURE); } if (player.hasPermission("nexuslobby.admin") && updateAvailable) { player.sendMessage(""); player.sendMessage(de.nexuslobby.utils.LangManager.get("update_available")); player.sendMessage(de.nexuslobby.utils.LangManager.get("update_version").replace("{old}", getDescription().getVersion()).replace("{new}", latestVersion)); TextComponent link = new TextComponent(de.nexuslobby.utils.LangManager.get("update_download_link")); link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.spigotmc.org/resources/132388/")); link.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(de.nexuslobby.utils.LangManager.get("update_download_hover")).create())); player.spigot().sendMessage(link); player.sendMessage(""); } } private void teleportToSpawn(Player player) { FileConfiguration config = getConfig(); if (config.contains("spawn.world")) { String worldName = config.getString("spawn.world"); World world = Bukkit.getWorld(worldName); if (world != null) { Location spawnLoc = new Location( world, config.getDouble("spawn.x"), config.getDouble("spawn.y"), config.getDouble("spawn.z"), (float) config.getDouble("spawn.yaw"), (float) config.getDouble("spawn.pitch") ); player.teleport(spawnLoc); } } } private void initCustomConfigs() { if (!getDataFolder().exists()) getDataFolder().mkdirs(); File configFile = new File(getDataFolder(), "config.yml"); if (!configFile.exists()) saveResource("config.yml", false); reloadConfig(); File settingsFile = new File(getDataFolder(), "settings.yml"); if (!settingsFile.exists()) saveResource("settings.yml", false); visualsFile = new File(getDataFolder(), "visuals.yml"); if (!visualsFile.exists()) saveResource("visuals.yml", false); // lang.yml automatisch erstellen, falls nicht vorhanden File langFile = new File(getDataFolder(), "lang.yml"); if (!langFile.exists()) saveResource("lang.yml", false); reloadVisualsConfig(); Config.load(); } public void reloadVisualsConfig() { if (visualsFile == null) visualsFile = new File(getDataFolder(), "visuals.yml"); visualsConfig = YamlConfiguration.loadConfiguration(visualsFile); } public FileConfiguration getVisualsConfig() { if (visualsConfig == null) reloadVisualsConfig(); return visualsConfig; } @Override public void onDisable() { // Cancle alle Scheduler-Tasks Bukkit.getScheduler().cancelTasks(this); // Stoppe spezifische Tasks ServerChecker.stopGlobalChecker(); // Unregister alle Event-Listener org.bukkit.event.HandlerList.unregisterAll((org.bukkit.plugin.Plugin) this); // Schließe BungeeCord Channel getServer().getMessenger().unregisterOutgoingPluginChannel(this, "BungeeCord"); // Disable alle Module (inkl. eigenes Cleanup) if (moduleManager != null) { moduleManager.disableAll(); } getLogger().info("NexusLobby deaktiviert."); } private void registerCommands() { LobbyTabCompleter tabCompleter = new LobbyTabCompleter(portalManager, hologramModule); NexusLobbyCommand nexusCommand = new NexusLobbyCommand(); if (getCommand("portal") != null) { getCommand("portal").setExecutor(new PortalCommand(portalManager)); getCommand("portal").setTabCompleter(tabCompleter); } if (getCommand("holo") != null) { getCommand("holo").setExecutor(new HoloCommand(hologramModule)); getCommand("holo").setTabCompleter(tabCompleter); } if (getCommand("maintenance") != null) { getCommand("maintenance").setExecutor(new MaintenanceCommand()); getCommand("maintenance").setTabCompleter(tabCompleter); } if (getCommand("giveportalwand") != null) getCommand("giveportalwand").setExecutor(new GivePortalToolCommand(this)); if (getCommand("settings") != null) getCommand("settings").setExecutor(new LobbySettingsCommand(lobbySettingsModule)); if (getCommand("build") != null) getCommand("build").setExecutor(new BuildCommand()); if (getCommand("nexustools") != null) { getCommand("nexustools").setExecutor(new ArmorStandCommand()); getCommand("nexustools").setTabCompleter(tabCompleter); } if (getCommand("nexuscmd") != null) { getCommand("nexuscmd").setExecutor(new ArmorStandCmdExecutor()); getCommand("nexuscmd").setTabCompleter(tabCompleter); } if (getCommand("nexuslobby") != null) { getCommand("nexuslobby").setExecutor(nexusCommand); getCommand("nexuslobby").setTabCompleter(tabCompleter); } if (getCommand("spawn") != null) { getCommand("spawn").setExecutor(nexusCommand); getCommand("spawn").setTabCompleter(tabCompleter); } if (getCommand("setstart") != null) { getCommand("setstart").setExecutor(nexusCommand); getCommand("setstart").setTabCompleter(tabCompleter); } if (getCommand("setcheckpoint") != null) { getCommand("setcheckpoint").setExecutor(nexusCommand); getCommand("setcheckpoint").setTabCompleter(tabCompleter); } if (getCommand("setfinish") != null) { getCommand("setfinish").setExecutor(nexusCommand); getCommand("setfinish").setTabCompleter(tabCompleter); } if (getCommand("mapart") != null) getCommand("mapart").setTabCompleter(tabCompleter); if (getCommand("intro") != null) getCommand("intro").setTabCompleter(tabCompleter); if (getCommand("border") != null) { getCommand("border").setExecutor(new BorderCommand()); getCommand("border").setTabCompleter(tabCompleter); } if (getCommand("serverswitcher") != null) { ServerSwitcherListener serverSwitcher = new ServerSwitcherListener(); getCommand("serverswitcher").setExecutor(serverSwitcher); } } public class NexusLobbyExpansion extends PlaceholderExpansion { @Override public @NotNull String getIdentifier() { return "nexuslobby"; } @Override public @NotNull String getAuthor() { return "M_Viper"; } @Override public @NotNull String getVersion() { return NexusLobby.this.getDescription().getVersion(); } @Override public boolean persist() { return true; } @Override public String onPlaceholderRequest(Player player, @NotNull String params) { if (player == null) return ""; if (params.equalsIgnoreCase("maintenance_status")) return MaintenanceListener.isMaintenance() ? "§cAktiv" : "§aDeaktiviert"; if (params.equalsIgnoreCase("version")) return NexusLobby.this.getDescription().getVersion(); if (params.equalsIgnoreCase("build_mode")) return BuildCommand.isInBuildMode(player) ? "§aAktiv" : "§cInaktiv"; if (params.equalsIgnoreCase("silent_join")) return silentPlayers.contains(player.getUniqueId()) ? "§aEin" : "§cAus"; if (params.equalsIgnoreCase("parkour_top")) { return parkourManager != null ? parkourManager.getTopTen() : "N/A"; } if (params.equalsIgnoreCase("parkour_top_1")) { return parkourManager != null ? parkourManager.getTopTen(1) : "N/A"; } if (params.equalsIgnoreCase("parkour_top_2")) { return parkourManager != null ? parkourManager.getTopTen(2) : "N/A"; } return null; } } public ModuleManager getModuleManager() { return moduleManager; } public PortalManager getPortalManager() { return portalManager; } public TablistModule getTablistModule() { return tablistModule; } public LobbySettingsModule getLobbySettingsModule() { return lobbySettingsModule; } public ItemsModule getItemsModule() { return itemsModule; } public GadgetModule getGadgetModule() { return gadgetModule; } public HologramModule getHologramModule() { return hologramModule; } public DynamicArmorStandModule getDynamicArmorStandModule() { return dynamicArmorStandModule; } public MapArtModule getMapArtModule() { return mapArtModule; } public IntroModule getIntroModule() { return introModule; } public BorderModule getBorderModule() { return borderModule; } }