From 15e5367175af8770ed054bf44249670b655e873a Mon Sep 17 00:00:00 2001 From: Evenprime Date: Sun, 23 Oct 2011 16:05:18 +0200 Subject: [PATCH] Make removal of unused playerdata more predictable and independent of JOIN/LEAVE events. --- plugin.yml | 2 +- .../co/evenprime/bukkit/nocheat/NoCheat.java | 28 +++++----- .../bukkit/nocheat/data/BaseData.java | 21 ++------ .../bukkit/nocheat/data/DataManager.java | 51 +++++++------------ .../bukkit/nocheat/debug/LagMeasureTask.java | 5 +- .../events/PlayerQuitEventManager.java | 44 ---------------- 6 files changed, 39 insertions(+), 112 deletions(-) delete mode 100644 src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java diff --git a/plugin.yml b/plugin.yml index a62d5eed..112289d9 100644 --- a/plugin.yml +++ b/plugin.yml @@ -3,7 +3,7 @@ name: NoCheat author: Evenprime main: cc.co.evenprime.bukkit.nocheat.NoCheat -version: 2.13a +version: 2.13b commands: nocheat: diff --git a/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java b/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java index d3a321ba..6dffe9a0 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java +++ b/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java @@ -29,7 +29,6 @@ import cc.co.evenprime.bukkit.nocheat.events.BlockBreakEventManager; import cc.co.evenprime.bukkit.nocheat.events.EntityDamageEventManager; import cc.co.evenprime.bukkit.nocheat.events.EventManager; import cc.co.evenprime.bukkit.nocheat.events.PlayerChatEventManager; -import cc.co.evenprime.bukkit.nocheat.events.PlayerQuitEventManager; import cc.co.evenprime.bukkit.nocheat.events.PlayerMoveEventManager; import cc.co.evenprime.bukkit.nocheat.events.PlayerTeleportEventManager; import cc.co.evenprime.bukkit.nocheat.log.LogLevel; @@ -101,7 +100,6 @@ public class NoCheat extends JavaPlugin { eventManagers.add(new PlayerChatEventManager(this)); eventManagers.add(new BlockBreakEventManager(this)); eventManagers.add(new BlockPlaceEventManager(this)); - eventManagers.add(new PlayerQuitEventManager(this)); eventManagers.add(new EntityDamageEventManager(this)); // Then set up a task to monitor server lag @@ -137,26 +135,14 @@ public class NoCheat extends JavaPlugin { data.clearCriticalData(playerName); } - public void playerLeft(String playerName) { - // Get rid of the critical data that's stored for player immediately - clearCriticalData(playerName); - - data.queueForRemoval(playerName); - } - public void playerJoined(String playerName) { - data.unqueueForRemoval(playerName); + clearCriticalData(playerName); } public Performance getPerformance(Type type) { return performance.get(type); } - public void cleanDataMap() { - if(data != null) - data.cleanDataMap(); - } - @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { return CommandHandler.handleCommand(this, sender, command, label, args); @@ -197,6 +183,16 @@ public class NoCheat extends JavaPlugin { public void reloadConfig() { conf.cleanup(); this.conf = new ConfigurationManager(this.getDataFolder().getPath()); - this.data.clearCriticalData(); + data.cleanDataMap(); + data.clearCriticalData(); + } + + /** + * Call this periodically to walk over the stored data map and remove old/unused entries + * + */ + public void cleanDataMap() { + data.cleanDataMap(); + } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/data/BaseData.java b/src/cc/co/evenprime/bukkit/nocheat/data/BaseData.java index f7f5b185..823f8898 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/data/BaseData.java +++ b/src/cc/co/evenprime/bukkit/nocheat/data/BaseData.java @@ -9,9 +9,9 @@ public class BaseData extends Data { public final MovingData moving; public final FightData fight; - private final Data[] data; // for convenience + private final Data[] data; // for convenience - private long removalTime; + public long lastUsedTime; public BaseData() { this.blockbreak = new BlockBreakData(); @@ -21,8 +21,6 @@ public class BaseData extends Data { this.moving = new MovingData(); this.fight = new FightData(); - this.removalTime = 0; - data = new Data[] {this.blockbreak, this.blockplace, this.chat, this.log, this.moving, this.fight}; } @@ -32,17 +30,8 @@ public class BaseData extends Data { d.clearCriticalData(); } } - - public void markForRemoval(boolean removal) { - if(removal) { - // 1 minute in the future - this.removalTime = System.currentTimeMillis() + 60000; - } else { - this.removalTime = 0; - } - } - - public boolean shouldBeRemoved() { - return removalTime != 0 && removalTime < System.currentTimeMillis(); + + public boolean shouldBeRemoved(long currentTimeInMilliseconds) { + return lastUsedTime + 60000L < currentTimeInMilliseconds; } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/data/DataManager.java b/src/cc/co/evenprime/bukkit/nocheat/data/DataManager.java index 6cc118a1..72bf9097 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/data/DataManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/data/DataManager.java @@ -40,6 +40,8 @@ public class DataManager { this.map.put(playerName, data); } + data.lastUsedTime = System.currentTimeMillis(); + return data; } @@ -54,47 +56,28 @@ public class DataManager { } /** - * put a players data on the queue for later deletion (unless it comes back - * before) - * - */ - public void queueForRemoval(String playerName) { - BaseData data = this.map.get(playerName); - - if(data != null) { - data.markForRemoval(true); - } - } - - public void unqueueForRemoval(String playerName) { - BaseData data = this.map.get(playerName); - - if(data != null) { - data.markForRemoval(false); - } - } - - /** - * check if queued for removal data is ready to get removed + * check if some data hasn't been used for a while and remove it * */ public void cleanDataMap() { - try { - for(Entry p : this.map.entrySet()) { - if(p.getValue().shouldBeRemoved()) { - removals.add(p.getKey()); + synchronized(removals) { + long time = System.currentTimeMillis(); + try { + for(Entry p : this.map.entrySet()) { + if(p.getValue().shouldBeRemoved(time)) { + removals.add(p.getKey()); + } } - } - for(String p : removals) { - this.map.remove(p); - } + for(String p : removals) { + this.map.remove(p); + } - removals.clear(); - } catch(Exception e) { - // Ignore problems, as they really don't matter much + removals.clear(); + } catch(Exception e) { + e.printStackTrace(); + } } - } public void clearCriticalData(String playerName) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java b/src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java index 8775808b..e0bc2a77 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java +++ b/src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java @@ -9,6 +9,7 @@ public class LagMeasureTask implements Runnable { private long lastIngamesecondDuration = 2000L; private boolean skipCheck = true; private int lagMeasureTaskId = -1; + private final NoCheat plugin; public LagMeasureTask(NoCheat plugin) { @@ -38,7 +39,9 @@ public class LagMeasureTask implements Runnable { ingameseconds++; // Check if some data is outdated now and let it be removed - plugin.cleanDataMap(); + if(ingameseconds % 62 == 0) { + plugin.cleanDataMap(); + } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java deleted file mode 100644 index 94198fb9..00000000 --- a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java +++ /dev/null @@ -1,44 +0,0 @@ -package cc.co.evenprime.bukkit.nocheat.events; - -import java.util.Collections; -import java.util.List; - -import org.bukkit.event.Event; -import org.bukkit.event.Event.Priority; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerListener; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.plugin.PluginManager; - -import cc.co.evenprime.bukkit.nocheat.NoCheat; -import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache; - -public class PlayerQuitEventManager extends PlayerListener implements EventManager { - - private final NoCheat plugin; - - public PlayerQuitEventManager(NoCheat plugin) { - this.plugin = plugin; - - PluginManager pm = plugin.getServer().getPluginManager(); - - pm.registerEvent(Event.Type.PLAYER_QUIT, this, Priority.Monitor, plugin); - pm.registerEvent(Event.Type.PLAYER_JOIN, this, Priority.Monitor, plugin); - } - - @Override - public void onPlayerQuit(PlayerQuitEvent event) { - // But only after a certain time, get rid of the rest of the data - plugin.playerLeft(event.getPlayer().getName()); - } - - @Override - public void onPlayerJoin(PlayerJoinEvent event) { - // A player came back early, so make sure that his data gets recycled - plugin.playerJoined(event.getPlayer().getName()); - } - - public List getActiveChecks(ConfigurationCache cc) { - return Collections.emptyList(); - } -}