1.15.2 How to create cooldown that disables a command

Discussion in 'Spigot Plugin Development' started by 6u5t4v, Feb 20, 2020.

    1. I want to disable a command while a cooldown is running
    2. When the cooldown is stopped then enable the command and at the same time start a new cooldown
    3. When the new cooldown stops running then disable the command again and start the first cooldown.
    How would I do this in the most efficient way possible?
     
  1. Hello,

    Create a Map<UUID, Long> (will contain player UUID and time in millis).
    Listen to the PlayerCommandPreprocessEvent.
    Check if the message starts with the command you want to cooldown.
    Then check in the map the last time player used this command, comparing the time with actual time (System#currentTimeMillis).
    Cancel the event if the cooldown is not respected.

    If you want to create differents cooldowns for differents commands, simply use a map in the map
    Map<UUID, Map<String, Long>> map = new HashMap<>(); // The String key is the command, or by using a wrapper (maybe cleaner).
     
  2. Should probably also say that this is not per player, but for the whole server
     
  3. If you have only one command to cooldown, just create a variable "long lastCommandUse", check and update it when needed.

    If you have multiple commands to cooldown, you can use the same system as I explained, but modifying the map:
    Map<String, Long> map;
     
  4. Like this ?
    Code (Java):
    public Map<String, Cooldown> cmdCooldown = new HashMap<>();

        public Cooldown getCooldown(String command) {
            for (Cooldown cd : cmdCooldown.values()) {
                if (cd.getCommand().equalsIgnoreCase(command)) {
                    return cd;
                }
            }
            return null;
        }

        @EventHandler
        public void onPlayerCallCooldownCommand(PlayerCommandPreprocessEvent e) {
            if (cmdCooldown.containsKey(e.getMessage())) {
                Cooldown cd = getCooldown(e.getMessage());
                if(cd.getDelay() >= System.currentTimeMillis()) {
                    e.setCancelled(true);
                }
            }
        }
     
  5. I do not know how your Cooldown class looks like, but yes, the idea is here.

    Don't forget to add cooldown in map if the key is not present:
    Code (Java):
    @EventHandler
        public void onPlayerCallCooldownCommand(PlayerCommandPreprocessEvent e) {
            if (cmdCooldown.containsKey(e.getMessage())) {
                Cooldown cd = getCooldown(e.getMessage());
                if(cd.getDelay() >= System.currentTimeMillis()) {
                    e.setCancelled(true);
                } else {
                   // map.put
                }
            }
        }
    You'll also have to handle the fact that if players enter arguments, e.getMessage() will not be in the map.. (ex: /home 1, /home 2)
     
  6. All cooldown instances will be put in a map on load. Also I want to broadcast a message to the server when the delay runs out.
     
  7. When the command is used, just put your broadcast message into a BukkitScheduler#runTaskLater.