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!
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.
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
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); } } }