Added AFK Listener and tracking #538

This commit is contained in:
Rsl1122 2018-04-06 09:57:45 +03:00
parent 20fa9c4665
commit d65dd4ca16
6 changed files with 134 additions and 21 deletions

View File

@ -36,6 +36,8 @@ public class Session {
private int mobKills;
private int deaths;
private long afkTime;
/**
* Creates a new session with given start and end of -1.
*
@ -48,15 +50,15 @@ public class Session {
playerKills = new ArrayList<>();
mobKills = 0;
deaths = 0;
afkTime = 0;
}
/**
* Re-Creates a session data object for viewing.
*
* @param sessionStart Epoch millisecond the session was started.
* @param sessionEnd Epoch millisecond the session ended.
*/
@Deprecated
public Session(int id, long sessionStart, long sessionEnd, int mobKills, int deaths) {
this(id, sessionStart, sessionEnd, mobKills, deaths, 0);
}
public Session(int id, long sessionStart, long sessionEnd, int mobKills, int deaths, long afkTime) {
this.sessionID = id;
this.sessionStart = sessionStart;
this.sessionEnd = sessionEnd;
@ -64,6 +66,7 @@ public class Session {
this.playerKills = new ArrayList<>();
this.mobKills = mobKills;
this.deaths = deaths;
this.afkTime = afkTime;
}
/**
@ -159,6 +162,18 @@ public class Session {
return sessionID != null;
}
public void addAFKTime(long timeAFK) {
afkTime += timeAFK;
}
public long getAfkLength() {
return afkTime;
}
public long getActiveLength() {
return getLength() - getAfkLength();
}
/**
* Used to get the ID of the session in the Database.
*

View File

@ -30,6 +30,7 @@ import com.djrapitops.plugin.api.utility.log.Log;
public class BukkitSystem extends PlanSystem implements ServerSystem {
public BukkitSystem(Plan plugin) {
testSystem = this;
Log.setErrorManager(new PlanErrorManager());

View File

@ -0,0 +1,51 @@
package com.djrapitops.plan.system.afk;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plugin.api.TimeAmount;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
/**
* Keeps track how long player has been afk during a session
*
* @author Rsl1122
*/
public class AFKTracker {
private final Map<UUID, Long> lastMovement;
private final long afkThresholdMs;
public AFKTracker() {
lastMovement = new HashMap<>();
afkThresholdMs = Settings.AFK_THRESHOLD_MINUTES.getNumber() * TimeAmount.MINUTE.ms();
}
public void performedAction(UUID uuid, long time) {
Long lastMoved = lastMovement.getOrDefault(uuid, time);
lastMovement.put(uuid, lastMoved);
if (time - lastMoved < afkThresholdMs) {
// Threshold not crossed, no action required.
return;
}
long timeAFK = time - lastMoved;
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
if (!cachedSession.isPresent()) {
return;
}
Session session = cachedSession.get();
session.addAFKTime(timeAFK);
}
public void loggedOut(UUID uuid, long time) {
performedAction(uuid, time);
lastMovement.remove(uuid);
}
}

View File

@ -20,7 +20,8 @@ public class BukkitListenerSystem extends ListenerSystem {
new GamemodeChangeListener(),
new WorldChangeListener(),
new CommandPreprocessListener(plugin),
new DeathEventListener()
new DeathEventListener(),
new AFKListener()
);
PlayerOnlineListener.setCountKicks(true);
}

View File

@ -0,0 +1,55 @@
package com.djrapitops.plan.system.listeners.bukkit;
import com.djrapitops.plan.system.afk.AFKTracker;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.UUID;
/**
* Listener that keeps track of actions that are not considered being AFK.
* <p>
* Additional Listener calls in PlayerOnlineListener to avoid having HIGHEST priority listeners.
*
* @author Rsl1122
* @see PlayerOnlineListener
*/
public class AFKListener implements Listener {
// Static so that /reload does not cause afk tracking to fail.
public static final AFKTracker AFK_TRACKER = new AFKTracker();
private void event(PlayerEvent event) {
try {
UUID uuid = event.getPlayer().getUniqueId();
long time = MiscUtils.getTime();
AFK_TRACKER.performedAction(uuid, time);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onMove(PlayerMoveEvent event) {
event(event);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerChat(AsyncPlayerChatEvent event) {
event(event);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
event(event);
}
}

View File

@ -69,13 +69,6 @@ public class PlayerOnlineListener implements Listener {
}
}
/**
* PlayerJoinEvent Listener.
* <p>
* Adds processing information to the ProcessingQueue.
*
* @param event The Fired event.
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
try {
@ -85,6 +78,8 @@ public class PlayerOnlineListener implements Listener {
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
AFKListener.AFK_TRACKER.performedAction(uuid, time);
String world = player.getWorld().getName();
String gm = player.getGameMode().name();
@ -110,13 +105,6 @@ public class PlayerOnlineListener implements Listener {
}
}
/**
* PlayerQuitEvent Listener.
* <p>
* Adds processing information to the ProcessingQueue.
*
* @param event Fired event
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
try {
@ -124,6 +112,8 @@ public class PlayerOnlineListener implements Listener {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
AFKListener.AFK_TRACKER.loggedOut(uuid, time);
Processing.submit(new BanAndOpProcessor(uuid, player.isBanned(), player.isOp()));
Processing.submit(new EndSessionProcessor(uuid, time));
Processing.submit(new NetworkPageUpdateProcessor());