Solved Custom Minigame not assigning players correctly

Discussion in 'Plugin Development' started by pcgamers123, May 6, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    pcgamers123

    Hello!
    So in the past day I have been trying to squash this little tiny bug, and man, it's killing me.
    I am trying to add player to different games by using ID's. It is adding the players somewhat correctly, but when me and a friend is trying to join two different matches, it adds the first player who tried to join a match to the correct game, and then when another player tries to join another game, it add both of the players to the last joined game. Hope you understood this ;) Sorry if my explanation was bad...

    **EDIT: Did some more debugging, and when one player joins a game, that player get's added to all of the game's player list. I only have one player list in the GhostGame class, does anyone know how I should fix this? Thanks again**

    Thanks for the help in advance ;)

    So here is the code for my Manager class:
    Code:
    public class GhostManager {
    
        private static GhostManager gm = new GhostManager();
    
        private GhostManager() {} //Prevent init.
    
        public static GhostManager getManager() {
            return gm;
        }
    
        public static List<GhostGame> ghostGames = new ArrayList<GhostGame>();
        private int ghostSize = 0;
    
        public GhostGame getGame(int id) {
            for (GhostGame g : ghostGames) {
                if(g.getGameID() == id) {
                    return g;
                }
            }
            //Not found.
            return null;
        }
    
        public void addPlayer(Player p, int id) {
            GhostGame game = getGame(id);
    
            //Timers.getInstance().startGamesID = a.getGameID();
    
            if (game == null) {
                p.sendMessage(ChatUtils.starter() + "There is no game with the ID: " + id);
                return;
            }
    
            if(this.isInGame(p)) {
                p.sendMessage(ChatUtils.starter() + "You can't join more than " + ChatColor.DARK_RED + "1 " + ChatColor.WHITE + "game!");
                return;
            }
    
            if(GhostManager.canJoin(game.getGameID())) {
               Timers.getInstance().startGamesID = a.getGameID();
    
                // Adds the player to the Ghost Game player list
                game.getPlayers().add(p.getUniqueId());
    
                ItemStack toRemove = GhostGameSelector.gameSelectorGUI.getItem(game.getGameID() - 1);
                ItemMeta toRemoveMeta = toRemove.getItemMeta();
                toRemoveMeta.setLore(Arrays.asList("Players:", ChatColor.BLUE + "(" + game.getJoinedPlayersCount() + "/" + GhostMain.maxPlayers + ")",
                        "Minimum players needed: " + ChatColor.BLUE  + GhostMain.minimumPlayers));
                toRemove.setType(Material.IRON_SWORD);
                toRemove.setItemMeta(toRemoveMeta);
    
                ChatUtils.sendMessage(game.getGameID(), ChatColor.GREEN + p.getDisplayName() + ChatColor.WHITE + " has joined " + ChatColor.DARK_RED + "Ghost" + ChatColor.WHITE + "!");
            }
            else {
                p.sendMessage(ChatUtils.starter() + "This game is full!");
                return;
            }
    
        }
    
        public void resetGameByID(int id) {
            GhostGame game = getGame(id);
            // Check arena validity
            if (game == null) {
                return;
            }
            //Remove game from our list and decrease the Size by number of games removed.
            GhostManager.getManager().Stop(game.getGameID());
    //        ghostGames.remove(game);
    //        ghostSize--;
    
    
            ItemStack toEdit = GhostGameSelector.gameSelectorGUI.getItem(id - 1);
            toEdit.setType(Material.DIAMOND_SWORD);
            ItemMeta toRemoveMeta = toEdit.getItemMeta();
            toRemoveMeta.setDisplayName(ChatColor.DARK_RED + "Ghost Game " + id + ChatColor.GREEN + " (WAITING)");
            toRemoveMeta.setLore(Arrays.asList("Players:",
                    ChatColor.BLUE + "(" + game.getJoinedPlayersCount() + "/" + GhostMain.maxPlayers + ")", "Minimum players needed: " + ChatColor.BLUE + GhostMain.minimumPlayers));
            toEdit.setItemMeta(toRemoveMeta);
    
            //createGame();
        }
    
        public boolean isInGame(Player p) {
            for(GhostGame gh : this.ghostGames) {
                if(gh.getPlayers().contains(p.getUniqueId())) {
                    return true;
                }
            }
            return false;
        }
    
        public GhostGame createGame() {
            if (ghostSize == GhostMain.getInstance().maxGames) {
                return null; //Too many games
            }
    
            if (ghostSize < GhostMain.getInstance().maxGames + 1) {
                ghostSize++;
    
                GhostGame gh = new GhostGame(ghostSize);
                ghostGames.add(gh);
    
                //Add the game to our game selector!
                GhostGameSelector.createGameItems(new ItemStack(Material.DIAMOND_SWORD, 1), gh.getGameID() - 1,
                        ChatColor.DARK_RED + "Ghost Game " + gh.getGameID() + ChatColor.GREEN + " (WAITING)", Arrays.asList("Players:",
                                ChatColor.BLUE + "(" + gh.getJoinedPlayersCount() + "/" + GhostMain.getInstance().maxPlayers + ")", "Minimum players needed: " + ChatColor.BLUE  + GhostMain.getInstance().minimumPlayers), GhostGameSelector.gameSelectorGUI);
    
                return gh;
            }
            return null;
        }
    
        public static int getGames() {
            return ghostGames.size();
        }
    
        static Player ghost = GhostPlayer.getInstance().player;
        static FileConfiguration config = GhostMain.getInstance().config;
    
        public static boolean canJoin(int id) {
            if (GhostManager.getManager().getGame(id).getJoinedPlayersCount() <= GhostMain.maxPlayers) {
                return true;
            }
            else {
                return false;
            }
        }
        public static boolean canStart(int id) {
            //Edit minimum size of a game!
            if (GhostManager.getManager().getGame(id).getJoinedPlayersCount() >= GhostMain.minimumPlayers) {
                return true;
            }
            else {
                return false;
            }
        }
    
        /**
         * START AND STOP FUNCTIONS
         * @param id
         */
        public void Start(int id) {
            for (UUID playerNames : GhostManager.getManager().getGame(id).getPlayers()) {
                Player p = Bukkit.getPlayer(playerNames);
    
                //p.getInventory().clear();
    
                //TODO MAKE CLASSES!!!!!
    //            p.getInventory().setHelmet(new ItemStack(Material.LEATHER_HELMET));
    //            p.getInventory().setChestplate(new ItemStack(Material.LEATHER_CHESTPLATE));
    //            p.getInventory().setLeggings(new ItemStack(Material.LEATHER_LEGGINGS));
    //            p.getInventory().setBoots(new ItemStack(Material.LEATHER_BOOTS));
    
                //Select Ghost player. ghostPlayer is now set!
                GhostPlayer.getInstance().SelectOneGhost(GhostManager.getManager().getGame(id).getPlayers());
    
                //Spawn Ghost Detector to one player only.
                Random rnd = new Random();
                int index = rnd.nextInt(GhostManager.getManager().getGame(id).getJoinedPlayersCount());
                Player ghostDetectorPlayer = Bukkit.getPlayer(GhostManager.getManager().getGame(id).getPlayers().get(index));
                GhostDetector.getInstance().spawnItemDetector(ghostDetectorPlayer);
                ghostDetectorPlayer.sendMessage(ChatUtils.starter() + "You have been selected to carry the Ghost Detector!");
    
                TeleportPlayers(p);
    
                GhostPlayer.getInstance().TeleportGhost();
                GhostPlayer.getInstance().AddEffectsToGhost(id);
    
                SummonTheDead.getInstance().id = id;
    
                //ChatUtils.broadcast("Game has started!");
                p.playSound(p.getLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 1f, 1f);
    
                //Remove game from our game selector! EDIT INSTEAD OF REMOVING
                ItemStack toRemove = GhostGameSelector.gameSelectorGUI.getItem(id - 1);
                toRemove.setType(Material.WOOD_SWORD);
                ItemMeta toRemoveMeta = toRemove.getItemMeta();
                toRemoveMeta.setDisplayName(ChatColor.DARK_RED + "Ghost Game " + id + ChatColor.DARK_RED + " (STARTED)");
                toRemoveMeta.setLore(Arrays.asList("Players:",
                        ChatColor.BLUE + "(" + GhostManager.getManager().getGame(id).getJoinedPlayersCount() + "/" + GhostMain.maxPlayers + ")",
                        "Minimum players needed: " + GhostMain.minimumPlayers));
                toRemove.setItemMeta(toRemoveMeta);
    
                //CREATE A NEW GAME
            }
            Timers.getInstance().startEndCountdown(40, id);
            //Timers.getInstance().startCheckWinnerAtEnd(id);
    
            //Setting to 0 because we don't want to start the last game over again.
            Timers.getInstance().startGamesID = 0;
            Timers.getInstance().startGameCountdown(20);
        }
    
        public void Stop(int id) {
            GhostGame game = GhostManager.getManager().getGame(id);
    
            game.getPlayers().add(game.getGhost().get(0));
    
            for (UUID playerNames : GhostManager.getManager().getGame(id).getPlayers()) {
                Player p = Bukkit.getPlayer(playerNames);
                p.playSound(p.getLocation(), Sound.ENTITY_LIGHTNING_THUNDER, 1f, 1f);
    
                Location configLoc = new Location(p.getWorld(), config.getDouble("LobbySpawn.Location.X"),
                        config.getDouble("LobbySpawn.Location.Y"),
                        config.getDouble("LobbySpawn.Location.Z"));
                p.teleport(configLoc);
    
                p.getInventory().clear();
    
                p.getInventory().addItem(GhostGameSelector.selector());
            }
            //Reset Ghost Player
            //GhostPlayer.player = null;
    
            GhostPlayer.getInstance().RemoveEffectsFromGhost(game.getGameID());
    
            GhostManager.getManager().getGame(game.getGameID()).getPlayers().clear();
            GhostManager.getManager().getGame(game.getGameID()).getDeadPlayers().clear();
            GhostManager.getManager().getGame(game.getGameID()).getGhost().clear();
    
            ChatUtils.broadcast("Ghost " + ChatColor.DARK_RED + id + ChatColor.WHITE + " has ended! Join a new game by using your " + ChatColor.DARK_RED + "" + ChatColor.BOLD + "Ghost" + ChatColor.WHITE
                    + "" + ChatColor.BOLD + " Game Selector!");
        }
    
        /**
         * TELEPORT PLAYERS FUNCTION
         * @param player
         */
        public static void TeleportPlayers(Player player) {
            Location configLoc = new Location(player.getWorld(), config.getDouble("PlayerSpawn.Location.X"),
                    config.getDouble("PlayerSpawn.Location.Y"),
                    config.getDouble("PlayerSpawn.Location.Z"));
            player.teleport(configLoc);
        }
    
    }
    
    And here is the code for the Game class:
    Code:
    public class GhostGame {
    
        private final int gameID;
    
        public static List<UUID> ghostPlayers = new ArrayList<UUID>();
        public static List<UUID> deadGhostPlayers = new ArrayList<UUID>();
        public static List<UUID> ghostPlayerList = new ArrayList<UUID>();
    
        public GhostGame(int gameID) {
            this.gameID = gameID;
        }
    
        public int getGameID() {
            return this.gameID;
        }
    
        public List<UUID> getPlayers() {
            return this.ghostPlayers;
        }
    
        public List<UUID> getDeadPlayers() {
            return this.deadGhostPlayers;
        }
    
        public List<UUID> getGhost() {
            return this.ghostPlayerList;
        }
    
        public int getJoinedPlayersCount() {
            return getPlayers().size();
        }
    }
    
    And there is a runnable always going to check if new players want to join a different match.
    Here's the Timers class with all of the runnables:
    Code:
    public class Timers {
    
        private static Timers timer = new Timers();
    
        public Timers() {
        }
    
        public static Timers getInstance(){
            return timer;
        }
    
        /**
         *  COUNTDOWN FUNCTIONS
         */
        public int startGameID = 0;
    
        public int startGamesID = 0;
        public boolean startGameBool = true;
        public void startGameCountdown(final int time) {
            startGameID = Bukkit.getScheduler().runTaskAsynchronously(GhostMain.getInstance(), new Runnable() {
    
                boolean run = startGameBool;
                int timeUntilStart = time;
    
                @Override
                public void run() {
                    while(run) {
                        //startGameIDs = startGamesID;
                        if (startGamesID != 0) {
                            if (GhostManager.getManager().canJoin(startGamesID)) {
    
                                if (GhostManager.getManager().canStart(startGamesID)) {
    
                                    for (; timeUntilStart >= 0; timeUntilStart--) {
                                        if (timeUntilStart == 0) {
                                            GhostGame ghGame = GhostManager.getManager().getGame(startGamesID);
                                            deadPlayers = GhostManager.getManager().getGame(startGamesID).getDeadPlayers(); //SummonTheDeadClass
    
                                            ChatUtils.broadcast("Game " + ChatColor.DARK_RED + startGamesID + ChatColor.WHITE + " has started!");
                                            GhostManager.getManager().Start(ghGame.getGameID());
    
                                            startGamesID = 0;
                                            return;
                                        }
    
                                        if (timeUntilStart % 10 == 0 || timeUntilStart < 10) {
                                            ChatUtils.sendMessage(startGamesID, ChatColor.GREEN + "" + timeUntilStart +
                                                    ChatColor.WHITE + " seconds until Ghost " + ChatColor.DARK_RED + startGamesID + ChatColor.WHITE + " starts! (" + GhostManager.getManager().getGame(startGamesID).getJoinedPlayersCount() + "/"
                                                    + GhostMain.maxPlayers + ")");
                                            for (UUID players : GhostManager.getManager().getGame(startGamesID).getPlayers()) {
                                                Player player = Bukkit.getPlayer(players);
                                                player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
                                            }
    
                                        }
                                        try {
                                            Thread.sleep(1000);
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                            Bukkit.shutdown();
                                        }
    
                                    }
                                    try {
                                        Thread.sleep(1000);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        Bukkit.shutdown();
                                    }
    
                                }
                            }
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e) {
                                e.printStackTrace();
                                Bukkit.shutdown();
                            }
    
                        }
                        //startGameIDs = startGamesID;
                        try {
                            Thread.sleep(1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Bukkit.shutdown();
                        }
                    }
                }
            }).getTaskId();
        }
    
        public int startEndCountdownID;
        public boolean startEndCountdownBool = true;
        public void startEndCountdown(final int time, final int id) {
            startEndCountdownID = Bukkit.getScheduler().runTaskAsynchronously(GhostMain.getInstance(), new Runnable() {
                boolean run = startEndCountdownBool;
                int gameID =  id;
                int timeUntilEnd = time;
                @Override
                public void run() {
                    while(run) {
                        timeUntilEnd = time;
                        if(gameID != 0) {
                            for (; timeUntilEnd >= 0; timeUntilEnd--) {
                                if (timeUntilEnd == 0) {
    
                                    //GhostMain.startCheckWinnerEnd(gameID);
    
                                    GhostManager.getManager().resetGameByID(gameID);
    
                                    gameID = 0;
                                    return;
                                }
                                //Edit after the % to show every '&&' seconds.
                                if (timeUntilEnd % 10 == 0 || timeUntilEnd < 10) {
                                    ChatUtils.sendMessage(gameID, ChatColor.GREEN + "" + timeUntilEnd +
                                            ChatColor.WHITE + " seconds until " + ChatColor.DARK_RED + "Ghost" + ChatColor.WHITE + " ends!");
    
                                    //deadPlayers = GhostManager.getManager().getGame(startGamesID).getDeadPlayers();
    
                                }
    
                                try {
                                    Thread.sleep(1000);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    Bukkit.shutdown();
                                }
                            }
                        }
                        try {
                            Thread.sleep(1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Bukkit.shutdown();
                        }
                    }
                }
            }).getTaskId();
        }
    
        public int startCheckWinnerEndID;
        public boolean startCheckWinnerBool = true;
        public void startCheckWinnerAtEnd(final int gameID) {
            startCheckWinnerEndID = Bukkit.getScheduler().runTaskAsynchronously(GhostMain.getInstance(), new Runnable() {
                boolean run = startCheckWinnerBool;
                int id = gameID;
                @Override
                public void run() {
                    while (run) {
                        if(id != 0) {
                            /**
                             * CHANGE '2' TO '1' WHEN COMPLETE!!!
                             *                                   VVV
                             *                                   |||
                             */
                            if (GhostManager.getManager().getGame(id).getPlayers().size() == 1) {
                                ChatUtils.broadcast(ChatColor.GREEN + "" + Bukkit.getPlayer(GhostManager.getManager().getGame(id).getPlayers().get(0)).getDisplayName() + ChatColor.WHITE + " has won the game!");
                                //TODO ADD TOKENS FOR EACH KILL!!!!
                                GhostTokens.addBalance(Bukkit.getPlayer(GhostManager.getManager().getGame(id).getPlayers().get(0)).getUniqueId(), 25);
    
                                //TELEPORT ALL DEAD PLAYERS
                                for (UUID deadNames : GhostManager.getManager().getGame(id).getDeadPlayers()) {
                                    Player dead = Bukkit.getPlayer(deadNames);
    
                                    Location configLoc = new Location(dead.getWorld(), GhostMain.config.getDouble("LobbySpawn.Location.X"),
                                            GhostMain.config.getDouble("LobbySpawn.Location.Y"),
                                            GhostMain.config.getDouble("LobbySpawn.Location.Z"));
                                    dead.teleport(configLoc);
                                }
    
                                GhostManager.getManager().Stop(id);
                                id = 0;
                                return;
    //                    this.cancel();
    //                    break;
    
                            }
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e) {
                                e.printStackTrace();
                                Bukkit.shutdown();
                            }
                        }
                        try {
                            Thread.sleep(1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Bukkit.shutdown();
                        }
                    }
                }
            }).getTaskId();
        }
    
        public int startSummonTimerID;
        public boolean startSummonTimer = true;
        public void startSummonTimer(final int time, final int id) {
            startSummonTimerID = Bukkit.getScheduler().runTaskAsynchronously(GhostMain.getInstance(), new Runnable() {
                int timeUntilUse = time;
                boolean run = startSummonTimer;
                @Override
                public void run() {
                    while (run) {
                        timeUntilUse = time;
                        for (; timeUntilUse >= 0; timeUntilUse--) {
                            if (SummonTheDead.canSummon == false) {
                                if (timeUntilUse == 0) {
                                    SummonTheDead.canSummon = true;
    //                        deadSummonerMeta(Listeners.summoner).setLore(Arrays.asList("Summon the dead every " + summonDelay + " seconds!", "Use it wisely.",
    //                                "Time until next use: " + summonDelay));
                                    ItemMeta summonerMeta = Listeners.getListener().summoner.getItemMeta();
                                    summonerMeta.setDisplayName(ChatColor.DARK_RED + "" + ChatColor.BOLD + "SUMMON THE DEAD");
                                    Listeners.getListener().summoner.setItemMeta(summonerMeta);
    
                                    return;
                                }
    
                                if (timeUntilUse % 5 == 0 || timeUntilUse < 10) {
                                    ItemMeta summonerMeta = Listeners.getListener().summoner.getItemMeta();
                                    summonerMeta.setDisplayName(ChatColor.DARK_RED + "" + ChatColor.BOLD + "SUMMON THE DEAD" + ChatColor.WHITE + "" + ChatColor.BOLD + " (Cooldown: " + timeUntilUse + ")");
                                    Listeners.getListener().summoner.setItemMeta(summonerMeta);
                                }
    
                                try {
                                    Thread.sleep(1000);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    Bukkit.shutdown();
                                }
                            }
                        }
                        try {
                            Thread.sleep(5000);
                        } catch (Exception e) {
                            e.printStackTrace();
                            Bukkit.shutdown();
                        }
                    }
                }
            }).getTaskId();
        }
    
    }
    
    There's still more classes, but I reckon those won't be necessary. If they are, just comment about it and I'll add them.
     
    Last edited: May 6, 2016
  2. Offline

    WinX64

    Ok, if I understood correctly, you can have multiple GhostGames running at once. So, why are the variables storing the players for each game, static?

    On a side note, refrain from running api related code asynchrounously, most of it is not thread-safe.
     
  3. Offline

    pcgamers123

    Wow, thank you! I facepalmed so hard when I read your comment... :oops:
    Could you mind helping me out with just one other problem? The startgame countdown only initializes on one GhostGame. So if me and a friend tries to join different games simultaneously, the last game joined get's the countdown, and the other game is just in WAITING status even when the other game is finished.
    Thanks again!:)
     
  4. Offline

    WinX64

    Different problem, but same principle.
    You have separate variables for each Timers instance, but only one Timers for every GhostGame.
     
  5. Offline

    pcgamers123

    Aaah, thanks for everything!
     
Thread Status:
Not open for further replies.

Share This Page