From e864d4cbc8f5d6f5f66034c349442397b97b98c0 Mon Sep 17 00:00:00 2001 From: pinont Date: Fri, 27 Sep 2024 23:20:41 +0700 Subject: [PATCH] Bug fixed patch: - Fixed mobs not spawning at player - Player is not begin tick when random ticking - Fixing Duplicated message when sending to all players WIP: player level requirement for summon mobs at target player Known bug: Glowing Effect is not giving to a player --- .../Commands/CommandHandler.java | 35 ++++-- .../pinont/elitebossevent/Config/Lang.java | 2 +- .../pinont/elitebossevent/EliteBossEvent.java | 19 +++- .../Listeners/PlayerListener.java | 36 +++++++ .../elitebossevent/Tasks/SummonMobTask.java | 101 +++++++++++------- .../elitebossevent/Utils/Message/Reply.java | 1 - .../Utils/MobsManager/SummonManager.java | 2 +- src/main/resources/config.yml | 8 +- src/main/resources/lang.yml | 2 +- 9 files changed, 148 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/pinont/elitebossevent/Listeners/PlayerListener.java diff --git a/src/main/java/com/pinont/elitebossevent/Commands/CommandHandler.java b/src/main/java/com/pinont/elitebossevent/Commands/CommandHandler.java index 261ce80..7118632 100644 --- a/src/main/java/com/pinont/elitebossevent/Commands/CommandHandler.java +++ b/src/main/java/com/pinont/elitebossevent/Commands/CommandHandler.java @@ -14,6 +14,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -23,18 +24,23 @@ public class CommandHandler implements CommandExecutor, TabCompleter { EliteBossEvent main = EliteBossEvent.getInstance(); - SummonMobTask summonMobTask = new SummonMobTask(); + SummonMobTask summonMobTask = main.summonMobTask; boolean bypass_perm = main.getConfig().getBoolean("debug.bypass-permission"); public CommandHandler() { - commandList.put("reload", "elitebossevent.reload"); + commandList.put("reload", "elitebossevent.admin"); commandList.put("start", "elitebossevent.admin"); commandList.put("stop", "elitebossevent.admin"); + commandList.put("delay-status", "elitebossevent.admin"); } @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (main.debug) { + new Debug("Command: " + command.getName() + " Label: " + label + " Args: " + Arrays.toString(args), Debug.DebugType.BOTH); + new Debug("Bypass permission: " + bypass_perm, Debug.DebugType.BOTH); + } if (args.length == 0) { return false; } @@ -45,9 +51,15 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command switch (args[0]) { case "reload": if (sender.hasPermission(commandList.get(args[0])) || bypass_perm) { + if (summonMobTask.scheduleTask != null) { + summonMobTask.scheduleTask.cancel(); + } else { + new Debug("Task is null or not scheduling", Debug.DebugType.WARNING); + } main.reloadConfig(); new Reply(Reply.SenderType.CONSOLE, Lang.RELOAD.toString()); new Reply("elitebossevent.notify", Lang.RELOAD.toString()); + main.executeTask(); } else { new Reply(sender, Lang.NO_PERMISSION.toString()); } @@ -60,13 +72,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command count = 0; } } - new Debug("Max Ticked player count: " + summonMobTask.getMaxTickedPlayers(), Debug.DebugType.INFO); - for (int i = 0; i >= summonMobTask.getMaxTickedPlayers() && i < Bukkit.getOnlinePlayers().size(); i++) { - Player p = (Player) Bukkit.getOnlinePlayers().toArray()[i]; - summonMobTask.addTickPlayer(p); - } summonMobTask.summonMob(count); - new Reply(Reply.SenderType.ALLPLAYER, Lang.ELITE_EVENT_STARTED.toString()); } else { new Reply(sender, Lang.NO_PERMISSION.toString()); } @@ -77,6 +83,14 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } else { new Reply(sender, Lang.NO_PERMISSION.toString()); } + break; + case "delay-status": + if (sender.hasPermission(commandList.get(args[0])) || bypass_perm) { + new Reply(sender, "Delay status: " + summonMobTask.getDelayStatus()); + } else { + new Reply(sender, Lang.NO_PERMISSION.toString()); + } + break; default: new Reply(sender, Lang.INVALID_COMMAND.toString()); break; @@ -88,6 +102,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command @Nullable @Override public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) { - return List.of(commandList.keySet().toArray(new String[0])); + if ((commandSender.hasPermission("elitebossevent.admin") || bypass_perm) && strings.length == 0) { + return List.of(commandList.keySet().toArray(new String[0])); + } + return null; } } diff --git a/src/main/java/com/pinont/elitebossevent/Config/Lang.java b/src/main/java/com/pinont/elitebossevent/Config/Lang.java index ccf9625..caed6a8 100644 --- a/src/main/java/com/pinont/elitebossevent/Config/Lang.java +++ b/src/main/java/com/pinont/elitebossevent/Config/Lang.java @@ -28,7 +28,7 @@ public enum Lang { ELITE_EVENT_STARTED("elite_event_started", "Elite Boss Event has started!"), ELITE_EVENT_STOPPED("elite_event_stopped", "Elite Boss Event has stopped!"), ELITE_EVENT_STARTING("elite_event_starting", "Mob will be summoned in seconds!"), - NO_PLAYER_TICKED("no_player_ticked", "No player ticked, mob will not be summoned!"), + NO_PLAYER_TICKED("no_player_ticked", "No player was ticked, mob will not be summoned!"), SUMMON_MOB("summon_mob", "Mob has been summoned!"), SUMMON_NOTIFY("summon_notify", "Mob will be summoned at a certain player seconds!"), WARNING_PLAYER("warning_player", "Please avoid a player with a glowing effect!"), diff --git a/src/main/java/com/pinont/elitebossevent/EliteBossEvent.java b/src/main/java/com/pinont/elitebossevent/EliteBossEvent.java index c0aa62a..5e68907 100644 --- a/src/main/java/com/pinont/elitebossevent/EliteBossEvent.java +++ b/src/main/java/com/pinont/elitebossevent/EliteBossEvent.java @@ -4,9 +4,11 @@ import com.pinont.elitebossevent.Config.Lang; import com.pinont.elitebossevent.Hooks.MythicMobsAPI; import com.pinont.elitebossevent.Listeners.EntityListener; +import com.pinont.elitebossevent.Listeners.PlayerListener; import com.pinont.elitebossevent.Tasks.SummonMobTask; import com.pinont.elitebossevent.Utils.Message.Debug; import com.pinont.elitebossevent.Utils.Message.Debug.DebugType; +import org.bukkit.ChatColor; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; @@ -26,6 +28,7 @@ public class EliteBossEvent extends JavaPlugin { private static EliteBossEvent instance; public static YamlConfiguration LANG; public static File LANG_FILE; + public SummonMobTask summonMobTask; public EliteBossEvent() {super();} @@ -36,8 +39,16 @@ protected EliteBossEvent(JavaPluginLoader loader, PluginDescriptionFile descript @Override public void onEnable() { + this.getLogger().info( + "\n" + ChatColor.GREEN +"___________.__ .__ __ __________ ___________ __ \n" + + ChatColor.GREEN +"\\_ _____/| | |__|/ |_ ____\\______ \\ ____ ______ _____\\_ _____/__ __ ____ _____/ |_ \n" + + ChatColor.GREEN +" | __)_ | | | \\ __\\/ __ \\| | _// _ \\/ ___// ___/| __)_\\ \\/ // __ \\ / \\ __\\\n" + + ChatColor.GREEN +" | \\| |_| || | \\ ___/| | ( <_> )___ \\ \\___ \\ | \\\\ /\\ ___/| | \\ | \n" + + ChatColor.GREEN +"/_______ /|____/__||__| \\___ >______ /\\____/____ >____ >_______ / \\_/ \\___ >___| /__| \n" + + ChatColor.GREEN +" \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ "); instance = this; log = this.getLogger(); + summonMobTask = new SummonMobTask(); loadLang(); LANG = YamlConfiguration.loadConfiguration(LANG_FILE); LANG_FILE = new File(getDataFolder(), "lang.yml"); @@ -65,6 +76,7 @@ private void loadConfig() { private void registerListeners() { getServer().getPluginManager().registerEvents(new EntityListener(), this); + getServer().getPluginManager().registerEvents(new PlayerListener(), this); } private void registerCommands() { @@ -72,8 +84,13 @@ private void registerCommands() { Objects.requireNonNull(getServer().getPluginCommand("eliteboss")).setTabCompleter(new CommandHandler()); } - private void executeTask() { + public void executeTask() { new SummonMobTask().start(); + new Debug("\n======== Summon Task Execution ========\n" + + "Using seconds as a ticks: " + this.getConfig().getBoolean("debug.change-delay-to-sec") + "\n" + + "Minimum player Required for spawning: " + this.getConfig().getInt("summon-rules.min-players") + "\n" + + "Summon Type: " + this.getConfig().getString("summon-rules.mob-type") + + "\n=======================================", DebugType.INFO); } public static EliteBossEvent getInstance() { diff --git a/src/main/java/com/pinont/elitebossevent/Listeners/PlayerListener.java b/src/main/java/com/pinont/elitebossevent/Listeners/PlayerListener.java new file mode 100644 index 0000000..6390fb1 --- /dev/null +++ b/src/main/java/com/pinont/elitebossevent/Listeners/PlayerListener.java @@ -0,0 +1,36 @@ +package com.pinont.elitebossevent.Listeners; + +import com.pinont.elitebossevent.EliteBossEvent; +import com.pinont.elitebossevent.Tasks.SummonMobTask; +import com.pinont.elitebossevent.Utils.Message.Reply; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class PlayerListener implements Listener { + + SummonMobTask summonMobTask = EliteBossEvent.getInstance().summonMobTask; + EliteBossEvent main = EliteBossEvent.getInstance(); + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (Bukkit.getOnlinePlayers().size() == 1) { + new Reply(Reply.SenderType.CONSOLE, "Minimum players reached, Elite event is resuming!"); + main.executeTask(); + } + summonMobTask.updateMaxTickedPlayers(); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (Bukkit.getOnlinePlayers().isEmpty() || main.getConfig().getInt("elite-boss-event.min-players") > Bukkit.getOnlinePlayers().size()) { + new Reply(Reply.SenderType.CONSOLE, "Online players are less than minimum players required, Elite event is pausing!"); + summonMobTask.stop(); + return; + } + summonMobTask.updateMaxTickedPlayers(); + } + +} diff --git a/src/main/java/com/pinont/elitebossevent/Tasks/SummonMobTask.java b/src/main/java/com/pinont/elitebossevent/Tasks/SummonMobTask.java index cc96933..8516794 100644 --- a/src/main/java/com/pinont/elitebossevent/Tasks/SummonMobTask.java +++ b/src/main/java/com/pinont/elitebossevent/Tasks/SummonMobTask.java @@ -6,6 +6,7 @@ import com.pinont.elitebossevent.Utils.Message.Reply; import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; @@ -16,102 +17,120 @@ public class SummonMobTask { + int ticks = 0; + public BukkitTask scheduleTask; + private final EliteBossEvent main = EliteBossEvent.getInstance(); - public final Map tickedPlayers = new HashMap<>(); + public final ArrayList tickedPlayers = new ArrayList<>(); public int maxTickedPlayers; private BukkitTask task; - public void addTickPlayer(Player player) { - tickedPlayers.put(player, 0); - new Debug("Player " + player.getName() + " has been ticked!", Debug.DebugType.BOTH); - new Debug("Ticked players" + getTickedPlayers()); - } - - public void removeTickPlayer(Player pLayer) { - tickedPlayers.remove(pLayer); - new Debug("Player " + pLayer.getName() + " has been removed from ticked list!", Debug.DebugType.BOTH); - } - public void clearTickPlayers() { tickedPlayers.clear(); new Debug("All players have been removed from ticked list!", Debug.DebugType.BOTH); } - public HashMap getTickedPlayers() { - return (HashMap) tickedPlayers; + public ArrayList getTickedPlayers() { + for (int i = 0; i <= updateMaxTickedPlayers() && i <= (Bukkit.getOnlinePlayers().size() + 1); i++) { + new Debug("Start ticking player " + (i + 1) + "/" + maxTickedPlayers, Debug.DebugType.BOTH); + Player player = getRandomOnlinePlayer(); + if (player == null) { + new Debug("Player is null!", Debug.DebugType.BOTH); + continue; + } + new Debug("Player " + player.getName() + " has been ticked!", Debug.DebugType.BOTH); + if (tickedPlayers.size() >= maxTickedPlayers) { + new Debug("Max ticked players reached!", Debug.DebugType.BOTH); + break; + } + if (tickedPlayers.contains(player)) { + new Debug("Player " + player.getName() + " has already been ticked!", Debug.DebugType.BOTH); + continue; + } + tickedPlayers.add(player); + // notify player + new Reply(player, Objects.requireNonNull(Lang.SUMMON_NOTIFY.toString().replace("", "30"))); + new Reply(Reply.SenderType.ALLPLAYER, Objects.requireNonNull(Lang.WARNING_PLAYER.toString())); + Bukkit.getScheduler().runTask(main, () -> { + for (Player p : tickedPlayers) { + p.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 30, 1, true, false, true)); + } + }); + } + new Debug("Ticked players: " + tickedPlayers, Debug.DebugType.BOTH); + return tickedPlayers; } - public int getMaxTickedPlayers() { + public int updateMaxTickedPlayers() { int configMaxPlayers = main.getConfig().getInt("summon-rules.max-players"); if (configMaxPlayers == 0) { - maxTickedPlayers = Bukkit.getOnlinePlayers().size() / 2; + maxTickedPlayers = (Bukkit.getOnlinePlayers().size() / 2) + 1; } else { maxTickedPlayers = configMaxPlayers; } + new Debug("Max ticked players: " + maxTickedPlayers, Debug.DebugType.BOTH); return maxTickedPlayers; } + public Player getRandomOnlinePlayer() { + Random random = new Random(); + List onlinePlayers = List.copyOf(Bukkit.getOnlinePlayers()); + if (onlinePlayers.isEmpty()) { + return null; // or handle the case when no players are online + } + int randomIndex = random.nextInt(onlinePlayers.size()); + return onlinePlayers.get(randomIndex); + } + public void start() { int delay = main.getConfig().getInt("summon-rules.event-delay"); boolean seconds = main.getConfig().getBoolean("debug.change-delay-to-sec"); + ticks = delay; if (delay < 1) { main.getLogger().warning(Lang.WARN_LOW_DELAY.toString()); delay = 10; } int period = seconds ? delay * 20 : delay * 1200; - new BukkitRunnable() { + scheduleTask = new BukkitRunnable() { @Override public void run() { if (main.getConfig().getInt("summon-rules.min-players") > Bukkit.getOnlinePlayers().size()) { + new Reply(Reply.SenderType.CONSOLE, "No player online, pausing event..."); cancel(); return; } - for (int i = 0; i >= maxTickedPlayers && i < Bukkit.getOnlinePlayers().size(); i++) { - Random random = new Random(); - Player player = Bukkit.getOnlinePlayers().toArray(new Player[0])[random.nextInt(Bukkit.getOnlinePlayers().size())]; - if (tickedPlayers.size() >= maxTickedPlayers) { - break; - } - if (tickedPlayers.containsKey(player)) { - continue; - } - tickedPlayers.put(player, 0); - // notify player - new Reply(player, Objects.requireNonNull(Lang.SUMMON_NOTIFY.toString().replace("", "30"))); - new Reply(Reply.SenderType.ALLPLAYER, Objects.requireNonNull(Lang.WARNING_PLAYER.toString())); - for (Player tickedPlayer : tickedPlayers.keySet()) { - tickedPlayer.addPotionEffect(PotionEffectType.GLOWING.createEffect(30 * 20, 1)); - } - } summonMob(30); } - }.runTaskTimerAsynchronously(main, 0, period); + }.runTaskTimerAsynchronously(main, 5 * 30 * 20, period); + new Debug("Task has been scheduled! [" + scheduleTask.getTaskId() + "]", Debug.DebugType.INFO); } public void summonMob(int countDown) { final int[] count = {countDown}; + new Reply(Reply.SenderType.ALLPLAYER, Objects.requireNonNull(Lang.ELITE_EVENT_STARTING.toString().replace("", String.valueOf(count[0])))); // delay 10 sec and notify player every sec before summoning mob new Reply(Reply.SenderType.BOTH, Objects.requireNonNull(Lang.SUMMON_NOTIFY.toString().replace("", "30"))); task = new BukkitRunnable() { @Override public void run() { if (count[0] == 0) { - if (tickedPlayers.isEmpty()) { + ArrayList targetedPlayers = getTickedPlayers(); + if (targetedPlayers.isEmpty()) { new Reply(Reply.SenderType.BOTH, Lang.NO_PLAYER_TICKED.toString()); cancel(); return; } new Reply(Reply.SenderType.BOTH, Lang.SUMMON_MOB.toString()); - spawnAtPlayer(new ArrayList<>(tickedPlayers.keySet())); + spawnAtPlayer(targetedPlayers); tickedPlayers.clear(); cancel(); return; } - new Reply(Reply.SenderType.BOTH, Objects.requireNonNull(Lang.ELITE_EVENT_STARTING.toString().replace("", String.valueOf(count[0])))); + if (count[0] <= 5) new Reply(Reply.SenderType.ALLPLAYER, Objects.requireNonNull(Lang.ELITE_EVENT_STARTING.toString().replace("", String.valueOf(count[0])))); count[0]--; } - }.runTaskTimerAsynchronously(main, 0, 20); + }.runTaskTimerAsynchronously(main, 20, 20); } public void stop() { @@ -119,4 +138,8 @@ public void stop() { task.cancel(); new Reply(Reply.SenderType.ALLPLAYER, Lang.ELITE_EVENT_STOPPED.toString()); } + + public int getDelayStatus() { + return ticks; + } } diff --git a/src/main/java/com/pinont/elitebossevent/Utils/Message/Reply.java b/src/main/java/com/pinont/elitebossevent/Utils/Message/Reply.java index 4db5e13..aafa673 100644 --- a/src/main/java/com/pinont/elitebossevent/Utils/Message/Reply.java +++ b/src/main/java/com/pinont/elitebossevent/Utils/Message/Reply.java @@ -29,7 +29,6 @@ public Reply(SenderType type, String message) { } } } else if (SenderType.ALLPLAYER.equals(type)) { - getServer().broadcastMessage(message); if (!getServer().getOnlinePlayers().isEmpty()) { for (Player player : getServer().getOnlinePlayers()) { player.sendMessage(message); diff --git a/src/main/java/com/pinont/elitebossevent/Utils/MobsManager/SummonManager.java b/src/main/java/com/pinont/elitebossevent/Utils/MobsManager/SummonManager.java index a0cb964..3ae3786 100644 --- a/src/main/java/com/pinont/elitebossevent/Utils/MobsManager/SummonManager.java +++ b/src/main/java/com/pinont/elitebossevent/Utils/MobsManager/SummonManager.java @@ -26,7 +26,7 @@ public class SummonManager { private static final int distance = main.getConfig().getInt("summon-rules.distance"); - public static void spawnAtPlayer(List players) { + public static void spawnAtPlayer(ArrayList players) { HashMap playerMap = new HashMap<>(); for (Player player : players) { playerMap.put(player, 0); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2bbbb9a..179e320 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ debug: # recommended to set this to false if you don't know what you're doing enabled: false - # recommended to set a value to 10 or higher for better performance + # recommended to set event-delay value to 60 or higher for better performance change-delay-to-sec: false # bypass-permission for debug mode bypass-permission: false @@ -54,15 +54,13 @@ summon-rules: # Max boss spawn count per world (default: 1) max-boss-spawn-count-per-world: 1 # Check level requirement (default: false) - check-level-requirement: false +# (WIP) check-level-requirement: false # Level requirement for player when boss is about to spawn (default: 1) - level-requirement: 10 +# (WIP) level-requirement: 1 # Check permission requirement (default: false) check-permission-requirement: false # Boss spawn chance (default: 0.1) boss-spawn-chance: 0.1 - # Include normal mobs when spawning? (default: false) - use-vanilla-mobs: false # delay in minutes before the event starts (default: 10) event-delay: 10 # what y level for starting pick a player and spawning mobs (default: 64) diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index af28213..c2907fa 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -13,7 +13,7 @@ invalid_command: "Invalid command!" elite_event_started: "Elite Boss Event has started!" elite_event_stopped: "Elite Boss Event has stopped!" elite_event_starting: "Mob will be summoned in seconds!" -no_player_ticked: "No player ticked, mob will not be summoned!" +no_player_ticked: "No player was ticked, mob will not be summoned!" summon_mob: "Mob has been summoned!" summon_notify: "Mob will be summoned at a certain player seconds!" warning_player: "Please avoid a player with a glowing effect!"