From ca2da0d6b4a6aa4efe5e5b1efe107af6f25b3d9b Mon Sep 17 00:00:00 2001 From: Evenprime Date: Wed, 19 Oct 2011 17:34:59 +0200 Subject: [PATCH] Lag detection in seperate thread, bugfix for blockbreak direction check and code refactoring to reduce complexity --- .../co/evenprime/bukkit/nocheat/NoCheat.java | 298 +++++++++--------- .../bukkit/nocheat/actions/ActionManager.java | 2 +- .../checks/blockbreak/DirectionCheck.java | 6 +- .../nocheat/checks/blockbreak/ReachCheck.java | 4 +- .../checks/blockplace/OnLiquidCheck.java | 4 +- .../nocheat/checks/blockplace/ReachCheck.java | 4 +- .../bukkit/nocheat/checks/chat/ChatCheck.java | 4 +- .../nocheat/checks/fight/FightCheck.java | 4 +- .../nocheat/checks/moving/FlyingCheck.java | 4 +- .../checks/moving/MorePacketsCheck.java | 4 +- .../nocheat/checks/moving/NoFallCheck.java | 4 +- .../nocheat/checks/moving/RunFlyCheck.java | 4 +- .../nocheat/checks/moving/RunningCheck.java | 8 +- .../bukkit/nocheat/debug/LagMeasureTask.java | 66 ++++ .../bukkit/nocheat/debug/Performance.java | 53 ++++ .../nocheat/debug/PerformanceManager.java | 49 +-- .../events/BlockBreakEventManager.java | 10 +- .../events/BlockPlaceEventManager.java | 6 +- .../events/EntityDamageEventManager.java | 4 +- .../events/PlayerChatEventManager.java | 6 +- .../events/PlayerMoveEventManager.java | 12 +- .../events/PlayerQuitEventManager.java | 3 - .../events/PlayerTeleportEventManager.java | 6 +- 23 files changed, 320 insertions(+), 245 deletions(-) create mode 100644 src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java diff --git a/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java b/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java index 31b9a6fe..668482d8 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java +++ b/src/cc/co/evenprime/bukkit/nocheat/NoCheat.java @@ -1,5 +1,6 @@ package cc.co.evenprime.bukkit.nocheat; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -16,8 +17,11 @@ import cc.co.evenprime.bukkit.nocheat.actions.ActionManager; import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager; import cc.co.evenprime.bukkit.nocheat.config.Permissions; import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache; +import cc.co.evenprime.bukkit.nocheat.config.util.ActionList; import cc.co.evenprime.bukkit.nocheat.data.BaseData; import cc.co.evenprime.bukkit.nocheat.data.DataManager; +import cc.co.evenprime.bukkit.nocheat.data.ExecutionHistory; +import cc.co.evenprime.bukkit.nocheat.debug.LagMeasureTask; import cc.co.evenprime.bukkit.nocheat.debug.Performance; import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager; import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager.Type; @@ -42,19 +46,15 @@ import cc.co.evenprime.bukkit.nocheat.log.LogManager; */ public class NoCheat extends JavaPlugin { - private ConfigurationManager conf; - private LogManager log; - private DataManager data; - private PerformanceManager performance; - private ActionManager action; + private ConfigurationManager conf; + private LogManager log; + private DataManager data; + private PerformanceManager performance; + private ActionManager action; - private final List eventManagers = new LinkedList(); + private List eventManagers; - private int taskId = -1; - private int ingameseconds = 0; - private long lastIngamesecondTime = 0L; - private long lastIngamesecondDuration = 0L; - private boolean skipCheck = false; + private LagMeasureTask lagMeasureTask; public NoCheat() { @@ -62,14 +62,17 @@ public class NoCheat extends JavaPlugin { public void onDisable() { - if(taskId != -1) { - this.getServer().getScheduler().cancelTask(taskId); - taskId = -1; - } PluginDescriptionFile pdfFile = this.getDescription(); - if(conf != null) + if(lagMeasureTask != null) { + lagMeasureTask.cancel(); + lagMeasureTask = null; + } + + if(conf != null) { conf.cleanup(); + conf = null; + } log.logToConsole(LogLevel.LOW, "[NoCheat] version [" + pdfFile.getVersion() + "] is disabled."); } @@ -93,6 +96,7 @@ public class NoCheat extends JavaPlugin { // Then set up the Action Manager this.action = new ActionManager(this); + eventManagers = new ArrayList(8); // Big enough // Then set up the event listeners eventManagers.add(new PlayerMoveEventManager(this)); eventManagers.add(new PlayerTeleportEventManager(this)); @@ -103,30 +107,9 @@ public class NoCheat extends JavaPlugin { eventManagers.add(new EntityDamageEventManager(this)); // Then set up a task to monitor server lag - if(taskId == -1) { - taskId = this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() { - - public void run() { - - // If the previous second took to long, skip checks during - // this second - skipCheck = lastIngamesecondDuration > 1500; - - long time = System.currentTimeMillis(); - lastIngamesecondDuration = time - lastIngamesecondTime; - if(lastIngamesecondDuration < 1000) - lastIngamesecondDuration = 1000; - else if(lastIngamesecondDuration > 3600000) { - lastIngamesecondDuration = 3600000; // top limit of 1 - // hour per "second" - } - lastIngamesecondTime = time; - ingameseconds++; - - // Check if some data is outdated now and let it be removed - data.cleanDataMap(); - } - }, 0, 20); + if(lagMeasureTask == null) { + lagMeasureTask = new LagMeasureTask(this); + lagMeasureTask.start(); } // Then print a list of active checks per world @@ -136,23 +119,26 @@ public class NoCheat extends JavaPlugin { log.logToConsole(LogLevel.LOW, "[NoCheat] version [" + this.getDescription().getVersion() + "] is enabled."); } - public ConfigurationManager getConfigurationManager() { - return conf; + public ConfigurationCache getConfig(Player player) { + return conf.getConfigurationCacheForWorld(player.getWorld().getName()); } public void log(LogLevel level, String message, ConfigurationCache cc) { log.log(level, message, cc); } - public BaseData getPlayerData(Player player) { + public BaseData getData(Player player) { return data.getData(player); } - public void clearCriticalPlayerData(Player player) { + public void clearCriticalData(Player player) { data.clearCriticalData(player); } public void playerLeft(Player player) { + // Get rid of the critical data that's stored for player immediately + clearCriticalData(player); + data.queueForRemoval(player); } @@ -160,24 +146,13 @@ public class NoCheat extends JavaPlugin { data.unqueueForRemoval(player); } - public PerformanceManager getPerformanceManager() { - return performance; + public Performance getPerformance(Type type) { + return performance.get(type); } - public ActionManager getActionManager() { - return action; - } - - public int getIngameSeconds() { - return ingameseconds; - } - - public long getIngameSecondDuration() { - return lastIngamesecondDuration; - } - - public boolean skipCheck() { - return skipCheck; + public void cleanDataMap() { + if(data != null) + data.cleanDataMap(); } /** @@ -197,119 +172,160 @@ public class NoCheat extends JavaPlugin { ConfigurationCache cc = this.conf.getConfigurationCacheForWorld(world.getName()); - if(cc.debug.showchecks) { - for(EventManager em : eventManagers) { - List checks = em.getActiveChecks(cc); - if(checks.size() > 0) { - for(String active : em.getActiveChecks(cc)) { - line.append(active).append(' '); - } + if(!cc.debug.showchecks) + continue; - if(!introPrinted) { - log.logToConsole(LogLevel.LOW, intro); - introPrinted = true; - } + for(EventManager em : eventManagers) { + if(em.getActiveChecks(cc).size() == 0) + continue; - log.logToConsole(LogLevel.LOW, line.toString()); + for(String active : em.getActiveChecks(cc)) { + line.append(active).append(' '); + } - line = new StringBuilder(length); + if(!introPrinted) { + log.logToConsole(LogLevel.LOW, intro); + introPrinted = true; + } - for(int i = 0; i < length; i++) { - line.append(' '); - } - } + log.logToConsole(LogLevel.LOW, line.toString()); + + line = new StringBuilder(length); + + for(int i = 0; i < length; i++) { + line.append(' '); } } + } } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if(command.getName().equalsIgnoreCase("nocheat") && args.length > 0) { - if(args[0].equalsIgnoreCase("permlist") && args.length >= 2) { - // permlist command was used CORRECTLY + // Not our command + if(!command.getName().equalsIgnoreCase("nocheat") || args.length == 0) + return false; - // Does the sender have permission? - if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_PERMLIST)) { - return false; - } + if(args[0].equalsIgnoreCase("permlist") && args.length >= 2) { + // permlist command was used + return handlePermlistCommand(sender, args); - // Get the player names - Player player = this.getServer().getPlayerExact(args[1]); - if(player == null) { - sender.sendMessage("Unknown player: " + args[1]); - return true; - } else { - String prefix = ""; - if(args.length == 3) { - prefix = args[2]; - } - // Make a copy to allow sorting - List perms = new LinkedList(this.getDescription().getPermissions()); - Collections.reverse(perms); + } else if(args[0].equalsIgnoreCase("reload")) { + // reload command was used + return handleReloadCommand(sender); + } - sender.sendMessage("Player " + player.getName() + " has the permission(s):"); - for(Permission permission : perms) { - if(permission.getName().startsWith(prefix)) { - sender.sendMessage(permission.getName() + ": " + player.hasPermission(permission)); - } - } - return true; - } - } else if(args[0].equalsIgnoreCase("reload")) { - // reload command was used + else if(args[0].equalsIgnoreCase("performance")) { + // performance command was used + return handlePerformanceCommand(sender); + } - // Does the sender have permission? - if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_RELOAD)) { - return false; - } + return false; + } - sender.sendMessage("[NoCheat] Reloading configuration"); + private boolean handlePermlistCommand(CommandSender sender, String[] args) { + // Does the sender have permission to use it? + if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_PERMLIST)) { + return false; + } - this.conf.cleanup(); - this.conf = new ConfigurationManager(this.getDataFolder().getPath()); - this.data.clearCriticalData(); + // Get the player by name + Player player = this.getServer().getPlayerExact(args[1]); + if(player == null) { + sender.sendMessage("Unknown player: " + args[1]); + return true; + } - sender.sendMessage("[NoCheat] Configuration reloaded"); + // Should permissions be filtered by prefix? + String prefix = ""; + if(args.length == 3) { + prefix = args[2]; + } - return true; + // Make a copy to allow sorting + List perms = new LinkedList(this.getDescription().getPermissions()); + Collections.reverse(perms); + + sender.sendMessage("Player " + player.getName() + " has the permission(s):"); + + for(Permission permission : perms) { + if(permission.getName().startsWith(prefix)) { + sender.sendMessage(permission.getName() + ": " + player.hasPermission(permission)); } + } + return true; + } - else if(args[0].equalsIgnoreCase("performance")) { - // performance command was used + private boolean handleReloadCommand(CommandSender sender) { + // Does the sender have permission? + if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_RELOAD)) { + return false; + } - // Does the sender have permission? - if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_PERFORMANCE)) { - return false; - } + sender.sendMessage("[NoCheat] Reloading configuration"); - sender.sendMessage("[NoCheat] Retrieving performance statistics"); + this.conf.cleanup(); + this.conf = new ConfigurationManager(this.getDataFolder().getPath()); + this.data.clearCriticalData(); - PerformanceManager pm = this.getPerformanceManager(); - long totalTime = 0; + sender.sendMessage("[NoCheat] Configuration reloaded"); - for(Type type : Type.values()) { - Performance p = pm.get(type); + return true; + } - long total = p.getTotalTime(); - totalTime += total; - long relative = p.getRelativeTime(); - long events = p.getCounter(); + private boolean handlePerformanceCommand(CommandSender sender) { + // Does the sender have permission? + if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_PERFORMANCE)) { + return false; + } - StringBuilder string = new StringBuilder("").append(type.toString()); - string.append(": total ").append(pm.convertToAppropriateUnit(total)).append(" ").append(pm.getAppropriateUnit(total)); - string.append(", relative ").append(pm.convertToAppropriateUnit(relative)).append(" ").append(pm.getAppropriateUnit(relative)); - string.append(" over ").append(events).append(" events."); + sender.sendMessage("[NoCheat] Retrieving performance statistics"); - sender.sendMessage(string.toString()); - } + long totalTime = 0; - sender.sendMessage("Total time spent: " + pm.convertToAppropriateUnit(totalTime) + " " + pm.getAppropriateUnit(totalTime)); + for(Type type : Type.values()) { + Performance p = this.getPerformance(type); - return true; - } + long total = p.getTotalTime(); + totalTime += total; + + StringBuilder string = new StringBuilder("").append(type.toString()); + string.append(": total ").append(Performance.toString(total)); + string.append(", relative ").append(Performance.toString(p.getRelativeTime())); + string.append(" over ").append(p.getCounter()).append(" events."); + + sender.sendMessage(string.toString()); + } + + sender.sendMessage("Total time spent: " + Performance.toString(totalTime) + " " + Performance.toString(totalTime)); + + return true; + } + + public int getIngameSeconds() { + if(lagMeasureTask != null) + return lagMeasureTask.getIngameSeconds(); + return 0; + } + + public boolean skipCheck() { + if(lagMeasureTask != null) + return lagMeasureTask.skipCheck(); + return false; + } + + public long getIngameSecondDuration() { + if(lagMeasureTask != null) + return lagMeasureTask.getIngameSecondDuration(); + return 1000L; + } + + public boolean execute(Player player, ActionList actions, int violationLevel, ExecutionHistory history, ConfigurationCache cc) { + if(action != null) { + return action.executeActions(player, actions, violationLevel, history, cc); } return false; } + } diff --git a/src/cc/co/evenprime/bukkit/nocheat/actions/ActionManager.java b/src/cc/co/evenprime/bukkit/nocheat/actions/ActionManager.java index df57c8a1..ce13b38b 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/actions/ActionManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/actions/ActionManager.java @@ -30,7 +30,7 @@ public class ActionManager { boolean special = false; - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); // Always set this here "by hand" data.log.violationLevel = violationLevel; diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/DirectionCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/DirectionCheck.java index 788f61bb..d266a34d 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/DirectionCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/DirectionCheck.java @@ -23,7 +23,7 @@ public class DirectionCheck { public boolean check(Player player, Block brokenBlock, ConfigurationCache cc) { - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); // If the block is instabreak and we don't check instabreak, return if(!cc.blockbreak.checkinstabreakblocks && brokenBlock.getLocation().equals(data.blockbreak.instaBrokeBlockLocation)) { @@ -48,11 +48,11 @@ public class DirectionCheck { // Prepare some event-specific values for logging and custom actions data.log.check = "blockbreak.direction"; - cancel = plugin.getActionManager().executeActions(player, cc.blockbreak.directionActions, (int) data.blockbreak.directionViolationLevel, data.blockbreak.history, cc); + cancel = plugin.execute(player, cc.blockbreak.directionActions, (int) data.blockbreak.directionViolationLevel, data.blockbreak.history, cc); if(cancel) { // Needed to calculate penalty times - data.fight.directionLastViolationTime = time; + data.blockbreak.directionLastViolationTime = time; } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/ReachCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/ReachCheck.java index 6754f673..6881a333 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/ReachCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/blockbreak/ReachCheck.java @@ -30,7 +30,7 @@ public class ReachCheck { double distance = CheckUtil.reachCheck(player, brokenBlock.getX() + 0.5D, brokenBlock.getY() + 0.5D, brokenBlock.getZ() + 0.5D, player.getGameMode() == GameMode.CREATIVE ? cc.blockbreak.reachDistance + 2 : cc.blockbreak.reachDistance); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(distance > 0D) { // Player failed the check @@ -42,7 +42,7 @@ public class ReachCheck { data.log.check = "blockbreak.reach"; data.log.reachdistance = distance; - cancel = plugin.getActionManager().executeActions(player, cc.blockbreak.reachActions, (int) data.blockbreak.reachViolationLevel, data.blockbreak.history, cc); + cancel = plugin.execute(player, cc.blockbreak.reachActions, (int) data.blockbreak.reachViolationLevel, data.blockbreak.history, cc); } else { data.blockbreak.reachViolationLevel *= 0.9D; } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/OnLiquidCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/OnLiquidCheck.java index 82aca913..7b8eaafd 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/OnLiquidCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/OnLiquidCheck.java @@ -26,7 +26,7 @@ public class OnLiquidCheck { boolean cancel = false; - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(blockPlaced == null || blockPlaced.isEmpty() || (blockPlacedAgainst != null && isSolid(blockPlacedAgainst.getTypeId()))) { // all ok @@ -38,7 +38,7 @@ public class OnLiquidCheck { data.log.placed = blockPlaced; data.log.placedAgainst = blockPlacedAgainst; - cancel = plugin.getActionManager().executeActions(player, cc.blockplace.onliquidActions, (int) data.blockplace.onliquidViolationLevel, data.blockplace.history, cc); + cancel = plugin.execute(player, cc.blockplace.onliquidActions, (int) data.blockplace.onliquidViolationLevel, data.blockplace.history, cc); } data.blockplace.onliquidViolationLevel *= 0.95D; // Reduce level over diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/ReachCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/ReachCheck.java index bb7086db..f7b22698 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/ReachCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/ReachCheck.java @@ -29,7 +29,7 @@ public class ReachCheck { double distance = CheckUtil.reachCheck(player, placedAgainstBlock.getX() + 0.5D, placedAgainstBlock.getY() + 0.5D, placedAgainstBlock.getZ() + 0.5D, cc.blockplace.reachDistance); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(distance > 0D) { // Player failed the check @@ -41,7 +41,7 @@ public class ReachCheck { data.log.check = "blockplace.reach"; data.log.reachdistance = distance; - cancel = plugin.getActionManager().executeActions(player, cc.blockplace.reachActions, (int) data.blockplace.reachViolationLevel, data.blockplace.history, cc); + cancel = plugin.execute(player, cc.blockplace.reachActions, (int) data.blockplace.reachViolationLevel, data.blockplace.history, cc); } else { data.blockplace.reachViolationLevel *= 0.9D; } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/chat/ChatCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/chat/ChatCheck.java index bceac909..db081c17 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/chat/ChatCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/chat/ChatCheck.java @@ -37,7 +37,7 @@ public class ChatCheck { int time = plugin.getIngameSeconds(); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(data.chat.spamLasttime + cc.chat.spamTimeframe <= time) { data.chat.spamLasttime = time; @@ -54,7 +54,7 @@ public class ChatCheck { data.log.check = "chat.spam"; data.log.text = message; - cancel = plugin.getActionManager().executeActions(player, cc.chat.spamActions, data.chat.messageCount - cc.chat.spamLimit, data.chat.history, cc); + cancel = plugin.execute(player, cc.chat.spamActions, data.chat.messageCount - cc.chat.spamLimit, data.chat.history, cc); } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java index b6837200..9f8fda0e 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java @@ -44,7 +44,7 @@ public class FightCheck { // height to get the "center" of the hitbox double off = CheckUtil.directionCheck(player, entity.locX, entity.locY + 1.0D, entity.locZ, width, 2.0D, cc.fight.directionPrecision); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(off < 0.1D) { // Player did probably nothing wrong @@ -61,7 +61,7 @@ public class FightCheck { // actions data.log.check = "fight.direction"; - cancel = plugin.getActionManager().executeActions(player, cc.fight.directionActions, (int) data.fight.violationLevel, data.fight.history, cc); + cancel = plugin.execute(player, cc.fight.directionActions, (int) data.fight.violationLevel, data.fight.history, cc); if(cancel) { // Needed to calculate penalty times diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/FlyingCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/FlyingCheck.java index 98d9747d..913b992b 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/FlyingCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/FlyingCheck.java @@ -29,7 +29,7 @@ public class FlyingCheck { public Location check(Player player, Location from, Location to, ConfigurationCache cc) { - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(data.moving.runflySetBackPoint == null) { data.moving.runflySetBackPoint = player.getLocation().clone(); @@ -83,7 +83,7 @@ public class FlyingCheck { data.log.toLocation = to; data.log.check = "flying/toofast"; - boolean cancel = plugin.getActionManager().executeActions(player, cc.moving.flyingActions, (int) data.moving.runflyViolationLevel, data.moving.history, cc); + boolean cancel = plugin.execute(player, cc.moving.flyingActions, (int) data.moving.runflyViolationLevel, data.moving.history, cc); // Was one of the actions a cancel? Then really do it if(cancel) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java index 340d4b2b..82a57046 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/MorePacketsCheck.java @@ -85,7 +85,7 @@ public class MorePacketsCheck { Location newToLocation = null; - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); data.moving.morePacketsCounter++; if(data.moving.morePacketsSetbackPoint == null) { @@ -122,7 +122,7 @@ public class MorePacketsCheck { data.log.check = "moving/morepackets"; boolean cancel = false; - cancel = plugin.getActionManager().executeActions(player, cc.moving.morePacketsActions, (int) data.moving.morePacketsViolationLevel, data.moving.history, cc); + cancel = plugin.execute(player, cc.moving.morePacketsActions, (int) data.moving.morePacketsViolationLevel, data.moving.history, cc); // Only do the cancel if the player didn't change worlds // inbetween diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/NoFallCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/NoFallCheck.java index 5f4b105c..92bc9eaa 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/NoFallCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/NoFallCheck.java @@ -31,7 +31,7 @@ public class NoFallCheck { double oldY = from.getY(); double newY = to.getY(); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); // This check is pretty much always a step behind for technical reasons. if(fromOnOrInGround) { @@ -58,7 +58,7 @@ public class NoFallCheck { data.log.falldistance = data.moving.fallDistance; data.log.check = "moving/nofall"; - boolean cancel = plugin.getActionManager().executeActions(player, cc.moving.nofallActions, (int) data.moving.nofallViolationLevel, data.moving.history, cc); + boolean cancel = plugin.execute(player, cc.moving.nofallActions, (int) data.moving.nofallViolationLevel, data.moving.history, cc); // If "cancelled", the fall damage gets dealt in a way that's // visible to other plugins diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunFlyCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunFlyCheck.java index e3b93595..3675f34b 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunFlyCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunFlyCheck.java @@ -54,7 +54,7 @@ public class RunFlyCheck { */ Location newToLocation = null; - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); /******** DO GENERAL DATA MODIFICATIONS ONCE FOR EACH EVENT *****/ if(data.moving.horizVelocityCounter > 0) { @@ -102,7 +102,7 @@ public class RunFlyCheck { */ public void blockPlaced(Player player, Block blockPlaced) { - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(blockPlaced == null || data.moving.runflySetBackPoint == null) { return; diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunningCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunningCheck.java index 04d22892..f82a3654 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunningCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/moving/RunningCheck.java @@ -43,7 +43,7 @@ public class RunningCheck { final double zDistance = to.getZ() - from.getZ(); final double horizontalDistance = Math.sqrt((xDistance * xDistance + zDistance * zDistance)); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(data.moving.runflySetBackPoint == null) { data.moving.runflySetBackPoint = from.clone(); @@ -84,7 +84,7 @@ public class RunningCheck { else if(resultVert > 0) data.log.check = "runfly/vertical"; - boolean cancel = plugin.getActionManager().executeActions(player, cc.moving.actions, (int) data.moving.runflyViolationLevel, data.moving.history, cc); + boolean cancel = plugin.execute(player, cc.moving.actions, (int) data.moving.runflyViolationLevel, data.moving.history, cc); // Was one of the actions a cancel? Then do it if(cancel) { @@ -130,7 +130,7 @@ public class RunningCheck { e.printStackTrace(); } - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); if(cc.moving.sneakingCheck && player.isSneaking() && !player.hasPermission(Permissions.MOVE_SNEAK)) { distanceAboveLimit = totalDistance - cc.moving.sneakingSpeedLimit - data.moving.horizFreedom; @@ -183,7 +183,7 @@ public class RunningCheck { final double toY = to.getY(); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); double limit = data.moving.vertFreedom + cc.moving.jumpheight; diff --git a/src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java b/src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java new file mode 100644 index 00000000..1102c4ad --- /dev/null +++ b/src/cc/co/evenprime/bukkit/nocheat/debug/LagMeasureTask.java @@ -0,0 +1,66 @@ +package cc.co.evenprime.bukkit.nocheat.debug; + +import cc.co.evenprime.bukkit.nocheat.NoCheat; + +public class LagMeasureTask implements Runnable { + + private int ingameseconds = 0; + private long lastIngamesecondTime = 0L; + private long lastIngamesecondDuration = 0L; + private boolean skipCheck = true; + private int lagMeasureTaskId = -1; + private final NoCheat plugin; + + public LagMeasureTask(NoCheat plugin) { + this.plugin = plugin; + } + + public void start() { + lagMeasureTaskId = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, this, 0, 20); + } + + public void run() { + + // If the previous second took to long, skip checks during + // this second + skipCheck = lastIngamesecondDuration > 1500; + + long time = System.currentTimeMillis(); + lastIngamesecondDuration = time - lastIngamesecondTime; + if(lastIngamesecondDuration < 1000) + lastIngamesecondDuration = 1000; + else if(lastIngamesecondDuration > 3600000) { + lastIngamesecondDuration = 3600000; // top limit of 1 + // hour per "second" + } + lastIngamesecondTime = time; + ingameseconds++; + + // Check if some data is outdated now and let it be removed + plugin.cleanDataMap(); + + } + + public void cancel() { + if(lagMeasureTaskId != -1) { + try { + plugin.getServer().getScheduler().cancelTask(lagMeasureTaskId); + } catch(Exception e) { + System.out.println("NoCheat: Couldn't cancel LagMeasureTask: " + e.getMessage()); + } + lagMeasureTaskId = -1; + } + } + + public int getIngameSeconds() { + return ingameseconds; + } + + public long getIngameSecondDuration() { + return lastIngamesecondDuration; + } + + public boolean skipCheck() { + return skipCheck; + } +} diff --git a/src/cc/co/evenprime/bukkit/nocheat/debug/Performance.java b/src/cc/co/evenprime/bukkit/nocheat/debug/Performance.java index 55ac04f0..360fae5f 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/debug/Performance.java +++ b/src/cc/co/evenprime/bukkit/nocheat/debug/Performance.java @@ -7,6 +7,12 @@ public class Performance { private long counter = 1; // start with 1 to avoid DIV/0 errors private final boolean enabled; + private static final long NANO = 1; + private static final long MICRO = NANO * 1000; + private static final long MILLI = MICRO * 1000; + private static final long SECOND = MILLI * 1000; + private static final long MINUTE = SECOND * 60; + public Performance(boolean enabled) { this.enabled = enabled; @@ -34,4 +40,51 @@ public class Performance { public boolean isEnabled() { return enabled; } + + private static String getAppropriateUnit(long timeInNanoseconds) { + + // more than 10 minutes + if(timeInNanoseconds > MINUTE * 10) { + return "minutes"; + } + // more than 10 seconds + else if(timeInNanoseconds > SECOND * 10) { + return "seconds"; + } + // more than 10 milliseconds + else if(timeInNanoseconds > MILLI * 10) { + return "milliseconds"; + } + // more than 10 microseconds + else if(timeInNanoseconds > MICRO * 10) { + return "microseconds"; + } else { + return "nanoseconds"; + } + } + + private static long convertToAppropriateUnit(long timeInNanoseconds) { + // more than 10 minutes + if(timeInNanoseconds > MINUTE * 10) { + return timeInNanoseconds / MINUTE; + } + // more than 10 seconds + else if(timeInNanoseconds > SECOND * 10) { + return timeInNanoseconds / SECOND; + } + // more than 10 milliseconds + else if(timeInNanoseconds > MILLI * 10) { + return timeInNanoseconds / MILLI; + } + // more than 10 microseconds + else if(timeInNanoseconds > MICRO * 10) { + return timeInNanoseconds / MICRO; + } else { + return timeInNanoseconds / NANO; + } + } + + public static String toString(long timeInNanoseconds) { + return convertToAppropriateUnit(timeInNanoseconds) + " " + getAppropriateUnit(timeInNanoseconds); + } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/debug/PerformanceManager.java b/src/cc/co/evenprime/bukkit/nocheat/debug/PerformanceManager.java index 37349573..a8997371 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/debug/PerformanceManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/debug/PerformanceManager.java @@ -9,11 +9,7 @@ public class PerformanceManager { BLOCKBREAK, BLOCKDAMAGE, BLOCKPLACE, CHAT, MOVING, VELOCITY, FIGHT } - private static final long NANO = 1; - private static final long MICRO = NANO * 1000; - private static final long MILLI = MICRO * 1000; - private static final long SECOND = MILLI * 1000; - private static final long MINUTE = SECOND * 60; + private final Map map; @@ -29,47 +25,4 @@ public class PerformanceManager { public Performance get(Type type) { return map.get(type); } - - public String getAppropriateUnit(long timeInNanoseconds) { - - // more than 10 minutes - if(timeInNanoseconds > MINUTE * 10) { - return "minutes"; - } - // more than 10 seconds - else if(timeInNanoseconds > SECOND * 10) { - return "seconds"; - } - // more than 10 milliseconds - else if(timeInNanoseconds > MILLI * 10) { - return "milliseconds"; - } - // more than 10 microseconds - else if(timeInNanoseconds > MICRO * 10) { - return "microseconds"; - } else { - return "nanoseconds"; - } - } - - public long convertToAppropriateUnit(long timeInNanoseconds) { - // more than 10 minutes - if(timeInNanoseconds > MINUTE * 10) { - return timeInNanoseconds / MINUTE; - } - // more than 10 seconds - else if(timeInNanoseconds > SECOND * 10) { - return timeInNanoseconds / SECOND; - } - // more than 10 milliseconds - else if(timeInNanoseconds > MILLI * 10) { - return timeInNanoseconds / MILLI; - } - // more than 10 microseconds - else if(timeInNanoseconds > MICRO * 10) { - return timeInNanoseconds / MICRO; - } else { - return timeInNanoseconds / NANO; - } - } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/BlockBreakEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/BlockBreakEventManager.java index 568528bb..c7c73c18 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/events/BlockBreakEventManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/events/BlockBreakEventManager.java @@ -24,8 +24,6 @@ import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager.Type; * Central location to listen to player-interact events and dispatch them to * relevant checks * - * @author Evenprime - * */ public class BlockBreakEventManager extends BlockListener implements EventManager { @@ -38,8 +36,8 @@ public class BlockBreakEventManager extends BlockListener implements EventManage this.plugin = plugin; this.blockBreakCheck = new BlockBreakCheck(plugin); - this.blockBreakPerformance = plugin.getPerformanceManager().get(Type.BLOCKBREAK); - this.blockDamagePerformance = plugin.getPerformanceManager().get(Type.BLOCKDAMAGE); + this.blockBreakPerformance = plugin.getPerformance(Type.BLOCKBREAK); + this.blockDamagePerformance = plugin.getPerformance(Type.BLOCKDAMAGE); PluginManager pm = Bukkit.getServer().getPluginManager(); @@ -62,7 +60,7 @@ public class BlockBreakEventManager extends BlockListener implements EventManage nanoTimeStart = System.nanoTime(); final Player player = event.getPlayer(); - final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName()); + final ConfigurationCache cc = plugin.getConfig(player); // Find out if checks need to be done for that player if(cc.blockbreak.check && !player.hasPermission(Permissions.BLOCKBREAK)) { @@ -98,7 +96,7 @@ public class BlockBreakEventManager extends BlockListener implements EventManage final Player player = event.getPlayer(); // Get the player-specific stored data that applies here - final BaseData data = plugin.getPlayerData(player); + final BaseData data = plugin.getData(player); // Remember this location. We ignore block breaks in the block-break // direction check that are insta-breaks diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/BlockPlaceEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/BlockPlaceEventManager.java index ce5352e2..53bf9654 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/events/BlockPlaceEventManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/events/BlockPlaceEventManager.java @@ -23,8 +23,6 @@ import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager.Type; * Central location to listen to Block-related events and dispatching them to * checks * - * @author Evenprime - * */ public class BlockPlaceEventManager extends BlockListener implements EventManager { @@ -41,7 +39,7 @@ public class BlockPlaceEventManager extends BlockListener implements EventManage this.movingCheck = new RunFlyCheck(plugin); this.blockPlaceCheck = new BlockPlaceCheck(plugin); - this.blockPlacePerformance = p.getPerformanceManager().get(Type.BLOCKPLACE); + this.blockPlacePerformance = p.getPerformance(Type.BLOCKPLACE); PluginManager pm = Bukkit.getServer().getPluginManager(); @@ -79,7 +77,7 @@ public class BlockPlaceEventManager extends BlockListener implements EventManage boolean cancel = false; final Player player = event.getPlayer(); - final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName()); + final ConfigurationCache cc = plugin.getConfig(player); // Find out if checks need to be done for that player if(cc.blockplace.check && !player.hasPermission(Permissions.BLOCKPLACE)) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/EntityDamageEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/EntityDamageEventManager.java index a1c4f44f..54f82230 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/events/EntityDamageEventManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/events/EntityDamageEventManager.java @@ -32,7 +32,7 @@ public class EntityDamageEventManager extends EntityListener implements EventMan this.plugin = plugin; this.fightCheck = new FightCheck(plugin); - this.fightPerformance = plugin.getPerformanceManager().get(Type.FIGHT); + this.fightPerformance = plugin.getPerformance(Type.FIGHT); PluginManager pm = Bukkit.getServer().getPluginManager(); @@ -64,7 +64,7 @@ public class EntityDamageEventManager extends EntityListener implements EventMan // possibilities above final Player player = (Player) ((EntityDamageByEntityEvent) event).getDamager(); - final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName()); + final ConfigurationCache cc = plugin.getConfig(player); // Find out if checks need to be done for that player if(cc.fight.check && !player.hasPermission(Permissions.FIGHT)) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerChatEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerChatEventManager.java index 8b095be1..e67a1d60 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerChatEventManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerChatEventManager.java @@ -20,8 +20,6 @@ import cc.co.evenprime.bukkit.nocheat.debug.Performance; import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager.Type; /** - * - * @author Evenprime * */ public class PlayerChatEventManager extends PlayerListener implements EventManager { @@ -35,7 +33,7 @@ public class PlayerChatEventManager extends PlayerListener implements EventManag this.plugin = plugin; this.chatCheck = new ChatCheck(plugin); - this.chatPerformance = plugin.getPerformanceManager().get(Type.CHAT); + this.chatPerformance = plugin.getPerformance(Type.CHAT); PluginManager pm = Bukkit.getServer().getPluginManager(); @@ -58,7 +56,7 @@ public class PlayerChatEventManager extends PlayerListener implements EventManag nanoTimeStart = System.nanoTime(); final Player player = event.getPlayer(); - final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName()); + final ConfigurationCache cc = plugin.getConfig(player); // Find out if checks need to be done for that player if(cc.chat.check && !player.hasPermission(Permissions.CHAT)) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerMoveEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerMoveEventManager.java index 9c3b0fd3..3e18eb7b 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerMoveEventManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerMoveEventManager.java @@ -28,8 +28,6 @@ import cc.co.evenprime.bukkit.nocheat.debug.PerformanceManager.Type; * Get the event, decide which checks should work on it and in what order, * evaluate the check results and decide what to * - * @author Evenprime - * */ public class PlayerMoveEventManager extends PlayerListener implements EventManager { @@ -44,8 +42,8 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag this.plugin = plugin; this.movingCheck = new RunFlyCheck(plugin); - this.movePerformance = plugin.getPerformanceManager().get(Type.MOVING); - this.velocityPerformance = plugin.getPerformanceManager().get(Type.VELOCITY); + this.movePerformance = plugin.getPerformance(Type.MOVING); + this.velocityPerformance = plugin.getPerformance(Type.VELOCITY); PluginManager pm = Bukkit.getServer().getPluginManager(); @@ -69,7 +67,7 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag // Get the world-specific configuration that applies here final Player player = event.getPlayer(); - final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName()); + final ConfigurationCache cc = plugin.getConfig(player); // Find out if checks need to be done for that player if(cc.moving.check && !player.hasPermission(Permissions.MOVE)) { @@ -95,7 +93,7 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag event.setTo(l); // Get the player-specific stored data that applies here - final BaseData data = plugin.getPlayerData(player); + final BaseData data = plugin.getData(player); data.moving.teleportTo = l; } @@ -120,7 +118,7 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag Player player = event.getPlayer(); - BaseData data = plugin.getPlayerData(player); + BaseData data = plugin.getData(player); Vector v = event.getVelocity(); diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java index de96f047..301de48b 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerQuitEventManager.java @@ -29,9 +29,6 @@ public class PlayerQuitEventManager extends PlayerListener implements EventManag @Override public void onPlayerQuit(PlayerQuitEvent event) { - // Get rid of the critical data that's stored for player immediately - plugin.clearCriticalPlayerData(event.getPlayer()); - // But only after a certain time, get rid of the rest of the data plugin.playerLeft(event.getPlayer()); } diff --git a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerTeleportEventManager.java b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerTeleportEventManager.java index 2a972acc..99df62eb 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/events/PlayerTeleportEventManager.java +++ b/src/cc/co/evenprime/bukkit/nocheat/events/PlayerTeleportEventManager.java @@ -23,8 +23,6 @@ import cc.co.evenprime.bukkit.nocheat.data.BaseData; * Only place that listens to Player-teleport related events and dispatches them * to relevant checks * - * @author Evenprime - * */ public class PlayerTeleportEventManager extends PlayerListener implements EventManager { @@ -52,7 +50,7 @@ public class PlayerTeleportEventManager extends PlayerListener implements EventM return; } - final BaseData data = plugin.getPlayerData(event.getPlayer()); + final BaseData data = plugin.getData(event.getPlayer()); if(data.moving.teleportTo != null && data.moving.teleportTo.equals(event.getTo())) { event.setCancelled(false); @@ -91,7 +89,7 @@ public class PlayerTeleportEventManager extends PlayerListener implements EventM private void handleTeleportation(Player player, Location newLocation) { - plugin.clearCriticalPlayerData(player); + plugin.clearCriticalData(player); } public List getActiveChecks(ConfigurationCache cc) {