Solved Why does this timer doesn't work

Discussion in 'Plugin Development' started by Fred7767, Mar 30, 2020.

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

    Fred7767

    Code:
    @EventHandler
        public void onInteract(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            Action a = e.getAction();
            if(a.equals(Action.RIGHT_CLICK_AIR)) {
                if(p.getItemInHand() != null) {
                    ItemStack item = p.getItemInHand();
                    Timer t = new Timer();
                    TimerTask test = new TimerTask() {
    
                            @Override
                            public void run() {
                                // TODO Auto-generated method stub
                                Bukkit.broadcastMessage("0");
                            }
                           
                          };
                    if(item.getType().equals(Material.DIAMOND)) {
                        t.schedule(test, 0, 1000);
                    } else if(item.getType().equals(Material.EMERALD)) {
                        test.cancel();
                        t.cancel();
                        t.purge();
                    }
                }
            }
        }
    
    When I right click the diamond, it starts the timertask, but when I click the emerald, the task doesn't stop. Can anyone tell me why this happens..?
     
  2. Online

    timtower Administrator Administrator Moderator

    @Fred7767 Try to use BukkitRunnable's instead.
     
  3. Offline

    Fred7767

    @timtower but does bukkitrunnable work like timer?
     
  4. Online

    timtower Administrator Administrator Moderator

  5. Offline

    Fred7767

    @timtower
    Code:
    if(a.equals(Action.RIGHT_CLICK_AIR)) {
                if(p.getItemInHand() != null) {
                    ItemStack item = p.getItemInHand();
                    BukkitRunnable runnable = new BukkitRunnable() {
    
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            Bukkit.broadcastMessage("0");
                        }
                       
                    };
                    int i = 0;
                    if(item.getType().equals(Material.DIAMOND)) {
                        i = getServer().getScheduler().scheduleSyncRepeatingTask(this, runnable, 0, 20);
                    } else if(item.getType().equals(Material.EMERALD)) {
                        getServer().getScheduler().cancelTask(i);;
                       
                    }
                }
            }
    
    i did it but its the same.
     
  6. Online

    timtower Administrator Administrator Moderator

  7. Offline

    Fred7767

    @timtower the diamond worked but the emerald doesn't stop the runnable
     
  8. Online

    timtower Administrator Administrator Moderator

    That is due to the scope.
    The "int i" that you are using only exists within that check, not outside of it.
    When the function ends that value gets erased again.
     
  9. Offline

    Fred7767

    then what can i do to stop the runnable?
     
  10. Online

    timtower Administrator Administrator Moderator

  11. Offline

    Fred7767

    @timtower
    Code:
    Map<UUID, BukkitTask> map;
       
        @EventHandler
        public void onInteract(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            Action a = e.getAction();
            if(a.equals(Action.RIGHT_CLICK_AIR)) {
                if(p.getItemInHand() != null) {
                    ItemStack item = p.getItemInHand();
                    BukkitRunnable runnable = new BukkitRunnable() {
    
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            Bukkit.broadcastMessage("0");
                        }
                       
                    };
                    if(item.getType().equals(Material.DIAMOND)) {
                        BukkitTask task = getServer().getScheduler().runTaskTimer(this, runnable, 0, 20);
                        map.put(p.getUniqueId(), task);
                    } else if(item.getType().equals(Material.EMERALD)) {
                        getServer().getScheduler().cancelTask(map.get(p.getUniqueId()).getTaskId());
                       
                    }
                }
            }
    
    still doesn't work
     
  12. Online

    timtower Administrator Administrator Moderator

    @Fred7767 BukkitTask has a cancel method.
    And did you add debugging lines to see where it is going wrong?
    Do you start multiple runnables and overwrite the old TimerTask making the original one unstoppable?
     
  13. Offline

    Fred7767

    @timtower
    Code:
    HashMap<UUID, BukkitTask> map = new HashMap<UUID, BukkitTask>();
       
        @EventHandler
        public void onInteract(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            Action a = e.getAction();
            if(a.equals(Action.RIGHT_CLICK_AIR)) {
                if(p.getItemInHand() != null) {
                    ItemStack item = p.getItemInHand();
                    BukkitRunnable runnable = new BukkitRunnable() {
    
                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            Bukkit.broadcastMessage("0");
                        }
                       
                    };
                    if(item.getType().equals(Material.DIAMOND)) {
                        if(map.containsKey(p.getUniqueId())) {
                            p.sendMessage("You have already started the timer!");
                            return;
                        }
                        BukkitTask task = getServer().getScheduler().runTaskTimer(this, runnable, 0, 20);
                        map.put(p.getUniqueId(), task);
                    } else if(item.getType().equals(Material.EMERALD)) {
                        map.get(p.getUniqueId()).cancel();
                        map.remove(p.getUniqueId());
                    }
                }
            }
        }
    
    Thank you timtower! This finally works!

    @timtower
    can i ask something more?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Mar 31, 2020
  14. Online

    timtower Administrator Administrator Moderator

    That is why this place exists.
     
  15. Offline

    Fred7767

    does the runnable works with ticks?
    if so what can i do to run a task every 1 millisecond?
     
  16. Online

    timtower Administrator Administrator Moderator

    It does indeed.
    The server only runs with 20 ticks per second, doing something every millisecond is not gonna happen in any way.
     
  17. Offline

    Fred7767

Thread Status:
Not open for further replies.

Share This Page