[Solved] Saving players cooldown

Discussion in 'Spigot Plugin Development' started by dyenxunit, May 22, 2015.

  1. Im encountering a problem with my cool down when a player leaves the cool down is reset and they can use the command once again and i was wounding how i could make it so when they leave and come back it doesnt reset.

    Code (Text):
    private HashMap<Player, Integer> cooldownTime;
            private HashMap<Player, BukkitRunnable> cooldownTask;

    //cooldown

    cooldownTime.put(p, 1800);
                            cooldownTask.put(p, new BukkitRunnable() {
                                    public void run() {
                                        if (Test.contains(p.getName())) {
                                            cooldownTime.put(p, cooldownTime.get(p) - 1);
                                            if (cooldownTime.get(p) == 0) {
                                                    cooldownTime.remove(p);
                                                    cooldownTask.remove(p);
                                                    cancel();
                                            }
                                    }
                            }
                            });
                         
                            cooldownTask.get(p).runTaskTimer(this, 20, 20);
                           
     
  2. You need to store this in a file or a database.
     
  3. When they leave save the cooldown (integer) to a config and when they join get it from the config and put it as cooldown (integer).

    Done.
     
  4. Is their not away for me to store it locally inside of the plugin in like a ArrayList ?
     
  5. Just store the uuid instead of the player object, will work to (except after reloading the server).
     
  6. So something like this" public List<UUID> CoolDown = new ArrayList();" ?
     
  7. - Why making it public?
    - Name it coolDown
    - If the reference isn't changed you can make it final.


    Otherwise, yes.
     
  8. I have added "private List<UUID> coolDown = new ArrayList<UUID>();" but i am confused on how do i store the players cool down time because my cooldownTime Variable is where it is stored atm which is this "private HashMap<Player, Integer> cooldownTime;".
     
  9. Then use a Map instead of a List, if you need the cooldown time. Otherwise you could simple schedule a delayed task, removing that uuid after x ticks. Then you can simple check whether the list contains the uuid.
     
  10. I have tried this private HashMap<String, Integer> cooldownTime = new HashMap<String, Integer>(); but still no luck can someone please help me i am still fairly new to coding.
     
  11. What were you using when you tried HashMap<String, Integer>?

    When you set and get a UUID to the hashmap, you needa use p.getUniqueId().toString()

    Example:

    cooldownTime.put(p.getUniqueId().toString(), 1800);
    cooldownTime.get(p.getUniqueId().toString()).intValue()

    By the way, is it working correctly when a player doesn't relog?
     
  12. Yes when the player doesnt relog the timer keeps on going. The problem im having is when the player relogs the timer resets it self i need it to keep on going if the player logs off.
     
  13. You wouldn't be able to use an ArrayList, you would have to use a HashMap, which stores 2 values, the key and the object.

    Also, since you are doing a cooldown, I suggest you use timestamps rather than a repeating task, as you may have some performance issues.
     
  14. The performance part doesn't concern me as much atm as to getting the code to actually work so when the player relogs the timer is still running
     
  15. But were you using getUniqueId().toString() to get the uuid for the HashMap key when you tried HashMap<String,Integer>?
    (Note, you'd also want to use HashMap<String,BukkitRunnable> too then)

    Also, I too recommend ZyphiorMC's suggestion of using timestamps.

    Edit: But if you only want to get it working right now, timestamps don't matter too much.
     
    • Like Like x 1
  16. i tried to do coolDownTime(p.getName());
     
  17. p.getName() should work just as fine as p.getUniqueId().toString() (unless the player changes their name before they log back in)

    You made sure that you did that for both cooldownTime and cooldownTask right?
     
  18. Here's my full code:
    Code (Text):
    private Random r;        
    private HashMap<Player, Integer> cooldownTime;
            private HashMap<Player, BukkitRunnable> cooldownTask;    

    public void onEnable() {
                    cooldownTime = new HashMap<Player, Integer>();
                    cooldownTask = new HashMap<Player, BukkitRunnable>();
                    r = new Random();
            }
            public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
                    if (!(sender instanceof Player)) {
                            sender.sendMessage(ChatColor.RED + "Only players can randomly teleport.");
                            return true;
                    }
                 
                    final Player p = (Player) sender;
                 
                    if (cmd.getName().equalsIgnoreCase("rtp")) {
                            if (cooldownTime.containsKey(p)) {
                                    p.sendMessage(ChatColor.RED + "You must wait for " + secToMin(cooldownTime.get(p.getName())) + " seconds.");
                                    return true;
                            }
                            p.sendMessage(ChatColor.GREEN + "Cool Down Time!");
                            cooldownTime.put(p, 1800);
                            cooldownTask.put(p, new BukkitRunnable() {
                                    public void run() {
                                            cooldownTime.put(p, cooldownTime.get(p) - 1);
                                            if (cooldownTime.get(p) == 0) {
                                                    cooldownTime.remove(p);
                                                    cooldownTask.remove(p);
                                                    cancel();
                                            }
                                    }
                            });
                         
                            cooldownTask.get(p.getName()).runTaskTimer(this, 20, 20);
                         
                            return true;
                    }
                 
                    return true;
            }
    }
     
  19. Using the full code you posted, I created a testing plugin and changed the references of p to p.getName() where it was needed (and made the HashMaps use String keys). After doing that, it was remembering my cooldown when I relogged.

    The code I tested with (slightly modified from your version):
    Code (Text):
    package net.nulll.uso.RandomTeleport;

    import java.util.HashMap;
    import java.util.Random;

    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitRunnable;

    public final class RandomTeleport extends JavaPlugin {
     
        private Random r;    
        private HashMap<String, Integer> cooldownTime;
        private HashMap<String, BukkitRunnable> cooldownTask;  

        @Override
        public void onEnable() {
            cooldownTime = new HashMap<String, Integer>();
            cooldownTask = new HashMap<String, BukkitRunnable>();
            r = new Random();
        }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
            if (!(sender instanceof Player)) {
                sender.sendMessage(ChatColor.RED + "Only players can randomly teleport.");
                return true;
            }

            final Player p = (Player) sender;
         
            if (cmd.getName().equalsIgnoreCase("rtp")) {
                if (cooldownTime.containsKey(p.getName())) {
                    p.sendMessage(ChatColor.RED + "You must wait for " + secToMin(cooldownTime.get(p.getName())) + " minutes.");
                    return true;
                }
                p.sendMessage(ChatColor.GREEN + "Cool Down Time!");
                cooldownTime.put(p.getName(), 1800);
                cooldownTask.put(p.getName(), new BukkitRunnable() {
                    public void run() {
                        cooldownTime.put(p.getName(), cooldownTime.get(p.getName()) - 1);
                        if (cooldownTime.get(p.getName()) == 0) {
                            cooldownTime.remove(p.getName());
                            cooldownTask.remove(p.getName());
                            cancel();
                        }
                    }
                });
                cooldownTask.get(p.getName()).runTaskTimer(this, 20, 20);
                return true;
            }
            return true;
        }
     
        int secToMin(int seconds){
            return (seconds/60)+1;
        }
    }
    Edit: Image of me using /rtp twice, relogging, then using it again. (Sorry about all the other text spam, I just threw the test plugin on my test server with everything else I was testing)
    [​IMG]
     
    #19 iPyronic, May 23, 2015
    Last edited: May 23, 2015
  20. Thank you so much it all works now :D