diff --git a/src/main/java/de/velocityfall/VelocityFall.java b/src/main/java/de/velocityfall/VelocityFall.java new file mode 100644 index 0000000..27b74e6 --- /dev/null +++ b/src/main/java/de/velocityfall/VelocityFall.java @@ -0,0 +1,148 @@ +package de.velocityfall; + +import de.velocityfall.commands.VelocityCommand; +import de.velocityfall.listeners.*; +import de.velocityfall.manager.*; +import de.velocityfall.utils.*; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.ArrayList; +import java.util.HashMap; + +public class VelocityFall extends JavaPlugin { + + private static VelocityFall instance; + public static VelocityFall getInstance() { return instance; } + + public static String prefix; + public static String noperms; + + // Spiel-Daten + public ArrayList ingamePlayers = new ArrayList<>(); + public HashMap arenaPlayersCount = new HashMap<>(); + public HashMap playerArena = new HashMap<>(); + public ArrayList ingameArenas = new ArrayList<>(); + public HashMap cdstarted = new HashMap<>(); + public HashMap arenaCountdown = new HashMap<>(); + public HashMap arenaBlocks = new HashMap<>(); + public HashMap gameStarted = new HashMap<>(); + public ArrayList cooldown = new ArrayList<>(); + public HashMap spectators = new HashMap<>(); + public HashMap checkint = new HashMap<>(); + + // Manager + private ArenaManager arenaManager; + private JoinManager joinManager; + private SignManager signManager; + private MySQLConnector mysqlConnector; + private Configs configs; + private Messages messages; + private Stats stats; + private DisableReset disablereset; + + @Override + public void onEnable() { + instance = this; + + saveDefaultConfig(); + getConfig().options().copyDefaults(true); + saveConfig(); + + prefix = ChatColor.translateAlternateColorCodes('&', getConfig().getString("Prefix", "&6Velocity&fFall &8» ")); + noperms = ChatColor.translateAlternateColorCodes('&', getConfig().getString("NoPermission", "&cKeine Rechte!")); + + ConfigManager.initializeFiles(this); + + this.arenaManager = new ArenaManager(this); + this.joinManager = new JoinManager(this); + this.signManager = new SignManager(this); + this.configs = new Configs(this); + this.messages = new Messages(this); + this.stats = new Stats(this); + this.disablereset = new DisableReset(this); + + configs.createConfigs(); + messages.loadMessages(); + stats.loadStats(); + + if (stats.getStatsConfig().getBoolean("EnableMySQL", false)) { + setupMySQL(); + } + + getCommand("velocityfall").setExecutor(new VelocityCommand(this)); + + Bukkit.getPluginManager().registerEvents(new FloorListener(this), this); + Bukkit.getPluginManager().registerEvents(new FloorLoseListener(this), this); + Bukkit.getPluginManager().registerEvents(new GameListener(this), this); + Bukkit.getPluginManager().registerEvents(new SetupListener(this), this); + Bukkit.getPluginManager().registerEvents(new SignListener(this), this); + + getLogger().info("VelocityFall aktiviert – Version " + getDescription().getVersion()); + } + + private void setupMySQL() { + var cfg = stats.getStatsConfig(); + String host = cfg.getString("MySQL.HOST", "localhost"); + String port = cfg.getString("MySQL.PORT", "3306"); + String db = cfg.getString("MySQL.DATABASE", "minecraft"); + String user = cfg.getString("MySQL.USERNAME", "root"); + String password = cfg.getString("MySQL.PASSWORD", ""); + + this.mysqlConnector = new MySQLConnector(this, host, port, db, user, password); + + mysqlConnector.executeUpdate( + "CREATE TABLE IF NOT EXISTS VelocityFallStats (" + + "UUID varchar(36) PRIMARY KEY, " + + "PLAYED int DEFAULT 0, " + + "LOSE int DEFAULT 0, " + + "WINS int DEFAULT 0" + + ");" + ); + } + + @Override + public void onDisable() { + if (disablereset != null) disablereset.disableReset(); + if (mysqlConnector != null) mysqlConnector.close(); + getLogger().info("VelocityFall deaktiviert"); + } + + public static String getArena(Player p) { + return instance != null ? instance.playerArena.get(p) : null; + } + + public static ArrayList getArenaPlayers(String arena) { + ArrayList list = new ArrayList<>(); + if (instance == null) return list; + instance.playerArena.forEach((player, a) -> { + if (arena.equals(a)) list.add(player); + }); + return list; + } + + public static ArrayList getArenaSpectators(String arena) { + ArrayList list = new ArrayList<>(); + if (instance == null) return list; + instance.spectators.forEach((player, a) -> { + if (arena.equals(a)) list.add(player); + }); + return list; + } + + public ArenaManager getArenaManager() { return arenaManager; } + public JoinManager getJoinManager() { return joinManager; } + public SignManager getSignManager() { return signManager; } + public MySQLConnector getMySQLConnector() { return mysqlConnector; } + public Configs getConfigs() { return configs; } + public Messages getMessages() { return messages; } + public Stats getStats() { return stats; } + + public HashMap getPlayerArenaMap() { return playerArena; } + public HashMap getArenaPlayersCountMap() { return arenaPlayersCount; } + public HashMap getGameStartedMap() { return gameStarted; } + public HashMap getArenaBlocksMap() { return arenaBlocks; } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/commands/VelocityCommand.java b/src/main/java/de/velocityfall/commands/VelocityCommand.java new file mode 100644 index 0000000..9689200 --- /dev/null +++ b/src/main/java/de/velocityfall/commands/VelocityCommand.java @@ -0,0 +1,196 @@ +package de.velocityfall.commands; + +import de.velocityfall.VelocityFall; +import de.velocityfall.manager.GameManager; +import org.bukkit.GameMode; +import org.bukkit.Material; +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; +import org.bukkit.ChatColor; + +import java.util.Arrays; + +public class VelocityCommand implements CommandExecutor { + private final VelocityFall plugin; + + public VelocityCommand(VelocityFall plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player p)) { + sender.sendMessage("Nur Spieler können diesen Befehl nutzen."); + return true; + } + + if (args.length == 0) { + sendHelp(p); + return true; + } + + String action = args[0].toLowerCase(); + + // --- Spieler-Befehle --- + + if (action.equals("join") && args.length == 2) { + plugin.getJoinManager().join(p, args[1]); + return true; + } + + if (action.equals("leave")) { + String arena = VelocityFall.getArena(p); + if (arena == null) { + p.sendMessage(VelocityFall.prefix + "§cDu bist in keiner Arena!"); + return true; + } + + // Entfernen aus Registern + plugin.getPlayerArenaMap().remove(p); + plugin.ingamePlayers.remove(p); + + // Zähler dekrementieren + plugin.getArenaPlayersCountMap().compute(arena, (k, v) -> Math.max(0, (v == null ? 0 : v) - 1)); + + // Siegprüfung (korrekt über GameManager) + GameManager.checkForWinner(arena); + + // Reset Spieler + p.teleport(p.getWorld().getSpawnLocation()); + p.setGameMode(GameMode.SURVIVAL); + p.setAllowFlight(false); + p.setFlying(false); + p.getInventory().clear(); + + p.sendMessage(VelocityFall.prefix + "§eArena verlassen."); + + plugin.getSignManager().updateSign(arena); + return true; + } + + // --- Admin-Befehle --- + + if (!p.hasPermission("velocityfall.admin")) { + p.sendMessage(VelocityFall.prefix + "§cKeine Rechte."); + return true; + } + + var am = plugin.getArenaManager(); + var arenaCfg = am.getArenaConfig(); + + switch (action) { + case "wand": + ItemStack wand = new ItemStack(Material.GOLDEN_AXE); + ItemMeta meta = wand.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.GOLD + "VelocityFall Setup Wand"); + meta.setLore(Arrays.asList( + ChatColor.GRAY + "Linksklick: Pos1 setzen", + ChatColor.GRAY + "Rechtsklick: Pos2 setzen" + )); + wand.setItemMeta(meta); + } + p.getInventory().addItem(wand); + p.sendMessage(VelocityFall.prefix + "§aSetup-Wand erhalten! Nutze Links-/Rechtsklick auf Blöcke."); + break; + + case "savearea": + if (args.length < 2) { + p.sendMessage("§c/vfall savearea "); + break; + } + am.saveArea(p, args[1]); + break; + + case "create": + if (args.length < 2) { + p.sendMessage("§c/vfall create "); + break; + } + arenaCfg.set("Arenas." + args[1] + ".Name", args[1]); + am.saveArenas(); + p.sendMessage(VelocityFall.prefix + "§aArena " + args[1] + " erstellt."); + break; + + case "setlobby": + if (args.length < 2) { + p.sendMessage("§c/vfall setlobby "); + break; + } + arenaCfg.set("Arenas." + args[1] + ".Lobby", p.getLocation()); + am.saveArenas(); + p.sendMessage(VelocityFall.prefix + "§aLobby für " + args[1] + " gesetzt."); + break; + + case "setspawn": + if (args.length < 2) { + p.sendMessage("§c/vfall setspawn "); + break; + } + arenaCfg.set("Arenas." + args[1] + ".Spawn", p.getLocation()); + am.saveArenas(); + p.sendMessage(VelocityFall.prefix + "§aSpawn für " + args[1] + " gesetzt."); + break; + + case "setlose": + if (args.length < 2) { + p.sendMessage("§c/vfall setlose "); + break; + } + arenaCfg.set("Arenas." + args[1] + ".YLose", p.getLocation().getY()); + am.saveArenas(); + p.sendMessage(VelocityFall.prefix + "§aYLose für " + args[1] + " gesetzt."); + break; + + case "setmax": + if (args.length < 3) { + p.sendMessage("§c/vfall setmax "); + break; + } + try { + arenaCfg.set("Arenas." + args[1] + ".Max", Integer.parseInt(args[2])); + am.saveArenas(); + p.sendMessage(VelocityFall.prefix + "§aMax-Spieler für " + args[1] + " auf " + args[2] + " gesetzt."); + } catch (NumberFormatException e) { + p.sendMessage("§cUngültige Zahl."); + } + break; + + case "start": + if (args.length < 2) { + p.sendMessage("§c/vfall start "); + break; + } + p.sendMessage(VelocityFall.prefix + "§6Start erzwungen für " + args[1]); + GameManager.startCountdown(args[1]); + break; + + default: + sendHelp(p); + break; + } + + return true; + } + + private void sendHelp(Player p) { + p.sendMessage("§7--- §6VelocityFall Hilfe §7---"); + p.sendMessage("§e/vfall join §7- Arena betreten"); + p.sendMessage("§e/vfall leave §7- Arena verlassen"); + if (p.hasPermission("velocityfall.admin")) { + p.sendMessage("§6Admin-Befehle:"); + p.sendMessage("§6/vfall wand §7- Setup-Wand holen"); + p.sendMessage("§6/vfall create §7- Arena erstellen"); + p.sendMessage("§6/vfall savearea §7- Bereich speichern"); + p.sendMessage("§6/vfall setlobby §7- Lobby setzen"); + p.sendMessage("§6/vfall setspawn §7- Spawn setzen"); + p.sendMessage("§6/vfall setlose §7- Verlust-Höhe setzen"); + p.sendMessage("§6/vfall setmax §7- Max-Spieler setzen"); + p.sendMessage("§6/vfall start §7- Spiel sofort starten"); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/listeners/FloorListener.java b/src/main/java/de/velocityfall/listeners/FloorListener.java new file mode 100644 index 0000000..6dc6ecc --- /dev/null +++ b/src/main/java/de/velocityfall/listeners/FloorListener.java @@ -0,0 +1,78 @@ +package de.velocityfall.listeners; + +import de.velocityfall.VelocityFall; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashSet; +import java.util.Set; + +public class FloorListener implements Listener { + private final VelocityFall plugin; + private final Set blocksInProcess = new HashSet<>(); + + public FloorListener(VelocityFall plugin) { + this.plugin = plugin; + startBlockChecker(); + } + + private void startBlockChecker() { + new BukkitRunnable() { + @Override + public void run() { + for (Player p : Bukkit.getOnlinePlayers()) { + if (!plugin.ingamePlayers.contains(p)) continue; + + String arena = plugin.getPlayerArenaMap().get(p); + if (arena == null || !plugin.getGameStartedMap().getOrDefault(arena, false)) continue; + + if (p.getGameMode() != GameMode.ADVENTURE && p.getGameMode() != GameMode.SURVIVAL) continue; + + Block b = p.getLocation().subtract(0, 0.1, 0).getBlock(); + + if (b.getType() == Material.AIR || blocksInProcess.contains(b)) continue; + + if (plugin.getArenaManager().isInArenaRegion(arena, b.getLocation())) { + blocksInProcess.add(b); + + Bukkit.getScheduler().runTaskLater(plugin, () -> { + updateBlock(b); + blocksInProcess.remove(b); + }, 10L); // 0.5 Sekunden Delay + } + } + } + }.runTaskTimer(plugin, 0L, 2L); + } + + private void updateBlock(Block b) { + Material current = b.getType(); + + Material next = switch (current) { + case WHITE_TERRACOTTA -> Material.YELLOW_TERRACOTTA; + case YELLOW_TERRACOTTA -> Material.ORANGE_TERRACOTTA; + case ORANGE_TERRACOTTA -> Material.RED_TERRACOTTA; + case RED_TERRACOTTA -> Material.AIR; + default -> null; + }; + + if (next != null) { + if (!plugin.getArenaBlocksMap().containsKey(b)) { + plugin.getArenaBlocksMap().put(b, current.name()); + } + + b.setType(next); + + if (next == Material.AIR) { + b.getWorld().playSound(b.getLocation(), org.bukkit.Sound.BLOCK_NYLIUM_BREAK, 1f, 1f); + } else { + b.getWorld().playSound(b.getLocation(), org.bukkit.Sound.BLOCK_NOTE_BLOCK_CHIME, 0.5f, 2f); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/listeners/FloorLoseListener.java b/src/main/java/de/velocityfall/listeners/FloorLoseListener.java new file mode 100644 index 0000000..3b7b49f --- /dev/null +++ b/src/main/java/de/velocityfall/listeners/FloorLoseListener.java @@ -0,0 +1,101 @@ +package de.velocityfall.listeners; + +import de.velocityfall.VelocityFall; +import de.velocityfall.manager.GameManager; +import de.velocityfall.utils.ScoreboardHelper; +import de.velocityfall.utils.StatsHandler; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.inventory.ItemStack; + +import java.io.IOException; + +public class FloorLoseListener implements Listener { + + private final VelocityFall plugin; + + public FloorLoseListener(VelocityFall plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent e) { + Player p = e.getPlayer(); + if (!plugin.ingamePlayers.contains(p)) return; + + String arena = VelocityFall.getArena(p); + if (arena == null) return; + + Location loc = p.getLocation(); + double minY = plugin.getArenaManager().getMinY(arena); + double buffer = 5.0; // Puffer für mehrstöckige Arenen + + // Verlierer nur, wenn wirklich unter der Arena + Puffer + if (loc.getY() < minY - buffer) { + removePlayerFromGame(p, arena); + GameManager.checkForWinner(arena); + return; + } + + // Optional: Wenn außerhalb der Region und unter MinY + if (!plugin.getArenaManager().isInArenaRegion(arena, loc) && loc.getY() < minY) { + removePlayerFromGame(p, arena); + GameManager.checkForWinner(arena); + } + } + + private void removePlayerFromGame(Player p, String arena) { + var playerArenaMap = plugin.getPlayerArenaMap(); + var arenaPlayersCountMap = plugin.getArenaPlayersCountMap(); + + // Potions entfernen (falls du eine Methode hast) + // methodes.removepotions(p); + + if (plugin.getConfig().getBoolean("SaveInv", false)) { + try { + // methodes.restore(p); + } catch (Exception ex) { + ex.printStackTrace(); + } + } else { + p.getInventory().clear(); + p.getInventory().setArmorContents(null); + + String uuid = p.getUniqueId().toString(); + var saveFile = plugin.getConfigs().getSaveConfig(); + double x = saveFile.getDouble(uuid + ".NoSave.X", p.getWorld().getSpawnLocation().getX()); + double y = saveFile.getDouble(uuid + ".NoSave.Y", p.getWorld().getSpawnLocation().getY()); + double z = saveFile.getDouble(uuid + ".NoSave.Z", p.getWorld().getSpawnLocation().getZ()); + String worldName = saveFile.getString(uuid + ".NoSave.World", p.getWorld().getName()); + + World w = Bukkit.getWorld(worldName); + if (w != null) { + p.teleport(new Location(w, x, y, z)); + } + + saveFile.set(uuid, null); + try { + saveFile.save(plugin.getConfigs().getSaveFile()); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + p.sendMessage(VelocityFall.prefix + ChatColor.translateAlternateColorCodes('&', + plugin.getMessages().getMessagesConfig().getString("LoseMessage", "&cDu bist rausgefallen!"))); + + arenaPlayersCountMap.compute(arena, (k, v) -> (v == null ? 0 : v) - 1); + plugin.ingamePlayers.remove(p); + playerArenaMap.remove(p); + p.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + + ScoreboardHelper.updateAllInArena(arena, true); + plugin.getSignManager().updateSign(arena); + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/listeners/GameListener.java b/src/main/java/de/velocityfall/listeners/GameListener.java new file mode 100644 index 0000000..846852f --- /dev/null +++ b/src/main/java/de/velocityfall/listeners/GameListener.java @@ -0,0 +1,51 @@ +package de.velocityfall.listeners; + +import de.velocityfall.VelocityFall; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class GameListener implements Listener { + private final VelocityFall plugin; + + public GameListener(VelocityFall plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onQuit(PlayerQuitEvent e) { + Player p = e.getPlayer(); + String arena = plugin.getPlayerArenaMap().get(p); + + if (arena == null) return; + + if (plugin.ingamePlayers.contains(p)) { + plugin.ingamePlayers.remove(p); + var countMap = plugin.getArenaPlayersCountMap(); + countMap.compute(arena, (k, v) -> Math.max(0, (v == null ? 0 : v) - 1)); + + Bukkit.getScheduler().runTaskLater(plugin, () -> { + de.velocityfall.manager.GameManager.checkForWinner(arena); + }, 1L); + } + } + + @EventHandler + public void onDamage(EntityDamageEvent e) { + if (!(e.getEntity() instanceof Player p)) return; + if (plugin.ingamePlayers.contains(p)) e.setCancelled(true); + } + + @EventHandler + public void onFood(FoodLevelChangeEvent e) { + if (!(e.getEntity() instanceof Player p)) return; + if (plugin.ingamePlayers.contains(p)) { + e.setCancelled(true); + p.setFoodLevel(20); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/listeners/SetupListener.java b/src/main/java/de/velocityfall/listeners/SetupListener.java new file mode 100644 index 0000000..5c29d8e --- /dev/null +++ b/src/main/java/de/velocityfall/listeners/SetupListener.java @@ -0,0 +1,42 @@ +package de.velocityfall.listeners; + +import de.velocityfall.VelocityFall; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; + +public class SetupListener implements Listener { + private final VelocityFall plugin; + + public SetupListener(VelocityFall plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onInteract(PlayerInteractEvent e) { + if (e.getHand() == EquipmentSlot.OFF_HAND) return; + + ItemStack item = e.getItem(); + if (item == null || item.getType() != Material.GOLDEN_AXE) return; + + if (!item.hasItemMeta() || !item.getItemMeta().getDisplayName().contains("VelocityFall")) return; + + if (!e.getPlayer().hasPermission("velocityfall.admin")) return; + + e.setCancelled(true); + + if (e.getClickedBlock() == null) return; + + if (e.getAction() == Action.LEFT_CLICK_BLOCK) { + plugin.getArenaManager().setPos1(e.getPlayer(), e.getClickedBlock().getLocation()); + e.getPlayer().sendMessage(VelocityFall.prefix + "§ePos1 gesetzt."); + } else if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { + plugin.getArenaManager().setPos2(e.getPlayer(), e.getClickedBlock().getLocation()); + e.getPlayer().sendMessage(VelocityFall.prefix + "§ePos2 gesetzt."); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/listeners/SignListener.java b/src/main/java/de/velocityfall/listeners/SignListener.java new file mode 100644 index 0000000..652d32f --- /dev/null +++ b/src/main/java/de/velocityfall/listeners/SignListener.java @@ -0,0 +1,64 @@ +package de.velocityfall.listeners; + +import de.velocityfall.VelocityFall; +import org.bukkit.block.Sign; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; + +public class SignListener implements Listener { + private final VelocityFall plugin; + + public SignListener(VelocityFall plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onSignChange(SignChangeEvent e) { + String line0 = e.getLine(0); + if (line0 == null || !(line0.equalsIgnoreCase("[VelocityFall]") || line0.equalsIgnoreCase("[LKF]"))) return; + + String arenaName = e.getLine(1); + if (arenaName == null || arenaName.trim().isEmpty()) return; + + var arenaConfig = plugin.getArenaManager().getArenaConfig(); + if (!arenaConfig.contains("Arenas." + arenaName)) { + e.setLine(0, "§4§lFEHLER"); + e.setLine(1, "§cArena nicht"); + e.setLine(2, "§cgefunden!"); + return; + } + + e.setLine(0, "§8§l- §cVelocityFall §8§l-"); + e.setLine(1, "§b" + arenaName); + e.setLine(2, "§aLOBBY"); + + int count = plugin.getArenaPlayersCountMap().getOrDefault(arenaName, 0); + int max = arenaConfig.getInt("Arenas." + arenaName + ".Max", 0); + e.setLine(3, "§8" + count + " §7/ §8" + max); + + arenaConfig.set("Arenas." + arenaName + ".SignLoc", e.getBlock().getLocation()); + plugin.getArenaManager().saveArenas(); + + e.getPlayer().sendMessage(VelocityFall.prefix + "§aSchild erstellt!"); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onSignClick(PlayerInteractEvent e) { + if (e.getAction() != Action.RIGHT_CLICK_BLOCK || e.getClickedBlock() == null) return; + if (!(e.getClickedBlock().getState() instanceof Sign sign)) return; + + if (!sign.getLine(0).contains("VelocityFall")) return; + + e.setCancelled(true); + + String arenaName = sign.getLine(1).replaceAll("§.", ""); + if (arenaName.trim().isEmpty()) return; + + plugin.getJoinManager().join(e.getPlayer(), arenaName); + plugin.getSignManager().updateSign(arenaName); + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/ArenaManager.java b/src/main/java/de/velocityfall/manager/ArenaManager.java new file mode 100644 index 0000000..e9babe1 --- /dev/null +++ b/src/main/java/de/velocityfall/manager/ArenaManager.java @@ -0,0 +1,114 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; +import org.bukkit.Location; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class ArenaManager { + private final VelocityFall plugin; + private final File arenaFile; + private FileConfiguration arenaConfig; + + private final Map pos1Map = new HashMap<>(); + private final Map pos2Map = new HashMap<>(); + + public ArenaManager(VelocityFall plugin) { + this.plugin = plugin; + this.arenaFile = new File(plugin.getDataFolder(), "arenas.yml"); + reloadArenas(); + } + + public void reloadArenas() { + arenaConfig = YamlConfiguration.loadConfiguration(arenaFile); + } + + public void saveArenas() { + try { + arenaConfig.save(arenaFile); + } catch (Exception e) { + plugin.getLogger().severe("Konnte arenas.yml nicht speichern: " + e.getMessage()); + } + } + + public void setPos1(Player player, Location loc) { + pos1Map.put(player.getUniqueId(), loc); + } + + public void setPos2(Player player, Location loc) { + pos2Map.put(player.getUniqueId(), loc); + } + + public void saveArenaRegion(Player player, String arenaName) { + UUID uuid = player.getUniqueId(); + + if (!pos1Map.containsKey(uuid) || !pos2Map.containsKey(uuid)) { + player.sendMessage(VelocityFall.prefix + "§cBeide Punkte müssen gesetzt sein!"); + return; + } + + Location pos1 = pos1Map.get(uuid); + Location pos2 = pos2Map.get(uuid); + + if (pos1.getWorld() == null || !pos1.getWorld().equals(pos2.getWorld())) { + player.sendMessage(VelocityFall.prefix + "§cBeide Punkte müssen in derselben Welt sein!"); + return; + } + + String path = "Arenas." + arenaName + "."; + arenaConfig.set(path + "Pos1", pos1); + arenaConfig.set(path + "Pos2", pos2); + arenaConfig.set(path + "World", pos1.getWorld().getName()); + + // Automatisch MinY berechnen und speichern (wichtig für mehrstöckige Arenen) + double minY = Math.min(pos1.getY(), pos2.getY()); + arenaConfig.set(path + "MinY", minY); + + saveArenas(); + + player.sendMessage(VelocityFall.prefix + "§aArena-Bereich §e" + arenaName + " §agespeichert! (MinY = " + minY + ")"); + + pos1Map.remove(uuid); + pos2Map.remove(uuid); + } + + public void saveArea(Player player, String arenaName) { + saveArenaRegion(player, arenaName); + } + + public boolean isInArenaRegion(String arenaName, Location loc) { + if (loc == null || loc.getWorld() == null) return false; + + String path = "Arenas." + arenaName + "."; + Location p1 = arenaConfig.getLocation(path + "Pos1"); + Location p2 = arenaConfig.getLocation(path + "Pos2"); + + if (p1 == null || p2 == null) return false; + if (!loc.getWorld().equals(p1.getWorld())) return false; + + double minX = Math.min(p1.getX(), p2.getX()); + double maxX = Math.max(p1.getX(), p2.getX()); + double minY = Math.min(p1.getY(), p2.getY()); + double maxY = Math.max(p1.getY(), p2.getY()); + double minZ = Math.min(p1.getZ(), p2.getZ()); + double maxZ = Math.max(p1.getZ(), p2.getZ()); + + return loc.getX() >= minX && loc.getX() <= maxX && + loc.getY() >= minY && loc.getY() <= maxY && + loc.getZ() >= minZ && loc.getZ() <= maxZ; + } + + public double getMinY(String arenaName) { + return arenaConfig.getDouble("Arenas." + arenaName + ".MinY", -100.0); + } + + public FileConfiguration getArenaConfig() { + return arenaConfig; + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/ConfigManager.java b/src/main/java/de/velocityfall/manager/ConfigManager.java new file mode 100644 index 0000000..e253ef8 --- /dev/null +++ b/src/main/java/de/velocityfall/manager/ConfigManager.java @@ -0,0 +1,37 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; + +import java.io.File; +import java.io.IOException; + +public class ConfigManager { + + public static void initializeFiles(VelocityFall plugin) { + if (!plugin.getDataFolder().exists()) { + plugin.getDataFolder().mkdirs(); + } + + plugin.saveDefaultConfig(); + + createIfMissing(plugin, "arenas.yml"); + createIfMissing(plugin, "stats.yml"); + createIfMissing(plugin, "messages.yml"); + createIfMissing(plugin, "saves.yml"); + } + + private static void createIfMissing(VelocityFall plugin, String filename) { + File file = new File(plugin.getDataFolder(), filename); + if (file.exists()) return; + + try { + if (plugin.getResource(filename) != null) { + plugin.saveResource(filename, false); + } else { + file.createNewFile(); + } + } catch (IOException e) { + plugin.getLogger().severe("Konnte " + filename + " nicht erstellen: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/Configs.java b/src/main/java/de/velocityfall/manager/Configs.java new file mode 100644 index 0000000..bbf5a7d --- /dev/null +++ b/src/main/java/de/velocityfall/manager/Configs.java @@ -0,0 +1,64 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; + +public class Configs { + + private final VelocityFall plugin; + private YamlConfiguration arenasConfig; + private YamlConfiguration saveConfig; + private File arenasFile; + private File saveFile; + + public Configs(VelocityFall plugin) { + this.plugin = plugin; + createConfigs(); + loadConfigs(); + } + + public void createConfigs() { + if (!plugin.getDataFolder().exists()) { + plugin.getDataFolder().mkdirs(); + } + + arenasFile = new File(plugin.getDataFolder(), "arenas.yml"); + saveFile = new File(plugin.getDataFolder(), "saves.yml"); + + if (!arenasFile.exists()) { + try { + arenasFile.createNewFile(); + } catch (IOException e) { + plugin.getLogger().severe("Fehler bei arenas.yml: " + e.getMessage()); + } + } + + if (!saveFile.exists()) { + try { + saveFile.createNewFile(); + } catch (IOException e) { + plugin.getLogger().severe("Fehler bei saves.yml: " + e.getMessage()); + } + } + } + + private void loadConfigs() { + arenasConfig = YamlConfiguration.loadConfiguration(arenasFile); + saveConfig = YamlConfiguration.loadConfiguration(saveFile); + } + + public YamlConfiguration getArenasConfig() { + return arenasConfig; + } + + public YamlConfiguration getSaveConfig() { + return saveConfig; + } + + public File getSaveFile() { + return saveFile; + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/DisableReset.java b/src/main/java/de/velocityfall/manager/DisableReset.java new file mode 100644 index 0000000..17b4673 --- /dev/null +++ b/src/main/java/de/velocityfall/manager/DisableReset.java @@ -0,0 +1,16 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; + +public class DisableReset { + + private final VelocityFall plugin; + + public DisableReset(VelocityFall plugin) { + this.plugin = plugin; + } + + public void disableReset() { + plugin.getLogger().info("DisableReset ausgeführt – Plugin heruntergefahren."); + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/GameManager.java b/src/main/java/de/velocityfall/manager/GameManager.java new file mode 100644 index 0000000..c45e636 --- /dev/null +++ b/src/main/java/de/velocityfall/manager/GameManager.java @@ -0,0 +1,126 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; +import de.velocityfall.utils.StatsHandler; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +public class GameManager { + + public static void startArenaCountdown(String arenaName) { + VelocityFall plugin = VelocityFall.getInstance(); + if (plugin.getGameStartedMap().getOrDefault(arenaName, false)) return; + + new BukkitRunnable() { + int timeLeft = plugin.getConfig().getInt("BeforeGameCD", 15); + + @Override + public void run() { + int playerCount = (int) plugin.getPlayerArenaMap().values().stream().filter(arenaName::equals).count(); + + if (playerCount < 1) { + cancel(); + return; + } + + if (timeLeft <= 5 && timeLeft > 0) { + broadcast(arenaName, "§aSpiel startet in §e" + timeLeft + "..."); + } + + if (timeLeft <= 0) { + plugin.getGameStartedMap().put(arenaName, true); + plugin.getArenaPlayersCountMap().put(arenaName, playerCount); + + plugin.getSignManager().updateSign(arenaName); + + broadcast(arenaName, "§6§lDAS SPIEL BEGINNT!"); + + Location spawn = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Spawn"); + + plugin.getPlayerArenaMap().forEach((p, a) -> { + if (arenaName.equals(a)) { + if (spawn != null) p.teleport(spawn); + p.setGameMode(GameMode.ADVENTURE); + p.setAllowFlight(false); + p.playSound(p.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 1f, 1f); + } + }); + cancel(); + } + timeLeft--; + } + }.runTaskTimer(plugin, 0L, 20L); + } + + public static void startCountdown(String arenaName) { + startArenaCountdown(arenaName); + } + + public static void checkForWinner(String arenaName) { + VelocityFall plugin = VelocityFall.getInstance(); + var countMap = plugin.getArenaPlayersCountMap(); + int remaining = countMap.getOrDefault(arenaName, 0); + + if (remaining != 1) return; + + var arenaPlayers = VelocityFall.getArenaPlayers(arenaName); + if (arenaPlayers.isEmpty()) return; + + Player winner = arenaPlayers.get(0); + + winner.sendMessage(VelocityFall.prefix + ChatColor.translateAlternateColorCodes('&', + plugin.getMessages().getMessagesConfig().getString("WinMessage", "&aDu hast gewonnen!"))); + + StatsHandler.addWin(winner.getUniqueId().toString()); + + plugin.ingameArenas.remove(arenaName); + plugin.ingamePlayers.remove(winner); + plugin.getPlayerArenaMap().remove(winner); + countMap.remove(arenaName); + plugin.getGameStartedMap().remove(arenaName); + winner.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + + resetArena(arenaName); + + plugin.getSignManager().updateSign(arenaName); + } + + public static void resetArena(String arenaName) { + VelocityFall plugin = VelocityFall.getInstance(); + + plugin.getArenaBlocksMap().forEach((block, matName) -> block.setType(Material.valueOf(matName))); + plugin.getArenaBlocksMap().clear(); + + plugin.getGameStartedMap().put(arenaName, false); + plugin.getArenaPlayersCountMap().remove(arenaName); + + Location lobby = plugin.getArenaManager().getArenaConfig().getLocation("Arenas." + arenaName + ".Lobby"); + + plugin.getPlayerArenaMap().entrySet().removeIf(e -> { + if (arenaName.equals(e.getValue())) { + Player p = e.getKey(); + p.setGameMode(GameMode.SURVIVAL); + p.getInventory().clear(); + if (lobby != null) p.teleport(lobby); + plugin.ingamePlayers.remove(p); + return true; + } + return false; + }); + + plugin.getSignManager().updateSign(arenaName); + } + + private static void broadcast(String arena, String msg) { + VelocityFall plugin = VelocityFall.getInstance(); + plugin.getPlayerArenaMap().forEach((player, a) -> { + if (arena.equals(a)) player.sendMessage(VelocityFall.prefix + msg); + }); + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/JoinManager.java b/src/main/java/de/velocityfall/manager/JoinManager.java new file mode 100644 index 0000000..d34b35e --- /dev/null +++ b/src/main/java/de/velocityfall/manager/JoinManager.java @@ -0,0 +1,76 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public class JoinManager { + private final VelocityFall plugin; + + public JoinManager(VelocityFall plugin) { + this.plugin = plugin; + } + + public void joinPlayer(Player player, String arenaName) { + var playerArena = plugin.getPlayerArenaMap(); + + if (playerArena.containsKey(player)) { + player.sendMessage(VelocityFall.prefix + "§cBereits in Arena!"); + return; + } + + var arenaConfig = plugin.getArenaManager().getArenaConfig(); + if (!arenaConfig.contains("Arenas." + arenaName)) { + player.sendMessage(VelocityFall.prefix + "§cArena nicht gefunden!"); + return; + } + + Location lobby = arenaConfig.getLocation("Arenas." + arenaName + ".Lobby"); + if (lobby == null) { + player.sendMessage(VelocityFall.prefix + "§cLobby nicht gesetzt!"); + return; + } + + int max = arenaConfig.getInt("Arenas." + arenaName + ".Max", 12); + int current = plugin.getArenaPlayersCountMap().getOrDefault(arenaName, 0); + + if (current >= max) { + player.sendMessage(VelocityFall.prefix + "§cArena voll!"); + return; + } + + playerArena.put(player, arenaName); + plugin.ingamePlayers.add(player); + plugin.getArenaPlayersCountMap().put(arenaName, current + 1); + + player.teleport(lobby); + player.setGameMode(GameMode.ADVENTURE); + player.setAllowFlight(false); + player.setFlying(false); + player.getInventory().clear(); + player.setHealth(20.0); + player.setFoodLevel(20); + + player.sendMessage(VelocityFall.prefix + "§aBeigetreten: §e" + arenaName); + + int min = plugin.getConfig().getInt("MinPlayers", 2); + if (current + 1 >= min && !plugin.getGameStartedMap().getOrDefault(arenaName, false)) { + GameManager.startArenaCountdown(arenaName); + } else { + broadcast(arenaName, "§7Noch " + (min - (current + 1)) + " Spieler benötigt..."); + } + + plugin.getSignManager().updateSign(arenaName); + } + + public void join(Player player, String arenaName) { + joinPlayer(player, arenaName); + } + + private void broadcast(String arena, String msg) { + plugin.getPlayerArenaMap().forEach((p, a) -> { + if (arena.equals(a)) p.sendMessage(VelocityFall.prefix + msg); + }); + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/Messages.java b/src/main/java/de/velocityfall/manager/Messages.java new file mode 100644 index 0000000..17edb29 --- /dev/null +++ b/src/main/java/de/velocityfall/manager/Messages.java @@ -0,0 +1,47 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; + +public class Messages { + + private final VelocityFall plugin; + private YamlConfiguration messagesConfig; + private File messagesFile; + + public Messages(VelocityFall plugin) { + this.plugin = plugin; + createMessagesFile(); + loadMessages(); + } + + private void createMessagesFile() { + if (!plugin.getDataFolder().exists()) { + plugin.getDataFolder().mkdirs(); + } + + messagesFile = new File(plugin.getDataFolder(), "messages.yml"); + if (!messagesFile.exists()) { + try { + messagesFile.createNewFile(); + YamlConfiguration defaultMsg = YamlConfiguration.loadConfiguration(messagesFile); + defaultMsg.set("LoseMessage", "&cDu bist rausgefallen!"); + defaultMsg.set("WinMessage", "&aDu hast gewonnen!"); + defaultMsg.save(messagesFile); + } catch (IOException e) { + plugin.getLogger().severe("Fehler bei messages.yml: " + e.getMessage()); + } + } + } + + public void loadMessages() { + messagesConfig = YamlConfiguration.loadConfiguration(messagesFile); + } + + public YamlConfiguration getMessagesConfig() { + return messagesConfig; + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/MySQLConnector.java b/src/main/java/de/velocityfall/manager/MySQLConnector.java new file mode 100644 index 0000000..d8bf2b2 --- /dev/null +++ b/src/main/java/de/velocityfall/manager/MySQLConnector.java @@ -0,0 +1,64 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class MySQLConnector { + + private Connection connection; + private final String host, port, database, username, password; + private final VelocityFall plugin; + + public MySQLConnector(VelocityFall plugin, String host, String port, String database, String username, String password) { + this.plugin = plugin; + this.host = host; + this.port = port; + this.database = database; + this.username = username; + this.password = password; + connect(); + } + + private void connect() { + try { + String url = "jdbc:mysql://" + host + ":" + port + "/" + database + "?autoReconnect=true&useSSL=false&serverTimezone=UTC"; + connection = DriverManager.getConnection(url, username, password); + plugin.getLogger().info("MySQL verbunden."); + } catch (SQLException e) { + plugin.getLogger().severe("MySQL-Fehler: " + e.getMessage()); + } + } + + public void executeUpdate(String sql, Object... params) { + try (PreparedStatement ps = connection.prepareStatement(sql)) { + for (int i = 0; i < params.length; i++) { + ps.setObject(i + 1, params[i]); + } + ps.executeUpdate(); + } catch (SQLException e) { + plugin.getLogger().warning("Update fehlgeschlagen: " + e.getMessage()); + connect(); + } + } + + public ResultSet executeQuery(String sql, Object... params) throws SQLException { + PreparedStatement ps = connection.prepareStatement(sql); + for (int i = 0; i < params.length; i++) { + ps.setObject(i + 1, params[i]); + } + return ps.executeQuery(); + } + + public void close() { + try { + if (connection != null && !connection.isClosed()) connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/SignManager.java b/src/main/java/de/velocityfall/manager/SignManager.java new file mode 100644 index 0000000..d68fa1b --- /dev/null +++ b/src/main/java/de/velocityfall/manager/SignManager.java @@ -0,0 +1,30 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; +import org.bukkit.Location; +import org.bukkit.block.Sign; + +public class SignManager { + private final VelocityFall plugin; + + public SignManager(VelocityFall plugin) { + this.plugin = plugin; + } + + public void updateSign(String arenaName) { + var arenaConfig = plugin.getArenaManager().getArenaConfig(); + Location signLoc = arenaConfig.getLocation("Arenas." + arenaName + ".SignLoc"); + + if (signLoc == null || !(signLoc.getBlock().getState() instanceof Sign sign)) return; + + int count = plugin.getArenaPlayersCountMap().getOrDefault(arenaName, 0); + int max = arenaConfig.getInt("Arenas." + arenaName + ".Max", 0); + + sign.setLine(0, "§8§l- §cVelocityFall §8§l-"); + sign.setLine(1, "§b" + arenaName); + sign.setLine(2, plugin.getGameStartedMap().getOrDefault(arenaName, false) ? "§cINGAME" : "§aLOBBY"); + sign.setLine(3, "§8" + count + "§7/§8" + max); + + sign.update(true, false); + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/manager/Stats.java b/src/main/java/de/velocityfall/manager/Stats.java new file mode 100644 index 0000000..5fc0fdd --- /dev/null +++ b/src/main/java/de/velocityfall/manager/Stats.java @@ -0,0 +1,51 @@ +package de.velocityfall.manager; + +import de.velocityfall.VelocityFall; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; + +public class Stats { + + private final VelocityFall plugin; + private YamlConfiguration statsConfig; + private File statsFile; + + public Stats(VelocityFall plugin) { + this.plugin = plugin; + createStatsFile(); + loadStats(); + } + + private void createStatsFile() { + if (!plugin.getDataFolder().exists()) { + plugin.getDataFolder().mkdirs(); + } + + statsFile = new File(plugin.getDataFolder(), "stats.yml"); + if (!statsFile.exists()) { + try { + statsFile.createNewFile(); + YamlConfiguration defaultStats = YamlConfiguration.loadConfiguration(statsFile); + defaultStats.set("EnableMySQL", false); + defaultStats.set("MySQL.HOST", "localhost"); + defaultStats.set("MySQL.PORT", "3306"); + defaultStats.set("MySQL.DATABASE", "minecraft"); + defaultStats.set("MySQL.USERNAME", "root"); + defaultStats.set("MySQL.PASSWORD", ""); + defaultStats.save(statsFile); + } catch (IOException e) { + plugin.getLogger().severe("Fehler bei stats.yml: " + e.getMessage()); + } + } + } + + public void loadStats() { + statsConfig = YamlConfiguration.loadConfiguration(statsFile); + } + + public YamlConfiguration getStatsConfig() { + return statsConfig; + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/utils/ScoreboardHelper.java b/src/main/java/de/velocityfall/utils/ScoreboardHelper.java new file mode 100644 index 0000000..32ed748 --- /dev/null +++ b/src/main/java/de/velocityfall/utils/ScoreboardHelper.java @@ -0,0 +1,45 @@ +package de.velocityfall.utils; + +import de.velocityfall.VelocityFall; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.*; + +import java.util.List; + +public class ScoreboardHelper { + + public static void updateBoard(Player player, String arenaName, boolean isIngame) { + VelocityFall plugin = VelocityFall.getInstance(); + + Scoreboard board = Bukkit.getScoreboardManager().getNewScoreboard(); + String titlePath = isIngame ? "InGameScoreBoardTitle" : "LobbyScoreBoardTitle"; + String title = ChatColor.translateAlternateColorCodes('&', plugin.getConfig().getString(titlePath, "&6VelocityFall")); + + Objective objective = board.registerNewObjective("vfall", Criteria.DUMMY, title); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + + String listPath = isIngame ? "InGameScoreBoard" : "LobbyScoreBoard"; + List lines = plugin.getConfig().getStringList(listPath); + + int scoreValue = lines.size(); + for (String rawLine : lines) { + String line = ChatColor.translateAlternateColorCodes('&', rawLine + .replace("%arena%", arenaName != null ? arenaName : "???") + .replace("%players%", String.valueOf(plugin.getArenaPlayersCountMap().getOrDefault(arenaName, 0))) + .replace("%max%", String.valueOf(plugin.getArenaManager().getArenaConfig().getInt("Arenas." + arenaName + ".Max", 0)))); + + objective.getScore(line).setScore(scoreValue--); + } + + player.setScoreboard(board); + } + + public static void updateAllInArena(String arenaName, boolean isIngame) { + VelocityFall plugin = VelocityFall.getInstance(); + plugin.getPlayerArenaMap().forEach((p, a) -> { + if (arenaName.equals(a)) updateBoard(p, arenaName, isIngame); + }); + } +} \ No newline at end of file diff --git a/src/main/java/de/velocityfall/utils/StatsHandler.java b/src/main/java/de/velocityfall/utils/StatsHandler.java new file mode 100644 index 0000000..88ae875 --- /dev/null +++ b/src/main/java/de/velocityfall/utils/StatsHandler.java @@ -0,0 +1,57 @@ +package de.velocityfall.utils; + +import de.velocityfall.VelocityFall; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class StatsHandler { + + public static void addWin(String uuid) { + addStat(uuid, "WINS"); + } + + public static void addLose(String uuid) { + addStat(uuid, "LOSE"); + } + + private static void addStat(String uuid, String column) { + VelocityFall plugin = VelocityFall.getInstance(); + if (plugin.getStats().getStatsConfig().getBoolean("EnableMySQL", false)) { + plugin.getMySQLConnector().executeUpdate( + "UPDATE VelocityFallStats SET " + column + " = " + column + " + 1 WHERE UUID = ?", + uuid + ); + } else { + File file = new File(plugin.getDataFolder(), "stats.yml"); + YamlConfiguration cfg = YamlConfiguration.loadConfiguration(file); + cfg.set(uuid + "." + column, cfg.getInt(uuid + "." + column, 0) + 1); + try { + cfg.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static int getWins(String uuid) { + return getStat(uuid, "WINS"); + } + + private static int getStat(String uuid, String column) { + VelocityFall plugin = VelocityFall.getInstance(); + if (plugin.getStats().getStatsConfig().getBoolean("EnableMySQL", false)) { + try (ResultSet rs = plugin.getMySQLConnector().executeQuery( + "SELECT " + column + " FROM VelocityFallStats WHERE UUID = ?", uuid)) { + if (rs.next()) return rs.getInt(column); + } catch (SQLException e) { + e.printStackTrace(); + } + } + File file = new File(plugin.getDataFolder(), "stats.yml"); + return YamlConfiguration.loadConfiguration(file).getInt(uuid + "." + column, 0); + } +} \ No newline at end of file diff --git a/src/main/resources/arenas.yml b/src/main/resources/arenas.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..f8cb624 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,26 @@ +Prefix: '&c[VelocityFall] ' +BeforeGameCD: 15 +CountdownSound: ENTITY_EXPERIENCE_ORB_PICKUP +SaveInv: true +WinCommands: + - eco give %player% 10 + - msg %player% Du hast gewonnen! +CmdWhitelist: + - /vfall leave + - /tell +MySQL: + Enable: false + Host: localhost + Port: '3306' + Database: vfall + User: root + Password: '' +LobbyScoreBoardTitle: '&6&lVelocityFall' +InGameScoreBoardTitle: '&6&lVelocityFall' +LobbyScoreBoard: + - '&7---' + - '&eArena:' + - '&f%arena%' + - '&7' + - '&eSpieler:' + - '&f%players%' \ No newline at end of file diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml new file mode 100644 index 0000000..f5dda15 --- /dev/null +++ b/src/main/resources/messages.yml @@ -0,0 +1,7 @@ +NoPerm: '&cDazu hast du keine Rechte!' +AlreadyIngame: '&cDu bist bereits in einem Spiel!' +ArenaFull: '&cDiese Arena ist voll!' +CountdownMessage: '&aDas Spiel startet in &e%time% &aSekunden!' +WinMessage: '&6Glückwunsch! Du hast gewonnen!' +NotInArena: '&cDu bist in keiner Arena!' +LeaveMessage: '&e%player% &7hat das Spiel verlassen!' \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..dad2995 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,9 @@ +name: VelocityFall +version: 1.0.0 +main: de.velocityfall.VelocityFall +api-version: 1.21 +author: M_Viper +commands: + velocityfall: + aliases: [vfall, lkf] + description: Hauptbefehl für VelocityFall \ No newline at end of file diff --git a/src/main/resources/stats.yml b/src/main/resources/stats.yml new file mode 100644 index 0000000..e69de29