AFK counter

Discussion in 'Plugin Development' started by augustt198, Sep 22, 2013.

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

    augustt198

    Hi, I'm trying to detect when a player is idle for 5 minutes in my plugin. But I don't know how or where to put the code, as everything so far in my plugin is triggered by events.

    I also am not sure about what logic I should use. I can either record the player's location every 10 seconds or so, and compare it to the last recorded position. If the positions are the same 30 times in a row, the player is afk. Or I can have a counter that is reset on every PlayerMoveEvent, and if the counter reaches 5 mins, the player is afk. Or perhaps there is a better solution...

    Thanks! :)
     
  2. Offline

    adam753

    Scheduling something to happen every few seconds sounds like a good place to start. What I would do is store all the online players in a HashMap along with an integer of how many seconds they've been AFK. Have a server-wide repeating task to increase every player's integer by 1 every second, but listen to PlayerMoveEvent and reset that player to 0. Of course you can have things like announcing "player is now AFK" inside the timer loop itself.
     
  3. Offline

    augustt198

    I hate to be "that guy", but could you show me an example of how to do this? :)
     
  4. Offline

    LucasEmanuel

    adam753
    I would rather reset the players "last moved time" to System.currentTimeMillis() and have a schedular that repeats every 30 seconds or so, if the "last moved time" is greater than the configured value, kick the player :)
     
  5. Offline

    Scizzr

    What about simply making a Map<String, Integer>, setting the String to the player's name and the Integer to how long they've not moved, and using a scheduler that repeats every second?

    May or may not be what you need or want, but this is one way to do it. Tailor it to your needs.
    Code:
    public class AFKCheck extends JavaPlugin implements Listener {
        private static ConcurrentHashMap<String, Integer> times = new ConcurrentHashMap<String, Integer>();
        public static AFKCheck instance;
        private static int secondsToAFK;
        
        public void onEnable() {
            instance = this;
            
            new AFKListener();
            
            Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
                public void run() {
                    for (Player player : Bukkit.getOnlinePlayers()) {
                        int time = times.containsKey(player.getName()) ? times.get(player.getName()) : 0;
                        times.put(player.getName(), time+1);
                    }
                }
            }, (long)0, (long)20);
        }
        
        public static boolean isAFK(Player player) {
            return (times.containsKey(player.getName())) ? (times.get(player.getName()) >= secondsToAFK) : false;
        }
        
        public static int getTime(Player player) {
            return (times.containsKey(player.getName())) ? times.get(player.getName()) : 0;
        }
        
        public static void setTime(Player player, int time) {
            times.put(player.getName(), time);
        }
        
        public class AFKListener implements Listener {
            public AFKListener() {
                Bukkit.getPluginManager().registerEvents(this, AFKCheck.instance);
            }
            
            @EventHandler
            public void onPlayerMove(PlayerMoveEvent event) {
                AFKCheck.setTime(event.getPlayer(), 0);
            }
        }
    }
    
     
Thread Status:
Not open for further replies.

Share This Page