PvP Minigame Error

Discussion in 'Spigot Plugin Development' started by HexLazer205, Jul 1, 2015.

Thread Status:
Not open for further replies.
  1. Hi, I've spent all day trying to code a fun minigame me and some friends can play on my server. So far, it's fully functional and doesn't break, and I've been able to fix all my errors... except for this one. The problem is, it only occurs when 1 player attempts to play. When multiple are playing, the error doesn't occur. I have a simple system built in to end the game when it starts with only 1 or less players. It is fully functional, until after where I stare at the console and find every second a stack trace error is popping up.

    I tracked the pieces of code causing these stack traces, and for an odd reason, it appears it is not cancelling the tasks that give each player an item every so seconds during the game, depending on the kit they selected. I never have this problem when multiple players are playing.

    Here is my main class (probably a bit messy):
    Code (Text):

    import java.util.HashMap;



    import org.bukkit.Bukkit;

    import org.bukkit.GameMode;

    import org.bukkit.Location;

    import org.bukkit.Material;

    import org.bukkit.Sound;

    import org.bukkit.command.Command;

    import org.bukkit.command.CommandSender;

    import org.bukkit.entity.Entity;

    import org.bukkit.entity.EntityType;

    import org.bukkit.entity.Player;

    import org.bukkit.entity.Zombie;

    import org.bukkit.event.EventHandler;

    import org.bukkit.event.Listener;

    import org.bukkit.event.block.Action;

    import org.bukkit.event.block.BlockBreakEvent;

    import org.bukkit.event.block.BlockPlaceEvent;

    import org.bukkit.event.entity.EntityDamageEvent;

    import org.bukkit.event.entity.EntityExplodeEvent;

    import org.bukkit.event.entity.PlayerDeathEvent;

    import org.bukkit.event.entity.ProjectileHitEvent;

    import org.bukkit.event.inventory.InventoryClickEvent;

    import org.bukkit.event.player.AsyncPlayerChatEvent;

    import org.bukkit.event.player.PlayerDropItemEvent;

    import org.bukkit.event.player.PlayerEggThrowEvent;

    import org.bukkit.event.player.PlayerInteractEvent;

    import org.bukkit.event.player.PlayerJoinEvent;

    import org.bukkit.event.player.PlayerQuitEvent;

    import org.bukkit.event.player.PlayerRespawnEvent;

    import org.bukkit.inventory.ItemStack;

    import org.bukkit.plugin.java.JavaPlugin;

    import org.w3c.dom.events.EventException;



    public class Minigame extends JavaPlugin implements Listener {

       

        private HashMap<String, Player> winner = new HashMap<>();

       

        privatestaticbooleangameInProgress = false;

        privatestaticbooleangameIsStarting = false;

       

        privatestaticbooleannotEnoughPlayers = false;

       

        private static Integer playersInGame = 0;

       

        private static Integer startTask = 0;

        private static Integer snowballerTask = 1;

        private static Integer tntthrowerTask = 2;

        private static Integer mobsummonerTask = 3;

        private static Integer marksmanTask = 4;

       

        Location arena;

        Location home;

       

        @Override

        public void onEnable() {

            Bukkit.getPluginManager().registerEvents(this, this);

            arena = new Location(Bukkit.getWorld("world"), 20, 6, -18);

            home = new Location(Bukkit.getWorld("world"), 475, 6, 910);

        }

       

        @Override

        public void onDisable() {

           

        }

       

        @EventHandler

        public void onJoin(PlayerJoinEvent event) {

            Player player = event.getPlayer();

            if(gameInProgress) {

                player.setGameMode(GameMode.CREATIVE);

                player.sendMessage("§d§lA game is currently in progress. Please wait...");

                player.teleport(arena);

                player.getInventory().clear();

            } elseif(gameIsStarting) {

                player.setGameMode(GameMode.ADVENTURE);

                player.sendMessage("§d§lA game is about to start. Please select your kit.");

                player.teleport(arena);

                player.getInventory().clear();

                playersInGame++;

            }

            event.setJoinMessage("§8§l[§a+§8§l] §7" + player.getName());

        }

       

        @EventHandler

        public void onQuit(PlayerQuitEvent event) {

            Player player = event.getPlayer();

            if(Kits.hasKit(player)) {

                Kits.removeKit(player);

                playersInGame--;

            }

            if(playersInGame == 1) {

                stopGame();

            }

            event.setQuitMessage("§8§l[§c-§8§l] §7" + player.getName());

        }

       

        @EventHandler

        public void onChat(AsyncPlayerChatEvent event) {

            Player player = event.getPlayer();

            if(!Kits.hasKit(player)) {

                event.setFormat("§7" + player.getName() + " §f" + event.getMessage());

            } else {

                if(Kits.getKit(player) == Kits.snowballer) {

                    event.setFormat("§b§lSnowballer §7" + player.getName() + " §f" + event.getMessage());

                } else if(Kits.getKit(player) == Kits.tntthrower) {

                    event.setFormat("§c§lTNT Thrower §7" + player.getName() + " §f" + event.getMessage());

                } else if(Kits.getKit(player) == Kits.mobsummoner) {

                    event.setFormat("§2§lMob Summoner §7" + player.getName() + " §f" + event.getMessage());

                } else if(Kits.getKit(player) == Kits.marksman) {

                    event.setFormat("§e§lMarksman §7" + player.getName() + " §f" + event.getMessage());

                }

            }

        }

       

        @EventHandler

        public void onEntityDamage(EntityDamageEvent event) {

            if(gameIsStarting) {

                event.setCancelled(true);

            }

        }

       

        @EventHandler

        public void onDrop(PlayerDropItemEvent event) {

            if(gameIsStarting || gameInProgress) {

                event.setCancelled(true);

            }

        }

       

        @EventHandler

        public void onInventoryClick(InventoryClickEvent event) {

            if(gameIsStarting || gameInProgress) {

                event.setCancelled(true);

                event.getWhoClicked().closeInventory();

            }

        }

       

        @EventHandler

        public void onRespawn(PlayerRespawnEvent event) {

            Player player = event.getPlayer();

            if(gameInProgress) {

                event.setRespawnLocation(arena);

                player.getInventory().clear();

                player.getInventory().setArmorContents(null);

            } else {

                event.setRespawnLocation(home);

            }

        }

       

        @EventHandler

        public void onDeath(PlayerDeathEvent event) throws EventException {

            Player player = event.getEntity();

            if(gameInProgress) {

                for(Player players : Bukkit.getOnlinePlayers()) {

                    players.playSound(players.getLocation(), Sound.NOTE_PLING, 1, 1);

                }

                player.setGameMode(GameMode.CREATIVE);

                playersInGame--;

                if(playersInGame == 1) {

                    stopGame();

                }

                player.sendMessage("§9§lOwch! Better luck next time!");

            }

        }

       

        @EventHandler

        public void onBreak(BlockBreakEvent event) {

            if(gameInProgress || gameIsStarting) {

                event.setCancelled(true);

            }

        }

       

        @EventHandler

        public void onPlace(BlockPlaceEvent event) {

            if(gameInProgress || gameIsStarting) {

                event.setCancelled(true);

            }

        }

       

        @EventHandler

        public void onInteract(PlayerInteractEvent event) {

            Player player = event.getPlayer();

            if(gameInProgress) {

                if(player.getItemInHand().getType() == Material.TNT) {

                    if(event.getAction() == Action.RIGHT_CLICK_AIR) {

                        player.getInventory().remove(new ItemStack(Material.TNT));

                        Entity tnt = player.getWorld().spawnEntity(player.getLocation(), EntityType.PRIMED_TNT);

                        tnt.setVelocity(player.getLocation().getDirection().multiply(1.5));

                    } else {

                        return;

                    }

                }

            } elseif(gameIsStarting) {

                event.setCancelled(true);

            }

        }

       

        @EventHandler

        public void onProjectileThrow(PlayerEggThrowEvent event) {

            Player player = event.getPlayer();

            if(gameIsStarting) {

                player.getInventory().addItem(new ItemStack(Material.EGG, 1));

            }

        }

       

        @EventHandler

        public void onProjectileHit(ProjectileHitEvent event) {

            Entity entity = event.getEntity();

            if(gameInProgress) {

                if(entity.getType() == EntityType.EGG) {

                    Zombie zombie = entity.getWorld().spawn(entity.getLocation(), Zombie.class);

                    zombie.getEquipment().setHelmet(new ItemStack(Material.GOLD_HELMET));

                }

            }

        }

       

        @EventHandler

        public void onExplode(EntityExplodeEvent event) {

            event.setCancelled(true);

        }

       

        @Override

        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {

            Player player = (Player) sender;

            if(cmd.getName().equalsIgnoreCase("startgame")) {

                if(!gameInProgress && !gameIsStarting) {

                    startGame();

                } else {

                    sender.sendMessage("§7§lThere is already a game in progress.");

                }

                returntrue;

            }

            if(cmd.getName().equalsIgnoreCase("kit")) {

                if(args.length < 1) {

                    sender.sendMessage("§7§lYou must specify a kit in order to play.");

                    returntrue;

                }

                if(gameIsStarting) {

                    if(args[0].equalsIgnoreCase("snowballer")) {

                        if(Kits.hasKit(player)) {

                            Kits.removeKit(player);

                        }

                        Kits.setKit(player, Kits.snowballer);

                        sender.sendMessage("§9§lYou have equipped the §e§lSnowballer §9§lkit.");

                    } else if(args[0].equalsIgnoreCase("tntthrower")) {

                        if(Kits.hasKit(player)) {

                            Kits.removeKit(player);

                        }

                        Kits.setKit(player, Kits.tntthrower);

                        sender.sendMessage("§9§lYou have equipped the §e§lTNT Thrower §9§lkit.");

                    } else if(args[0].equalsIgnoreCase("mobsummoner")) {

                        if(Kits.hasKit(player)) {

                            Kits.removeKit(player);

                        }

                        Kits.setKit(player, Kits.mobsummoner);

                        sender.sendMessage("§9§lYou have equipped the §e§lMob Summoner §9§lkit.");

                    } else if(args[0].equalsIgnoreCase("marksman")) {

                        if(Kits.hasKit(player)) {

                            Kits.removeKit(player);

                        }

                        Kits.setKit(player, Kits.marksman);

                        sender.sendMessage("§9§lYou have equipped the §e§lMarksman §9§lkit.");

                    } else {

                        sender.sendMessage("§7§lThat kit could not be found.");

                    }

                } elseif(gameInProgress) {

                    sender.sendMessage("§7§lA game is currently in progress.");

                } else {

                    sender.sendMessage("§7§lThere is no current game running.");

                }

                returntrue;

            }

            if(cmd.getName().equalsIgnoreCase("kits")) {

                sender.sendMessage("§9§lKits: §b§lSnowballer§9§l, §b§lTNT Thrower§9§l, §b§lMob Summoner§9§l, §b§lMarksman§9§l.");

                returntrue;

            }

            returnfalse;

        }

       

        public void startGame() {

            gameIsStarting = true;

            Bukkit.broadcastMessage("§b§lA PvP match is now starting! Select your kit and fight!");

            for(Player players : Bukkit.getOnlinePlayers()) {

                players.teleport(arena);

                players.playSound(players.getLocation(), Sound.LEVEL_UP, 1, 1);

                players.setGameMode(GameMode.ADVENTURE);

                players.setHealth(20);

                players.setFoodLevel(20);

                players.getInventory().clear();

                players.getInventory().setArmorContents(null);

                playersInGame++;

            }

            startTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {

                int seconds = 20;

                @Override

                public void run() {

                    if(seconds != 0) {

                        seconds--;

                    }

                    if(seconds <= 5 && seconds >= 1) {

                        Bukkit.broadcastMessage("§9§lThe game will start in §6§l" + seconds);

                        for(Player players : Bukkit.getOnlinePlayers()) {

                            players.playSound(players.getLocation(), Sound.NOTE_PLING, 1, 1);

                        }

                    }

                    if(seconds == 0) {

                        Bukkit.getScheduler().cancelTask(startTask);

                        gameIsStarting = false;

                        gameInProgress = true;

                        Bukkit.broadcastMessage("§2§lThe game has started! Good luck!");

                        for(Player players : Bukkit.getOnlinePlayers()) {

                            if(!Kits.hasKit(players)) {

                                Kits.setKit(players, Kits.snowballer);

                                players.sendMessage("§9§lYou have equipped the §e§lSnowballer §9§lkit.");

                            }

                            players.playSound(players.getLocation(), Sound.WITHER_SPAWN, 1, 1);

                            if(playersInGame <= 1) {

                                notEnoughPlayers = true;

                                stopGame();

                            }

                        }

                        beginSnowballerCountdown();

                        beginTntthrowerCountdown();

                        beginMobsummonerCountdown();

                        beginMarksmanCountdown();

                    }

                }

            }, 0, 20);

        }

       

        public void stopGame() {

            for(Player players : Bukkit.getOnlinePlayers()) {

                if(players.getGameMode() == GameMode.ADVENTURE) {

                    winner.put("winner", players);

                }

            }

            endGame(winner.get("winner"));

        }

       

        public void endGame(Player player) {

            if(notEnoughPlayers == true) {

                Bukkit.broadcastMessage("§c§lThere are not enough players to begin the game.");

            } else {

                Bukkit.broadcastMessage("§7§l" + player.getName() + " §a§lwon the game!");

            }

            Bukkit.getScheduler().cancelTask(snowballerTask);

            Bukkit.getScheduler().cancelTask(tntthrowerTask);

            Bukkit.getScheduler().cancelTask(mobsummonerTask);

            Bukkit.getScheduler().cancelTask(marksmanTask);

            notEnoughPlayers = false;

            winner.remove("winner");

            playersInGame = 0;

            for(Player players : Bukkit.getOnlinePlayers()) {

                players.playSound(players.getLocation(), Sound.LEVEL_UP, 1, 1);

            }

            Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {

                @Override

                public void run() {

                    for(Player players : Bukkit.getOnlinePlayers()) {

                        players.getInventory().clear();

                        players.getInventory().setArmorContents(null);

                        players.teleport(home);

                        if(Kits.hasKit(players)) {

                            Kits.removeKit(players);

                        } else {

                            continue;

                        }

                    }

                }

            }, 50);

            Bukkit.broadcastMessage("§b§lThe game has ended. Play again!");

            gameInProgress = false;

        }

       

        public void beginSnowballerCountdown() {

            snowballerTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {

                @Override

                public void run() {

                    for(Player players : Bukkit.getOnlinePlayers()) {

                        if(Kits.getKit(players) == Kits.snowballer) {

                            players.getInventory().addItem(new ItemStack(Material.SNOW_BALL));

                            players.playSound(players.getLocation(), Sound.CHICKEN_EGG_POP, 1, 1);

                        } else {

                            continue;

                        }

                    }

                }

            }, 40, 40);

        }

       

        public void beginTntthrowerCountdown() {

            tntthrowerTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {

                @Override

                public void run() {

                    for(Player players : Bukkit.getOnlinePlayers()) {

                        if(Kits.getKit(players) == Kits.tntthrower) {

                            players.getInventory().addItem(new ItemStack(Material.TNT));

                            players.playSound(players.getLocation(), Sound.CHICKEN_EGG_POP, 1, 1);

                        } else {

                            continue;

                        }

                    }

                }

            }, 400, 400);

        }

       

        public void beginMobsummonerCountdown() {

            mobsummonerTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {

                @Override

                public void run() {

                    for(Player players : Bukkit.getOnlinePlayers()) {

                        if(Kits.getKit(players) == Kits.mobsummoner) {

                            players.getInventory().addItem(new ItemStack(Material.EGG));

                            players.playSound(players.getLocation(), Sound.CHICKEN_EGG_POP, 1, 1);

                        } else {

                            continue;

                        }

                    }

                }

            }, 400, 400);

        }

       

        public void beginMarksmanCountdown() {

            marksmanTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {

                @Override

                public void run() {

                    for(Player players : Bukkit.getOnlinePlayers()) {

                        if(Kits.getKit(players) == Kits.marksman) {

                            players.getInventory().addItem(new ItemStack(Material.ARROW));

                            players.playSound(players.getLocation(), Sound.CHICKEN_EGG_POP, 1, 1);

                        } else {

                            continue;

                        }

                    }

                }

            }, 100, 100);

        }

       

    }


     
     
  2. Here is my Kits class:
    Code (Text):

    import java.util.HashMap;



    import org.bukkit.Material;

    import org.bukkit.entity.Player;

    import org.bukkit.inventory.ItemStack;



    publicclass Kits {

       

        publicstaticintsnowballer = 1;

        publicstaticinttntthrower = 2;

        publicstaticintmobsummoner = 3;

        publicstaticintmarksman = 4;

       

        private static HashMap<String, Integer> playerKit = new HashMap<>();

       

        public static boolean hasKit(Player player) {

            if(playerKit.containsKey(player.getName())) {

                returntrue;

            }

            returnfalse;

        }

       

        public static void removeKit(Player player) {

            playerKit.remove(player.getName());

        }

       

        public static Integer getKit(Player player) {

            return playerKit.get(player.getName());

        }

       

        public static void setKit(Player player, Integer kit) {

            playerKit.put(player.getName(), kit);

            giveItems(player, kit);

            giveDefaultKitItems(player);

        }

       

        public static void giveItems(Player player, Integer kit) {

            if(kit.equals(snowballer)) {

                giveSnowballerItems(player);

            } else if(kit.equals(tntthrower)) {

                giveTntThrowerItems(player);

            } else if(kit.equals(mobsummoner)) {

                giveMobSummonerItems(player);

            } else if(kit.equals(marksman)){

                giveMarksmanItems(player);

            } else {

                return;

            }

        }

       

        private static void giveSnowballerItems(Player player) {

            player.getInventory().setItem(1, new ItemStack(Material.SNOW_BALL, 1));

        }

       

        private static void giveTntThrowerItems(Player player) {

            player.getInventory().setItem(1, new ItemStack(Material.TNT, 1));

        }

       

        private static void giveMobSummonerItems(Player player) {

            player.getInventory().setItem(1, new ItemStack(Material.EGG, 1));

        }

       

        private static void giveMarksmanItems(Player player) {

            player.getInventory().setItem(1, new ItemStack(Material.BOW, 1));

            player.getInventory().setItem(2, new ItemStack(Material.ARROW, 1));

        }

       

        private static void giveDefaultKitItems(Player player) {

            ItemStack helm = new ItemStack(Material.IRON_HELMET, 1);

            ItemStack chest = new ItemStack(Material.IRON_CHESTPLATE, 1);

            ItemStack legs = new ItemStack(Material.IRON_LEGGINGS, 1);

            ItemStack boots = new ItemStack(Material.IRON_BOOTS, 1);

            ItemStack sword = new ItemStack(Material.STONE_SWORD, 1);

            player.getInventory().setHelmet(helm);

            player.getInventory().setChestplate(chest);

            player.getInventory().setLeggings(legs);

            player.getInventory().setBoots(boots);

            player.getInventory().setItem(0, sword);

        }

       

    }


     
    The several stack traces constantly appearing in my console are the 4 different tasks in the main class, which oddly won't cancel when I call Bukkit#getScheduler()#cancelTask(taskid), but only when 1 player attempts to play.

    The only difference between the stack traces is the line causing the error in the main class.
    Code (Text):

    [Plugin205] Task #501 for Plugin205 v1.0 generated an exception

    java.lang.NullPointerException

        at me.edragon205.minigame.Minigame$3.run(Minigame.java:382) ~[?:?]

        at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftTask.run(CraftTask.java:71) ~[spigot-1.8.6.jar:git-Spigot-044d928-e8c6403]

        at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:350) [spigot-1.8.6.jar:git-Spigot-044d928-e8c6403]

        at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:726) [spigot-1.8.6.jar:git-Spigot-044d928-e8c6403]

        at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:367) [spigot-1.8.6.jar:git-Spigot-044d928-e8c6403]

        at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:657) [spigot-1.8.6.jar:git-Spigot-044d928-e8c6403]

        at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:560) [spigot-1.8.6.jar:git-Spigot-044d928-e8c6403]

        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45]

     
    I don't even understand why it wants to call these tasks "Task #501" and such. I only have tasks 0, 1, 2, 3, and 4.

    Any help is appreciated.

    Sorry for the double post, I couldn't put this all in one post because of the maximum character limit.
     
  3. Can we see your "Minigame" class?
     
  4. The "Minigame" class is my main class. Sorry I forgot to mention that.
     
  5. What is line 382 in your main class?
     
  6. Code (Text):

    public void beginSnowballerCountdown() {

            snowballerTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {

                @Override

                public void run() {

                    for(Player players : Bukkit.getOnlinePlayers()) {

                        if(Kits.getKit(players) == Kits.snowballer) {

                            players.getInventory().addItem(new ItemStack(Material.SNOW_BALL));

                            players.playSound(players.getLocation(), Sound.CHICKEN_EGG_POP, 1, 1);

                        } else {

                            continue;

                        }

                    }

                }

            }, 40, 40);
     
    Line 382 is if(Kits.getKit(players) == Kits.snowballer) {.

    The stack trace is a NullPointerError, which I suspect then this means the next player has the kit Snowballer. However, I have an 'else' there, which then should continue the loop, but something is obviously wrong somewhere.
     
  7. Kits.getKit(players); is returning null. Make sure everybody on the server has a kit and is added to the hashmap. Also, I don't recommend using Bukkit.getOnlinePlayers() to get the players in the arena. Maybe make a list of your own or just iterate through the keyset of the kits hashmap using Kits.playerKit.keySet(). That would return a collection of strings in this case. Use Bukkit.getPlayer(string) to get the player by their name.
     
    • Agree Agree x 1
  8. I use Bukkit.getOnlinePlayers() for all of the players in the server, then I add to the variable 'playersInGame' for all the players in Adventure mode. I subtract it whenever a player leaves, dies, etc. then when it is at 1, I end the game since there is 1 player left alive. This all works perfectly for me - the problem is *after* the game, I get the errors, which at this point, no one has a kit or is in the game, and each of the tasks were supposed to be cancelled.
     
  9. Considering my advice will also work the same and it'll solve your issue.
     
Thread Status:
Not open for further replies.