Updating Player Count on Sign

Discussion in 'Spigot Plugin Development' started by four_4, May 22, 2017.

  1. As stated in the title of the thread, I am having trouble updating the amount of players in a specific world on a sign. I have everything working -- teleporting the player to the new location in the world when the right click the sign, in addition to having the sign have its own custom text -- but whenever someone clicks on the sign, the line that says how many players are in the world doesn't update. I've tried scheduling a repeating task, but that didn't work. Any suggestions?
     
  2. BananaPuncher714

    Supporter

    some code pls?
    Get the sign, then get the materialData: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/material/Sign.html
    Edit the lines then apply to sign
     
  3. You could try using events to see if a player gets in the world or connects, add them to a list, then count the list, or leave the integer onto the sign with an update event, then if someone leaves remove them from the list and update the number.
     
  4. @BananaPuncher714 This is all the code
    Code (Text):
    package me.four.ddm;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.Sign;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.block.SignChangeEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.plugin.java.JavaPlugin;

    public class Main extends JavaPlugin implements Listener{
       
        public void onEnable(){
            World ddm1 = Bukkit.getWorld("ddm1");
            if(!getConfig().contains("ddm1")){
                getConfig().set(ddm1.getName() + ".Status", "disabled");
                saveConfig();
            }
             
             getServer().getPluginManager().registerEvents(this, this);
             
        }
       
        public void onDisable(){
           
        }
       
        @EventHandler
        public void onSignChangeEvent(SignChangeEvent e){
            if(e.getLine(0).equalsIgnoreCase("[DDM1]")){
                if(e.getLine(1).equalsIgnoreCase("join")){
                        e.setLine(0, ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]");
                        e.setLine(1, ChatColor.GREEN + "Arena 1");
                        e.setLine(2, ChatColor.DARK_GRAY + "" + Bukkit.getServer().getWorld("ddm1").getPlayers().size() + "/4");
                        e.setLine(3, ChatColor.GREEN + "" + ChatColor.BOLD + "JOIN");
                }
                else if(e.getLine(1).equalsIgnoreCase("leave")){
                    e.setLine(0, ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]");
                    e.setLine(1, ChatColor.RED + "Return to Lobby");
                    e.setLine(3, ChatColor.RED + "" + ChatColor.BOLD + "LEAVE");  
                }
            }
        }
       
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent e){
            Player p = e.getPlayer();
            Block block = e.getClickedBlock();
            Sign sign = (Sign) block.getState();
            String[] lines = sign.getLines();
            if(e.getAction() == Action.RIGHT_CLICK_BLOCK){
                if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST){
                    if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.GREEN + "" + ChatColor.BOLD + "JOIN")){
                        p.performCommand("ddm join 1");  
                    }
                    else if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.RED + "" + ChatColor.BOLD + "LEAVE")){
                        p.performCommand("ddm leave");
                    }
                }
            }
        }
       
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){
           
            if (cmd.getName().equalsIgnoreCase("ddm")){
                Player p = (Player) sender;
                if (args.length == 0){
                p.sendMessage("---------------[Commands]---------------");
                p.sendMessage(ChatColor.DARK_PURPLE + "/ddm" + ChatColor.WHITE + " - Shows a list of commands for Drop Death Match");
                p.sendMessage(ChatColor.GOLD + "/ddm join <arena #>" + ChatColor.WHITE + " - Join a Drop Death Match arena");
                p.sendMessage(ChatColor.DARK_PURPLE + "/ddm leave" + ChatColor.WHITE + " - Leave a Drop Death Match arena");
                p.sendMessage("---------------[Commands]---------------");
                }
                if (args.length == 1){
                    if (args[0].equalsIgnoreCase("leave")){//returns player to the lobby
                        World lobby = Bukkit.getWorld("lobby");
                        if (p.getWorld().getName().equalsIgnoreCase("ddm1")){
                            p.teleport(new Location(lobby, 63, 4, 71));
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.WHITE + " You Have Left The Arena!");                      
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                    + " ERROR: You are not in a game!");
                        }
                    }
                    else if (args[0].equalsIgnoreCase("join")){//prints error message
                        p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: Not enough arguments! Use the command '" + ChatColor.WHITE + "/ddm join <arena #>" + ChatColor.RED + "'");
                    }
                    else if (args[0].equalsIgnoreCase("enable")){//prints error message
                        if (p.hasPermission("ddm.enable")){
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: Not enough arguments! Use the command '" + ChatColor.WHITE + "/ddm enable <arena #>" + ChatColor.RED + "'");
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: You do not have permission to use this command!");
                        }
                    }
                    else if (args[0].equalsIgnoreCase("disable")){//prints error message
                        if (p.hasPermission("ddm.disable")){
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: Not enough arguments! Use the command '" + ChatColor.WHITE + "/ddm disable <arena #>" + ChatColor.RED + "'");
                        }
                        else {
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: You do not have permission to use this command!");
                        }
                    }  
                    else if (args[0].equalsIgnoreCase("kick")){//prints error message
                        if (p.hasPermission("ddm.kick")){
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: Not enough arguments! Use the command '" + ChatColor.WHITE + "/ddm kick <player>" + ChatColor.RED + "'");                      
                         }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: You do not have permission to use this command!");                            
                        }
                    }
                    else if (args[0].equalsIgnoreCase("start")){
                        if (p.hasPermission("ddm.start")){
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: Not enough arguments! Use the command '" + ChatColor.WHITE + "/ddm kick <player>" + ChatColor.RED + "'");
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: You do not have permission to use this command!");
                        }
                    }
                }
                         
                else if (args.length == 2){
                    World ddm1 = Bukkit.getWorld("ddm1");
                    World lobby = Bukkit.getWorld("lobby");
                    Player target_player = Bukkit.getServer().getPlayer(args[1]);
                   
                     
                    if (args[0].equalsIgnoreCase("join") && args[1].equalsIgnoreCase("1")){//teleports sender to the arena
                        if (p.getWorld().getName().equalsIgnoreCase("lobby")){
                            if (getConfig().getString("ddm1.Status").equals("enabled")){
                                if(Bukkit.getServer().getWorld("ddm1").getPlayers().size() <= 4){
                                    p.teleport(new Location(ddm1, 0, 4, 0));
                                    p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.WHITE + " You Joined Arena 1!");      
                                }
                                else{
                                    p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                            + " ERROR: This arena is full!");
                                }
                            }
                            else{
                                p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                    + " ERROR: This arena is disabled!");
                            }
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                    + " ERROR: You are already in a game!");
                        }
                    }
                   
                    else if (args[0].equalsIgnoreCase("enable") && args[1].equalsIgnoreCase("1")){
                        if(p.hasPermission("ddm.enable")){
                            if (getConfig().getString("ddm1.Status").equals("disabled")){
                                getConfig().set(ddm1.getName() + ".Status", "enabled");
                                saveConfig();
                                p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.WHITE + " Enabling Arena 1!");
                            }
                            else{
                                p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                    + " ERROR: Arena 1 is already enabled!");
                            }
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                    + " ERROR: You do not have permission to use this command!");
                        }
                       
                    }
                   
                    else if (args[0].equalsIgnoreCase("disable") && args[1].equalsIgnoreCase("1")){
                        if(p.hasPermission("ddm.disable")){
                            if (getConfig().getString("ddm1.Status").equals("enabled")){
                                getConfig().set(ddm1.getName() + ".Status", "disabled");
                                saveConfig();
                                p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.WHITE + " Disabling Arena 1!");
                            }
                            else{
                                p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                    + " ERROR: Arena 1 is already disabled!");
                            }
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                    + " ERROR: You do not have permission to use this command!");
                        }
                    }
                    else if(args[0].equalsIgnoreCase("kick") && args[1].equalsIgnoreCase(target_player.getName())){
                        if(p.hasPermission("ddm.kick")){
                            if(target_player.getWorld().getName().equalsIgnoreCase("ddm1")){
                                p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.WHITE
                                        + " You have kicked " + ChatColor.YELLOW + target_player.getName() + ChatColor.WHITE + "!");
                                target_player.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.WHITE + " You have been kicked!");
                                target_player.teleport(new Location(lobby, 63, 4, 71));
                            }
                            else{
                                p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED + " ERROR: That player is not in a game!");
                            }
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED + " ERROR: You do not have permission to use this command!");
                           
                        }
                    }
                    else if(args[0].equalsIgnoreCase("start") && args[1].equalsIgnoreCase("1")){
                        if(p.hasPermission("ddm.start")){
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.WHITE + " Starting Arena 1!");
                        }
                        else{
                            p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: You do not have permission to use this command!");
                        }
                    }
                    else{
                        p.sendMessage(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]" + ChatColor.RED
                                + " ERROR: Something went wrong!");
                    }
                }
               
                return true;
            }
            return false;
        }
    }
     
     
  5. when they interact with join sign get the playerCount again and set the line of the sign that shows the playerCount to that value.
     
  6. WAS

    WAS

    You should make sure the block is an instance of a sign. Additionally, you should have a method that updates the sign, and fire it when a user teleports to the world to be accurate. If a sign is created that is a join sign, apply it to a hash map with it's location. When a person teleports, fire off that method with the given location of the sign. If that block is still a sign, and it still is a join sign, update it.
     
  7. I would recommend storing the sign's location (world,x,y,z) in a database or yml config upon placing the sign. Once that's done put the sign in a Map<Location,Sign>, or List<Sign> and iterate through that map during your task. This well let you use Sign.setLine(x, Bukkit.getOnlinePlayers()) to update it.

    onEnable load the signs up into memory from the database or config file, so the update task will get them. Remove them from the db/config upon breaking, and doneskis.
     
  8. To clarify what Billy is saying (he has a good point) the way to get the Sign instance is the BlockState.
    When you do Block.getState() you can check if it's an instance of sign. If it is you can cast it to sign.

    It's a bit of a confusing system.
     
  9. BananaPuncher714

    Supporter

    Pseudo code:
    1. Check if the block is a sign
    2. Get blockstate and cast to Sign
    3. Change lines in blockstate
    4. Update blockstate
     
  10. Ok so @Azewilious's suggestion worked -- but only for it adding onto the player count. I'm now having trouble removing the player count when someone clicks a leave sign.
     
  11. WAS

    WAS

    Updated code, please. You need to apply what you've learned from scenario 1 (joining world) to scenario 2 (leaving world).
     
  12. @WAS This is the sign stuff
    Code (Text):
        @EventHandler
        public void onSignChangeEvent(SignChangeEvent e){
                if(e.getLine(0).equalsIgnoreCase("[DDM1]")){
                    if(e.getLine(1).equalsIgnoreCase("join")){
                            e.setLine(0, ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]");
                            e.setLine(1, ChatColor.GREEN + "" + ChatColor.BOLD + "Arena 1");
                            e.setLine(2, ChatColor.DARK_GRAY + "" + Bukkit.getServer().getWorld("ddm1").getPlayers().size() + "/4");
                            e.setLine(3, ChatColor.GREEN + "" + ChatColor.BOLD + "JOIN");
                    }
                    else if(e.getLine(1).equalsIgnoreCase("leave")){
                        e.setLine(0, ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]");
                        e.setLine(1, ChatColor.RED + "Return to Lobby");
                        e.setLine(3, ChatColor.RED + "" + ChatColor.BOLD + "LEAVE");
                    }
                }
            }
     
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent e){
            Player p = e.getPlayer();
            Block block = e.getClickedBlock();
            Sign sign = (Sign) block.getState();
            String[] lines = sign.getLines();
            if(e.getAction() == Action.RIGHT_CLICK_BLOCK){
                if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST){
                    if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.GREEN + "" + ChatColor.BOLD + "JOIN")){
                        p.performCommand("ddm join 1");  
                        sign.setLine(2, ChatColor.DARK_GRAY + "" + Bukkit.getServer().getWorld("ddm1").getPlayers().size() + "/4");
                        sign.update();
                    }
                    else if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.RED + "" + ChatColor.BOLD + "LEAVE")){
                        p.performCommand("ddm leave");
                    }
                }
            }
        }
     
  13. BananaPuncher714

    Supporter

    In your code, you cast the blockstate to Sign before checking if it's really a sign. Cast it after you are sure it's a sign!! Also, set the sign text and update it after your if statements. It should look something like this(sorry for the spoonfeeding but it's pretty simple):
    Code (Java):
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent e){
            Player p = e.getPlayer();
            Block block = e.getClickedBlock();
            if(e.getAction() == Action.RIGHT_CLICK_BLOCK){
                if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST){
                    // Cast to sign AFTER you're sure it's a sign
                    Sign sign = (Sign) block.getState();
                    String[] lines = sign.getLines();
                    if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.GREEN + "" + ChatColor.BOLD + "JOIN")){
                        p.performCommand("ddm join 1");
                    }
                   else if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.RED + "" + ChatColor.BOLD + "LEAVE")){
                        p.performCommand("ddm leave");
                    }
                    // Update your sign here after you make the player leave or join
                    sign.setLine(2, ChatColor.DARK_GRAY + "" + Bukkit.getServer().getWorld("ddm1").getPlayers().size() + "/4");
                    sign.update();
                }
            }
        }
     
  14. In addition to this, for my parkour plugin I stored each player UUID in my Object List. Then you get the size :p

    On sign enter: getPlayers().add(UUID)
    on leave: getPlayers().remove(UUID)
    get amount: getPlayers.size()

    (Done on mobile)

    This is useful for a certain command to, like /cmd match / info
    And if you're in an arena it says the arena ID and such
     
    • Agree Agree x 1
  15. huh.... that must be why my console is spamming me a thousand times with that same error message haha
     
  16. So update on this... I tried the code that @BananaPuncher714 gave, and it doesn't work. Any suggestions? Here is the current code for the signs:
    Code (Text):
        @EventHandler
        public void onSignChangeEvent(SignChangeEvent e){
                if(e.getLine(0).equalsIgnoreCase("[DDM1]")){
                    if(e.getLine(1).equalsIgnoreCase("join")){
                            e.setLine(0, ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]");
                            e.setLine(1, ChatColor.GREEN + "" + ChatColor.BOLD + "Arena 1");
                            e.setLine(2, ChatColor.DARK_GRAY + "" + Bukkit.getServer().getWorld("ddm1").getPlayers().size() + "/4");
                            e.setLine(3, ChatColor.GREEN + "" + ChatColor.BOLD + "JOIN");
                    }
                    else if(e.getLine(1).equalsIgnoreCase("leave")){
                        e.setLine(0, ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]");
                        e.setLine(1, ChatColor.RED + "Return to Lobby");
                        e.setLine(3, ChatColor.RED + "" + ChatColor.BOLD + "LEAVE");
                    }
                }
            }
       
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent e){
            Player p = e.getPlayer();
            Block block = e.getClickedBlock();
            if(e.getAction() == Action.RIGHT_CLICK_BLOCK){
                if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST){
                    Sign sign = (Sign) block.getState();
                    String[] lines = sign.getLines();
                    if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.GREEN + "" + ChatColor.BOLD + "JOIN")){
                        p.performCommand("ddm join 1");
                        sign.setLine(2, ChatColor.DARK_GRAY + "" + Bukkit.getServer().getWorld("ddm1").getPlayers().size() + "/4");
                        sign.update();
                    }
                   else if(lines[0].equalsIgnoreCase(ChatColor.DARK_PURPLE + "[" + ChatColor.GOLD + "DDM" + ChatColor.DARK_PURPLE + "]") &&
                            lines[3].equalsIgnoreCase(ChatColor.RED + "" + ChatColor.BOLD + "LEAVE")){
                        p.performCommand("ddm leave");                  
                       
                    }
                }
            }
        }
     
  17. do the same thing you did when a player clicked the join sign.
     
  18. i tried that. what happens is it casts the player count to the leave sign and not the join sign
     
  19. any help? this is becoming quite frustrating...