From 45b4f11452db66ff770ce222f24dc30a1bcee824 Mon Sep 17 00:00:00 2001 From: Evenprime Date: Fri, 4 Mar 2011 20:38:54 +0100 Subject: [PATCH] Code cleanup --- plugin.yml | 2 +- .../bukkit/nocheat/NoCheatConfiguration.java | 62 +- .../evenprime/bukkit/nocheat/NoCheatData.java | 10 +- .../bukkit/nocheat/NoCheatPlugin.java | 256 +++---- .../bukkit/nocheat/checks/AirbuildCheck.java | 8 +- .../nocheat/checks/BedteleportCheck.java | 23 +- .../nocheat/checks/DupebydeathCheck.java | 9 +- .../bukkit/nocheat/checks/MovingCheck.java | 628 +++++++++--------- .../bukkit/nocheat/checks/SpeedhackCheck.java | 36 +- .../listeners/NoCheatBlockListener.java | 4 +- .../listeners/NoCheatEntityListener.java | 7 +- .../listeners/NoCheatPlayerListener.java | 50 +- 12 files changed, 548 insertions(+), 547 deletions(-) diff --git a/plugin.yml b/plugin.yml index d5eab181..7d39762d 100644 --- a/plugin.yml +++ b/plugin.yml @@ -3,5 +3,5 @@ name: NoCheatPlugin author: Evenprime main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin -version: 0.6.3 +version: 0.6.3a diff --git a/src/cc/co/evenprime/bukkit/nocheat/NoCheatConfiguration.java b/src/cc/co/evenprime/bukkit/nocheat/NoCheatConfiguration.java index 9ced18ab..63b0e5ad 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/NoCheatConfiguration.java +++ b/src/cc/co/evenprime/bukkit/nocheat/NoCheatConfiguration.java @@ -18,129 +18,129 @@ import org.bukkit.util.config.Configuration; * */ public class NoCheatConfiguration { - + // Our personal logger public static final String loggerName = "cc.co.evenprime.bukkit.nocheat"; public static final Logger logger = Logger.getLogger(loggerName); - + // Which checks are active public static boolean speedhackCheckActive; public static boolean movingCheckActive; public static boolean airbuildCheckActive; public static boolean dupebydeathCheckActive; public static boolean bedteleportCheckActive; - + // Limits for the speedhack check public static int speedhackLimitLow; public static int speedhackLimitMed; public static int speedhackLimitHigh; - + // How should speedhack violations be treated? public static String speedhackActionMinor = ""; public static String speedhackActionNormal = ""; public static String speedhackActionHeavy = ""; - + public static int movingFreeMoves = 10; - + // How should moving violations be treated? public static String movingActionMinor = ""; public static String movingActionNormal = ""; public static String movingActionHeavy = ""; - + // How should airbuild violations be treated? public static String airbuildAction = ""; - + // The log level above which players with the permission nocheat.notify will get informed about violations public static Level notifyLevel = Level.OFF; - + // Our two log outputs, the console and a file private static ConsoleHandler ch = null; private static FileHandler fh = null; - + private NoCheatConfiguration() {} - + /** * Read the configuration file and assign either standard values or whatever is declared in the file * @param configurationFile */ public static void config(File configurationFile) { - + if(!configurationFile.exists()) { createStandardConfigFile(configurationFile); } Configuration c = new Configuration(configurationFile); c.load(); - + logger.setLevel(Level.INFO); logger.setUseParentHandlers(false); - + if(ch == null) { ch = new ConsoleHandler(); - + ch.setLevel(stringToLevel(c.getString("logging.logtoconsole"))); ch.setFormatter(Logger.getLogger("Minecraft").getHandlers()[0].getFormatter()); logger.addHandler(ch); } - - + + if(fh == null) { try { fh = new FileHandler(c.getString("logging.filename"), true); fh.setLevel(stringToLevel(c.getString("logging.logtofile"))); fh.setFormatter(Logger.getLogger("Minecraft").getHandlers()[0].getFormatter()); logger.addHandler(fh); - + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } - + notifyLevel = stringToLevel(c.getString("logging.logtonotify")); - + speedhackCheckActive = c.getBoolean("active.speedhack", true); movingCheckActive = c.getBoolean("active.moving", true); airbuildCheckActive = c.getBoolean("active.airbuild", false); dupebydeathCheckActive = c.getBoolean("active.dupebydeath", true); bedteleportCheckActive = c.getBoolean("active.bedteleport", true); - + speedhackLimitLow = c.getInt("speedhack.limits.low", 30); speedhackLimitMed = c.getInt("speedhack.limits.med", 45); speedhackLimitHigh = c.getInt("speedhack.limits.high", 60); - + movingFreeMoves = c.getInt("moving.freemoves", 10); - + movingActionMinor = c.getString("moving.action.low", "loglow reset"); movingActionNormal = c.getString("moving.action.med", "logmed reset"); movingActionHeavy = c.getString("moving.action.high", "loghigh reset"); - + speedhackActionMinor = c.getString("speedhack.action.low", "loglow"); speedhackActionNormal = c.getString("speedhack.action.med", "logmed"); speedhackActionHeavy = c.getString("speedhack.action.high", "loghigh"); - + airbuildAction = c.getString("airbuild.action", "logmed deny"); - + if(movingFreeMoves < 10) movingFreeMoves = 10; } - + /** * Convert a string into a log level * @param string * @return */ private static Level stringToLevel(String string) { - + if(string == null) { return Level.OFF; } - + if(string.trim().equals("info") || string.trim().equals("low")) return Level.INFO; if(string.trim().equals("warn") || string.trim().equals("med")) return Level.WARNING; if(string.trim().equals("severe")|| string.trim().equals("high")) return Level.SEVERE; return Level.OFF; } - + /** * Standard configuration file for people who haven't got one yet * @param f @@ -150,7 +150,7 @@ public class NoCheatConfiguration { f.getParentFile().mkdirs(); f.createNewFile(); BufferedWriter w = new BufferedWriter(new FileWriter(f)); - + w.write("# Logging: potential log levels are low (info), med (warn), high (severe), off"); w.newLine(); w.write("logging:"); w.newLine(); w.write(" filename: plugins/NoCheat/nocheat.log"); w.newLine(); diff --git a/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java b/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java index fc77b173..a8452d7d 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java +++ b/src/cc/co/evenprime/bukkit/nocheat/NoCheatData.java @@ -9,23 +9,21 @@ import org.bukkit.Location; * */ public class NoCheatData { - + /** * Don't rely on any of these yet, they are likely going to change their name/functionality */ - + public int movingJumpPhase = 0; // current jumpingPhase public int movingMinorViolationsInARow = 0; public int movingNormalViolationsInARow = 0; public int movingHeavyViolationsInARow = 0; public Location movingSetBackPoint = null; - - public int movingIgnoreNextXEvents = 0; - + public long speedhackLastCheck = System.currentTimeMillis(); // timestamp of last check for speedhacks public Location speedhackSetBackPoint = null; public int speedhackEventsSinceLastCheck = 0; // used to identify speedhacks public int speedhackViolationsInARow = 0; - + NoCheatData() { } } \ No newline at end of file diff --git a/src/cc/co/evenprime/bukkit/nocheat/NoCheatPlugin.java b/src/cc/co/evenprime/bukkit/nocheat/NoCheatPlugin.java index 5e97af7f..16efd030 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/NoCheatPlugin.java +++ b/src/cc/co/evenprime/bukkit/nocheat/NoCheatPlugin.java @@ -22,46 +22,46 @@ import com.nijiko.permissions.PermissionHandler; import org.bukkit.plugin.Plugin; /** -* -* NoCheatPlugin -* -* Check various player events for their plausibilty and log/deny them based on configuration -* -* @author Evenprime -*/ + * + * NoCheatPlugin + * + * Check various player events for their plausibilty and log/deny them based on configuration + * + * @author Evenprime + */ public class NoCheatPlugin extends JavaPlugin { - - // Various listeners needed for different Checks - private NoCheatPlayerListener playerListener; - private NoCheatBlockListener blockListener; - private NoCheatEntityListener entityListener; - - // My main logger - private static Logger log; - - private static NoCheatPlugin p; - - // Permissions 2.0, if available - public static PermissionHandler Permissions = null; - - // Store data between Events - public static Map playerData = new HashMap(); - public NoCheatPlugin() { - p = this; - } - - /** - * Main access to data that needs to be stored between different events. - * Always returns a NoCheatData object, because if there isn't one - * for the specified player, one will be created. - * - * @param p - * @return - */ - public static NoCheatData getPlayerData(Player p) { - NoCheatData data = null; - + // Various listeners needed for different Checks + private NoCheatPlayerListener playerListener; + private NoCheatBlockListener blockListener; + private NoCheatEntityListener entityListener; + + // My main logger + private static Logger log; + + private static NoCheatPlugin p; + + // Permissions 2.0, if available + public static PermissionHandler Permissions = null; + + // Store data between Events + public static Map playerData = new HashMap(); + + public NoCheatPlugin() { + p = this; + } + + /** + * Main access to data that needs to be stored between different events. + * Always returns a NoCheatData object, because if there isn't one + * for the specified player, one will be created. + * + * @param p + * @return + */ + public static NoCheatData getPlayerData(Player p) { + NoCheatData data = null; + if((data = playerData.get(p)) == null ) { synchronized(playerData) { data = playerData.get(p); @@ -72,98 +72,98 @@ public class NoCheatPlugin extends JavaPlugin { } } } - + return data; - } + } - public void onDisable() { - PluginDescriptionFile pdfFile = this.getDescription(); - Logger.getLogger("Minecraft").info( "[NoCheatPlugin] version [" + pdfFile.getVersion() + "] is disabled."); - } + public void onDisable() { + PluginDescriptionFile pdfFile = this.getDescription(); + Logger.getLogger("Minecraft").info( "[NoCheatPlugin] version [" + pdfFile.getVersion() + "] is disabled."); + } - public void onEnable() { - // Create our listeners and feed them with neccessary information - playerListener = new NoCheatPlayerListener(); - blockListener = new NoCheatBlockListener(); - entityListener = new NoCheatEntityListener(); + public void onEnable() { + // Create our listeners and feed them with neccessary information + playerListener = new NoCheatPlayerListener(); + blockListener = new NoCheatBlockListener(); + entityListener = new NoCheatEntityListener(); - log = NoCheatConfiguration.logger; - - PluginManager pm = getServer().getPluginManager(); - pm.registerEvent(Event.Type.PLAYER_MOVE, playerListener, Priority.Lowest, this); // needed for speedhack and moving checks - pm.registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Monitor, this); // used to delete old data of users - pm.registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Low, this); // used for airbuild check - pm.registerEvent(Event.Type.ENTITY_DEATH, entityListener, Priority.Highest, this); // used for dupebydeath check - pm.registerEvent(Event.Type.PLAYER_TELEPORT, playerListener, Priority.Lowest, this); // used for teleportfrombed check + log = NoCheatConfiguration.logger; - PluginDescriptionFile pdfFile = this.getDescription(); - - // Get, if available, the Permissions plugin - setupPermissions(); - - // parse the nocheat.yml config file - setupConfig(); - - String checks = (NoCheatConfiguration.movingCheckActive ? "moving ": "") + - (NoCheatConfiguration.speedhackCheckActive ? "speedhack " : "") + - (NoCheatConfiguration.airbuildCheckActive ? "airbuild " : "") + - (NoCheatConfiguration.dupebydeathCheckActive ? "dupebydeath " : "") + - (NoCheatConfiguration.bedteleportCheckActive ? "bedteleport " : ""); - - Logger.getLogger("Minecraft").info( "[NoCheatPlugin] version [" + pdfFile.getVersion() + "] is enabled with the following checks: "+checks); - } + PluginManager pm = getServer().getPluginManager(); + pm.registerEvent(Event.Type.PLAYER_MOVE, playerListener, Priority.Lowest, this); // needed for speedhack and moving checks + pm.registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Monitor, this); // used to delete old data of users + pm.registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Low, this); // used for airbuild check + pm.registerEvent(Event.Type.ENTITY_DEATH, entityListener, Priority.Highest, this); // used for dupebydeath check + pm.registerEvent(Event.Type.PLAYER_TELEPORT, playerListener, Priority.Lowest, this); // used for teleportfrombed check - /** - * Get, if available, a reference to the Permissions-plugin - */ - public void setupPermissions() { - Permissions = null; - - Plugin test = this.getServer().getPluginManager().getPlugin("Permissions"); + PluginDescriptionFile pdfFile = this.getDescription(); - if(test != null) { - Permissions = ((Permissions)test).getHandler(); - if(Permissions == null) { - this.getServer().getPluginManager().enablePlugin(test); - } - Permissions = ((Permissions)test).getHandler(); - } - - if(Permissions == null) { - log.info("Nocheat couldn't find Permissions plugin. Fallback to 'isOp()' equals 'all allowed'."); - } - } - - /** - * Log a violation message to all locations declared in the config file - * @param message - */ - private static void log(Level l, String message) { - if(l != null) { - logToChat(l, message); - log.log(l, message); - } - } + // Get, if available, the Permissions plugin + setupPermissions(); + + // parse the nocheat.yml config file + setupConfig(); + + String checks = (NoCheatConfiguration.movingCheckActive ? "moving ": "") + + (NoCheatConfiguration.speedhackCheckActive ? "speedhack " : "") + + (NoCheatConfiguration.airbuildCheckActive ? "airbuild " : "") + + (NoCheatConfiguration.dupebydeathCheckActive ? "dupebydeath " : "") + + (NoCheatConfiguration.bedteleportCheckActive ? "bedteleport " : ""); + + Logger.getLogger("Minecraft").info( "[NoCheatPlugin] version [" + pdfFile.getVersion() + "] is enabled with the following checks: "+checks); + } + + /** + * Get, if available, a reference to the Permissions-plugin + */ + public void setupPermissions() { + Permissions = null; + + Plugin test = this.getServer().getPluginManager().getPlugin("Permissions"); + + if(test != null) { + Permissions = ((Permissions)test).getHandler(); + if(Permissions == null) { + this.getServer().getPluginManager().enablePlugin(test); + } + Permissions = ((Permissions)test).getHandler(); + } + + if(Permissions == null) { + log.info("Nocheat couldn't find Permissions plugin. Fallback to 'isOp()' equals 'all allowed'."); + } + } + + /** + * Log a violation message to all locations declared in the config file + * @param message + */ + private static void log(Level l, String message) { + if(l != null) { + logToChat(l, message); + log.log(l, message); + } + } + + + + private static void logToChat(Level l, String message) { + if(NoCheatConfiguration.notifyLevel.intValue() <= l.intValue()) { + for(Player player : p.getServer().getOnlinePlayers()) { + if((Permissions != null && Permissions.has(player, "nocheat.notify")) || + (Permissions == null && player.isOp())) { + player.sendMessage("["+l.getName()+"] " + message); + } + } + } + } + + public static void logAction(String actions, String message) { + if(actions == null) return; - - - private static void logToChat(Level l, String message) { - if(NoCheatConfiguration.notifyLevel.intValue() <= l.intValue()) { - for(Player player : p.getServer().getOnlinePlayers()) { - if((Permissions != null && Permissions.has(player, "nocheat.notify")) || - (Permissions == null && player.isOp())) { - player.sendMessage("["+l.getName()+"] " + message); - } - } - } - } - - public static void logAction(String actions, String message) { - if(actions == null) return; - // LOGGING IF NEEDED AND WHERE NEEDED Level logLevel = null; - + if(actions.contains("loglow")) { logLevel = Level.INFO; } @@ -173,15 +173,15 @@ public class NoCheatPlugin extends JavaPlugin { if(actions.contains("loghigh")) { logLevel = Level.SEVERE; } - + if(logLevel != null) { NoCheatPlugin.log(logLevel, "NC: "+message); } - } - /** - * Read the config file - */ - public void setupConfig() { - NoCheatConfiguration.config(new File("plugins/NoCheat/nocheat.yml")); - } + } + /** + * Read the config file + */ + public void setupConfig() { + NoCheatConfiguration.config(new File("plugins/NoCheat/nocheat.yml")); + } } \ No newline at end of file diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/AirbuildCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/AirbuildCheck.java index a3a26a0a..15fdaafb 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/AirbuildCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/AirbuildCheck.java @@ -40,17 +40,17 @@ public class AirbuildCheck { w.getBlockTypeIdAt(l.getBlockX(), l.getBlockY(), l.getBlockZ()-1) == airId && w.getBlockTypeIdAt(l.getBlockX(), l.getBlockY(), l.getBlockZ()+1) == airId) action(NoCheatConfiguration.airbuildAction, event); - + } - + private static void action(String action, BlockPlaceEvent event) { - + // LOG IF NEEDED if(action.contains("log")) { Location l = event.getBlockPlaced().getLocation(); NoCheatPlugin.logAction(action, "NoCheatPlugin: Airbuild violation: "+event.getPlayer().getName()+" tried to place block " + event.getBlockPlaced().getType() + " in the air at " + l.getBlockX() + "," + l.getBlockY() +"," + l.getBlockZ()); } - + // DENY IF NEEDED if(action.contains("deny")) { event.setCancelled(true); diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/BedteleportCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/BedteleportCheck.java index ba3391d9..0b89fb85 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/BedteleportCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/BedteleportCheck.java @@ -5,24 +5,29 @@ import org.bukkit.event.player.PlayerMoveEvent; import cc.co.evenprime.bukkit.nocheat.NoCheatPlugin; +/** + * + * @author Evenprime + * + */ public class BedteleportCheck { public static void check(PlayerMoveEvent event) { - + // Should we check at all - if(NoCheatPlugin.Permissions != null && NoCheatPlugin.Permissions.has(event.getPlayer(), "nocheat.bedteleport")) { + if(NoCheatPlugin.Permissions != null && NoCheatPlugin.Permissions.has(event.getPlayer(), "nocheat.bedteleport")) { return; } else if(NoCheatPlugin.Permissions == null && event.getPlayer().isOp() ) { return; } - - if(event.getFrom().getWorld().getBlockTypeIdAt(event.getFrom()) == Material.BED_BLOCK.getId()) { - double yRest = Math.floor(event.getFrom().getY()) - event.getFrom().getY(); - if(yRest > 0.099 && yRest < 0.101) - // Don't allow the teleport - event.setCancelled(true); - } + + if(event.getFrom().getWorld().getBlockTypeIdAt(event.getFrom()) == Material.BED_BLOCK.getId()) { + double yRest = Math.floor(event.getFrom().getY()) - event.getFrom().getY(); + if(yRest > 0.099 && yRest < 0.101) + // Don't allow the teleport + event.setCancelled(true); + } } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/DupebydeathCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/DupebydeathCheck.java index 296c744c..6c6a9f33 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/DupebydeathCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/DupebydeathCheck.java @@ -9,6 +9,11 @@ import org.bukkit.inventory.PlayerInventory; import cc.co.evenprime.bukkit.nocheat.NoCheatPlugin; +/** + * + * @author Evenprime + * + */ public class DupebydeathCheck { /** @@ -16,7 +21,7 @@ public class DupebydeathCheck { * @param event */ public static void playerDeath(EntityDeathEvent event) { - + if(event.getEntity() instanceof Player) { Player p = (Player)event.getEntity(); @@ -28,7 +33,7 @@ public class DupebydeathCheck { else if(NoCheatPlugin.Permissions == null && p.isOp() ) { return; } - + PlayerInventory playerInventory = p.getInventory(); List drops = event.getDrops(); diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/MovingCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/MovingCheck.java index 85959274..b9b55852 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/MovingCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/MovingCheck.java @@ -21,304 +21,304 @@ import cc.co.evenprime.bukkit.nocheat.NoCheatPlugin; public class MovingCheck { // previously-calculated upper bound values for jumps. Minecraft is very deterministic when it comes to jumps - // Each entry represents the maximum gain in height per move event. - private static double jumpingPhases[] = new double[]{ 0.501D, 0.34D, 0.26D, 0.17D, 0.09D, 0.02D, 0.00D, -0.07D, -0.15D, -0.22D, -0.29D, -0.36D, -0.43D, -0.49D }; - + // Each entry represents the maximum gain in height per move event. + private static double jumpingPhases[] = new double[]{ 0.501D, 0.34D, 0.26D, 0.17D, 0.09D, 0.02D, 0.00D, -0.07D, -0.15D, -0.22D, -0.29D, -0.36D, -0.43D, -0.49D }; + // Limits for the moving check public static double movingDistanceLow = 0.1D; public static double movingDistanceMed = 2.0D; public static double movingDistanceHigh = 5.0D; - - // Block types that may be treated specially - private enum BlockType { + + // Block types that may be treated specially + private enum BlockType { SOLID, NONSOLID, LADDER, LIQUID, UNKNOWN; } - - // Until I can think of a better way to determine if a block is solid or not, this is what I'll do - private static BlockType types[] = new BlockType[256]; - static { - - for(int i = 0; i < types.length; i++) { - types[i] = BlockType.UNKNOWN; - } - - types[Material.AIR.getId()] = BlockType.NONSOLID; - types[Material.STONE.getId()] = BlockType.SOLID; - types[Material.GRASS.getId()] = BlockType.SOLID; - types[Material.DIRT.getId()] = BlockType.SOLID; - types[Material.COBBLESTONE.getId()] = BlockType.SOLID; - types[Material.WOOD.getId()] = BlockType.SOLID; - types[Material.SAPLING.getId()] = BlockType.NONSOLID; - types[Material.BEDROCK.getId()] = BlockType.SOLID; - types[Material.WATER.getId()] = BlockType.LIQUID; - types[Material.STATIONARY_WATER.getId()] = BlockType.LIQUID; - types[Material.LAVA.getId()] = BlockType.LIQUID; - types[Material.STATIONARY_LAVA.getId()] = BlockType.LIQUID; - types[Material.SAND.getId()] = BlockType.SOLID; - types[Material.GRAVEL.getId()] = BlockType.SOLID; - types[Material.GOLD_ORE.getId()] = BlockType.SOLID; - types[Material.IRON_ORE.getId()] = BlockType.SOLID; - types[Material.COAL_ORE.getId()] = BlockType.SOLID; - types[Material.LOG.getId()] = BlockType.SOLID; - types[Material.LEAVES.getId()] = BlockType.SOLID; - types[Material.SPONGE.getId()] = BlockType.SOLID; - types[Material.GLASS.getId()] = BlockType.SOLID; - types[Material.LAPIS_ORE.getId()] = BlockType.SOLID; - types[Material.LAPIS_BLOCK.getId()] = BlockType.SOLID; - types[Material.DISPENSER.getId()] = BlockType.SOLID; - types[Material.SANDSTONE.getId()] = BlockType.SOLID; - types[Material.NOTE_BLOCK.getId()]= BlockType.SOLID; - types[Material.WOOL.getId()]= BlockType.SOLID; - types[Material.YELLOW_FLOWER.getId()]= BlockType.NONSOLID; - types[Material.RED_ROSE.getId()]= BlockType.NONSOLID; - types[Material.BROWN_MUSHROOM.getId()]= BlockType.NONSOLID; - types[Material.RED_MUSHROOM.getId()]= BlockType.NONSOLID; - types[Material.GOLD_BLOCK.getId()]= BlockType.SOLID; - types[Material.IRON_BLOCK.getId()]= BlockType.SOLID; - types[Material.DOUBLE_STEP.getId()]= BlockType.UNKNOWN; - types[Material.STEP.getId()]= BlockType.UNKNOWN; - types[Material.BRICK.getId()]= BlockType.SOLID; - types[Material.TNT.getId()]= BlockType.SOLID; - types[Material.BOOKSHELF.getId()]= BlockType.SOLID; - types[Material.MOSSY_COBBLESTONE.getId()] = BlockType.SOLID; - types[Material.OBSIDIAN.getId()]= BlockType.SOLID; - types[Material.TORCH.getId()]= BlockType.NONSOLID; - types[Material.FIRE.getId()]= BlockType.NONSOLID; - types[Material.MOB_SPAWNER.getId()]= BlockType.SOLID; - types[Material.WOOD_STAIRS.getId()]= BlockType.UNKNOWN; - types[Material.CHEST.getId()]= BlockType.SOLID; - types[Material.REDSTONE_WIRE.getId()]= BlockType.NONSOLID; - types[Material.DIAMOND_ORE.getId()]= BlockType.SOLID; - types[Material.DIAMOND_BLOCK.getId()]= BlockType.SOLID; - types[Material.WORKBENCH.getId()]= BlockType.SOLID; - types[Material.CROPS.getId()]= BlockType.NONSOLID; - types[Material.SOIL.getId()]= BlockType.SOLID; - types[Material.FURNACE.getId()]= BlockType.SOLID; - types[Material.BURNING_FURNACE.getId()]= BlockType.SOLID; - types[Material.SIGN_POST.getId()]= BlockType.NONSOLID; - types[Material.WOODEN_DOOR.getId()]= BlockType.NONSOLID; - types[Material.LADDER.getId()]= BlockType.LADDER; - types[Material.RAILS.getId()]= BlockType.NONSOLID; - types[Material.COBBLESTONE_STAIRS.getId()]= BlockType.UNKNOWN; - types[Material.WALL_SIGN.getId()]= BlockType.NONSOLID; - types[Material.LEVER.getId()]= BlockType.NONSOLID; - types[Material.STONE_PLATE.getId()]= BlockType.UNKNOWN; - types[Material.IRON_DOOR_BLOCK.getId()]= BlockType.NONSOLID; - types[Material.WOOD_PLATE.getId()]= BlockType.NONSOLID; - types[Material.REDSTONE_ORE.getId()]= BlockType.SOLID; - types[Material.GLOWING_REDSTONE_ORE.getId()]= BlockType.SOLID; - types[Material.REDSTONE_TORCH_OFF.getId()]= BlockType.NONSOLID; - types[Material.REDSTONE_TORCH_ON.getId()]= BlockType.NONSOLID; - types[Material.STONE_BUTTON.getId()]= BlockType.NONSOLID; - types[Material.SNOW.getId()]= BlockType.UNKNOWN; - types[Material.ICE.getId()]= BlockType.UNKNOWN; - types[Material.SNOW_BLOCK.getId()]= BlockType.SOLID; - types[Material.CACTUS.getId()]= BlockType.SOLID; - types[Material.CLAY.getId()]= BlockType.SOLID; - types[Material.SUGAR_CANE_BLOCK.getId()]= BlockType.NONSOLID; - types[Material.JUKEBOX.getId()]= BlockType.SOLID; - types[Material.FENCE.getId()]= BlockType.UNKNOWN; - types[Material.PUMPKIN.getId()]= BlockType.SOLID; - types[Material.NETHERRACK.getId()]= BlockType.SOLID; - types[Material.SOUL_SAND.getId()]= BlockType.UNKNOWN; - types[Material.GLOWSTONE.getId()]= BlockType.SOLID; - types[Material.PORTAL.getId()]= BlockType.NONSOLID; - types[Material.JACK_O_LANTERN.getId()]= BlockType.SOLID; - types[Material.CAKE_BLOCK.getId()]= BlockType.UNKNOWN; - } - + + // Until I can think of a better way to determine if a block is solid or not, this is what I'll do + private static BlockType types[] = new BlockType[256]; + static { + + for(int i = 0; i < types.length; i++) { + types[i] = BlockType.UNKNOWN; + } + + types[Material.AIR.getId()] = BlockType.NONSOLID; + types[Material.STONE.getId()] = BlockType.SOLID; + types[Material.GRASS.getId()] = BlockType.SOLID; + types[Material.DIRT.getId()] = BlockType.SOLID; + types[Material.COBBLESTONE.getId()] = BlockType.SOLID; + types[Material.WOOD.getId()] = BlockType.SOLID; + types[Material.SAPLING.getId()] = BlockType.NONSOLID; + types[Material.BEDROCK.getId()] = BlockType.SOLID; + types[Material.WATER.getId()] = BlockType.LIQUID; + types[Material.STATIONARY_WATER.getId()] = BlockType.LIQUID; + types[Material.LAVA.getId()] = BlockType.LIQUID; + types[Material.STATIONARY_LAVA.getId()] = BlockType.LIQUID; + types[Material.SAND.getId()] = BlockType.SOLID; + types[Material.GRAVEL.getId()] = BlockType.SOLID; + types[Material.GOLD_ORE.getId()] = BlockType.SOLID; + types[Material.IRON_ORE.getId()] = BlockType.SOLID; + types[Material.COAL_ORE.getId()] = BlockType.SOLID; + types[Material.LOG.getId()] = BlockType.SOLID; + types[Material.LEAVES.getId()] = BlockType.SOLID; + types[Material.SPONGE.getId()] = BlockType.SOLID; + types[Material.GLASS.getId()] = BlockType.SOLID; + types[Material.LAPIS_ORE.getId()] = BlockType.SOLID; + types[Material.LAPIS_BLOCK.getId()] = BlockType.SOLID; + types[Material.DISPENSER.getId()] = BlockType.SOLID; + types[Material.SANDSTONE.getId()] = BlockType.SOLID; + types[Material.NOTE_BLOCK.getId()]= BlockType.SOLID; + types[Material.WOOL.getId()]= BlockType.SOLID; + types[Material.YELLOW_FLOWER.getId()]= BlockType.NONSOLID; + types[Material.RED_ROSE.getId()]= BlockType.NONSOLID; + types[Material.BROWN_MUSHROOM.getId()]= BlockType.NONSOLID; + types[Material.RED_MUSHROOM.getId()]= BlockType.NONSOLID; + types[Material.GOLD_BLOCK.getId()]= BlockType.SOLID; + types[Material.IRON_BLOCK.getId()]= BlockType.SOLID; + types[Material.DOUBLE_STEP.getId()]= BlockType.UNKNOWN; + types[Material.STEP.getId()]= BlockType.UNKNOWN; + types[Material.BRICK.getId()]= BlockType.SOLID; + types[Material.TNT.getId()]= BlockType.SOLID; + types[Material.BOOKSHELF.getId()]= BlockType.SOLID; + types[Material.MOSSY_COBBLESTONE.getId()] = BlockType.SOLID; + types[Material.OBSIDIAN.getId()]= BlockType.SOLID; + types[Material.TORCH.getId()]= BlockType.NONSOLID; + types[Material.FIRE.getId()]= BlockType.NONSOLID; + types[Material.MOB_SPAWNER.getId()]= BlockType.SOLID; + types[Material.WOOD_STAIRS.getId()]= BlockType.UNKNOWN; + types[Material.CHEST.getId()]= BlockType.SOLID; + types[Material.REDSTONE_WIRE.getId()]= BlockType.NONSOLID; + types[Material.DIAMOND_ORE.getId()]= BlockType.SOLID; + types[Material.DIAMOND_BLOCK.getId()]= BlockType.SOLID; + types[Material.WORKBENCH.getId()]= BlockType.SOLID; + types[Material.CROPS.getId()]= BlockType.NONSOLID; + types[Material.SOIL.getId()]= BlockType.SOLID; + types[Material.FURNACE.getId()]= BlockType.SOLID; + types[Material.BURNING_FURNACE.getId()]= BlockType.SOLID; + types[Material.SIGN_POST.getId()]= BlockType.NONSOLID; + types[Material.WOODEN_DOOR.getId()]= BlockType.NONSOLID; + types[Material.LADDER.getId()]= BlockType.LADDER; + types[Material.RAILS.getId()]= BlockType.NONSOLID; + types[Material.COBBLESTONE_STAIRS.getId()]= BlockType.UNKNOWN; + types[Material.WALL_SIGN.getId()]= BlockType.NONSOLID; + types[Material.LEVER.getId()]= BlockType.NONSOLID; + types[Material.STONE_PLATE.getId()]= BlockType.UNKNOWN; + types[Material.IRON_DOOR_BLOCK.getId()]= BlockType.NONSOLID; + types[Material.WOOD_PLATE.getId()]= BlockType.NONSOLID; + types[Material.REDSTONE_ORE.getId()]= BlockType.SOLID; + types[Material.GLOWING_REDSTONE_ORE.getId()]= BlockType.SOLID; + types[Material.REDSTONE_TORCH_OFF.getId()]= BlockType.NONSOLID; + types[Material.REDSTONE_TORCH_ON.getId()]= BlockType.NONSOLID; + types[Material.STONE_BUTTON.getId()]= BlockType.NONSOLID; + types[Material.SNOW.getId()]= BlockType.UNKNOWN; + types[Material.ICE.getId()]= BlockType.UNKNOWN; + types[Material.SNOW_BLOCK.getId()]= BlockType.SOLID; + types[Material.CACTUS.getId()]= BlockType.SOLID; + types[Material.CLAY.getId()]= BlockType.SOLID; + types[Material.SUGAR_CANE_BLOCK.getId()]= BlockType.NONSOLID; + types[Material.JUKEBOX.getId()]= BlockType.SOLID; + types[Material.FENCE.getId()]= BlockType.UNKNOWN; + types[Material.PUMPKIN.getId()]= BlockType.SOLID; + types[Material.NETHERRACK.getId()]= BlockType.SOLID; + types[Material.SOUL_SAND.getId()]= BlockType.UNKNOWN; + types[Material.GLOWSTONE.getId()]= BlockType.SOLID; + types[Material.PORTAL.getId()]= BlockType.NONSOLID; + types[Material.JACK_O_LANTERN.getId()]= BlockType.SOLID; + types[Material.CAKE_BLOCK.getId()]= BlockType.UNKNOWN; + } + public static void check(NoCheatData data, PlayerMoveEvent event) { - + // Should we check at all - if(NoCheatPlugin.Permissions != null && NoCheatPlugin.Permissions.has(event.getPlayer(), "nocheat.moving")) { + if(NoCheatPlugin.Permissions != null && NoCheatPlugin.Permissions.has(event.getPlayer(), "nocheat.moving")) { return; } else if(NoCheatPlugin.Permissions == null && event.getPlayer().isOp() ) { return; } - - // Get the two locations of the event + + // Get the two locations of the event Location from = event.getFrom(); Location to = event.getTo(); - + System.out.println(from.getY() + " " + to.getY()); - // First check the distance the player has moved horizontally - // TODO: Make this check much more precise - double xDistance = Math.abs(from.getX() - to.getX()); - double zDistance = Math.abs(from.getZ() - to.getZ()); - double combined = xDistance * xDistance + zDistance * zDistance; - + // First check the distance the player has moved horizontally + // TODO: Make this check much more precise + double xDistance = Math.abs(from.getX() - to.getX()); + double zDistance = Math.abs(from.getZ() - to.getZ()); + double combined = xDistance * xDistance + zDistance * zDistance; + // If the target is a bed and distance not too big, allow it - if(to.getWorld().getBlockTypeIdAt(to) == Material.BED_BLOCK.getId() && xDistance < 5.0D && zDistance < 5.0D) { - return; // players are allowed to "teleport" into a bed over short distances - } - + if(to.getWorld().getBlockTypeIdAt(to) == Material.BED_BLOCK.getId() && xDistance < 5.0D && zDistance < 5.0D) { + return; // players are allowed to "teleport" into a bed over short distances + } + Level vl = null; // The violation level (none, minor, normal, heavy) - - // How far are we off? - if(combined > movingDistanceHigh) { - vl = max(vl, Level.SEVERE); - } - else if(combined > movingDistanceMed) { - vl = max(vl, Level.WARNING); - } - else if(combined > movingDistanceLow) { - vl = max(vl, Level.INFO); - } - // pre-calculate boundary values that are needed multiple times in the following checks - // the array each contains [lowerX, higherX, Y, lowerZ, higherZ] - int fromValues[] = {floor_double(from.getX() - 0.3D), (int)Math.floor(from.getX() + 0.3D), from.getBlockY(), floor_double(from.getZ() - 0.3D),(int)Math.floor(from.getZ() + 0.3D) }; - int toValues[] = {floor_double(to.getX() - 0.3D), (int)Math.floor(to.getX() + 0.3D), to.getBlockY(), floor_double(to.getZ() - 0.3D), (int)Math.floor(to.getZ() + 0.3D) }; - - // compare locations to the world to guess if the player is standing on the ground, a half-block or next to a ladder - boolean onGroundFrom = playerIsOnGround(from.getWorld(), fromValues, from); - boolean onGroundTo = playerIsOnGround(from.getWorld(), toValues, to); + // How far are we off? + if(combined > movingDistanceHigh) { + vl = max(vl, Level.SEVERE); + } + else if(combined > movingDistanceMed) { + vl = max(vl, Level.WARNING); + } + else if(combined > movingDistanceLow) { + vl = max(vl, Level.INFO); + } - // Both locations seem to be on solid ground or at a ladder - if(onGroundFrom && onGroundTo) - { - // reset jumping - data.movingJumpPhase = 0; + // pre-calculate boundary values that are needed multiple times in the following checks + // the array each contains [lowerX, higherX, Y, lowerZ, higherZ] + int fromValues[] = {floor_double(from.getX() - 0.3D), (int)Math.floor(from.getX() + 0.3D), from.getBlockY(), floor_double(from.getZ() - 0.3D),(int)Math.floor(from.getZ() + 0.3D) }; + int toValues[] = {floor_double(to.getX() - 0.3D), (int)Math.floor(to.getX() + 0.3D), to.getBlockY(), floor_double(to.getZ() - 0.3D), (int)Math.floor(to.getZ() + 0.3D) }; - // Check if the player isn't 'walking' up unrealistically far in one step - // Finally found out why this can happen: - // If a player runs into a wall at an angle from above, the game tries to - // place him above the block he bumped into, by placing him 0.5 m above - // the target block - if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { + // compare locations to the world to guess if the player is standing on the ground, a half-block or next to a ladder + boolean onGroundFrom = playerIsOnGround(from.getWorld(), fromValues, from); + boolean onGroundTo = playerIsOnGround(from.getWorld(), toValues, to); - double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; + // Both locations seem to be on solid ground or at a ladder + if(onGroundFrom && onGroundTo) + { + // reset jumping + data.movingJumpPhase = 0; - if(offset > 2D) vl = max(vl, Level.SEVERE); - else if(offset > 1D) vl = max(vl, Level.WARNING); - else vl = max(vl, Level.INFO); - } - } - // player is starting to jump (or starting to fall down somewhere) - else if(onGroundFrom && !onGroundTo) - { - // reset jumping - data.movingJumpPhase = 0; + // Check if the player isn't 'walking' up unrealistically far in one step + // Finally found out why this can happen: + // If a player runs into a wall at an angle from above, the game tries to + // place him above the block he bumped into, by placing him 0.5 m above + // the target block + if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { - // Check if player isn't jumping too high - if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { + double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; - double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; + if(offset > 2D) vl = max(vl, Level.SEVERE); + else if(offset > 1D) vl = max(vl, Level.WARNING); + else vl = max(vl, Level.INFO); + } + } + // player is starting to jump (or starting to fall down somewhere) + else if(onGroundFrom && !onGroundTo) + { + // reset jumping + data.movingJumpPhase = 0; - if(offset > 2D) vl = max(vl, Level.SEVERE); - else if(offset > 1D) vl = max(vl, Level.WARNING); - else vl = max(vl, Level.INFO); - } - else if(to.getY() <= from.getY()) { - // Very special case if running over a cliff and then immediately jumping. - // Some sort of "air jump", MC allows it, so we have to do so too. - } - else data.movingJumpPhase++; // Setup next phase of the jump - } - // player is probably landing somewhere - else if(!onGroundFrom && onGroundTo) - { - // Check if player isn't landing to high (sounds weird, but has its use) - if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { + // Check if player isn't jumping too high + if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { - double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; + double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; - if(offset > 2D) vl = max(vl, Level.SEVERE); - else if(offset > 1D) vl = max(vl, Level.WARNING); - else vl = max(vl, Level.INFO); - } - else { - data.movingJumpPhase = 0; // He is on ground now, so reset the jump - } - } - // Player is moving through air (during jumping, falling) - else { - // May also be at the very edge of a platform (I seem to not be able to reliably tell if that's the case) - if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { + if(offset > 2D) vl = max(vl, Level.SEVERE); + else if(offset > 1D) vl = max(vl, Level.WARNING); + else vl = max(vl, Level.INFO); + } + else if(to.getY() <= from.getY()) { + // Very special case if running over a cliff and then immediately jumping. + // Some sort of "air jump", MC allows it, so we have to do so too. + } + else data.movingJumpPhase++; // Setup next phase of the jump + } + // player is probably landing somewhere + else if(!onGroundFrom && onGroundTo) + { + // Check if player isn't landing to high (sounds weird, but has its use) + if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { - double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; + double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; - if(offset > 2D) vl = max(vl, Level.SEVERE); - else if(offset > 1D) vl = max(vl, Level.WARNING); - else vl = max(vl, Level.INFO); - } + if(offset > 2D) vl = max(vl, Level.SEVERE); + else if(offset > 1D) vl = max(vl, Level.WARNING); + else vl = max(vl, Level.INFO); + } + else { + data.movingJumpPhase = 0; // He is on ground now, so reset the jump + } + } + // Player is moving through air (during jumping, falling) + else { + // May also be at the very edge of a platform (I seem to not be able to reliably tell if that's the case) + if(!(to.getY() - from.getY() < jumpingPhases[data.movingJumpPhase])) { - data.movingJumpPhase++; // Enter next phase of the flight - } + double offset = (to.getY() - from.getY()) - jumpingPhases[data.movingJumpPhase]; - // do a security check on the jumping phase, such that we don't get - // OutOfArrayBoundsExceptions at long air times (falling off high places) - if(!(data.movingJumpPhase < jumpingPhases.length)) { - data.movingJumpPhase = jumpingPhases.length - 1; - } + if(offset > 2D) vl = max(vl, Level.SEVERE); + else if(offset > 1D) vl = max(vl, Level.WARNING); + else vl = max(vl, Level.INFO); + } - if(vl == null) { - legitimateMove(data, event); - } - else { - String actions = null; - boolean log = true; - - // If it is the first violation, store the "from" location for potential later use - if(data.movingSetBackPoint == null) { - data.movingSetBackPoint = event.getFrom().clone(); - } - - // Find out with what actions to treat the violation(s) - if(Level.INFO.equals(vl)) { - data.movingMinorViolationsInARow++; + data.movingJumpPhase++; // Enter next phase of the flight + } - actions = NoCheatConfiguration.movingActionMinor; + // do a security check on the jumping phase, such that we don't get + // OutOfArrayBoundsExceptions at long air times (falling off high places) + if(!(data.movingJumpPhase < jumpingPhases.length)) { + data.movingJumpPhase = jumpingPhases.length - 1; + } - // React only after the freebee illegal moves have all been used - if(data.movingMinorViolationsInARow % (NoCheatConfiguration.movingFreeMoves) != 0) { - vl = null; - actions = null; - } - - if(data.movingMinorViolationsInARow != NoCheatConfiguration.movingFreeMoves) { - log = false; - } + if(vl == null) { + legitimateMove(data, event); + } + else { + String actions = null; + boolean log = true; - // using up all free moves 4 times in a row counts as one normal violation - if(data.movingMinorViolationsInARow % (NoCheatConfiguration.movingFreeMoves * 4) == 0) { - vl = Level.WARNING; - log = true; - } - } - - if(Level.WARNING.equals(vl)) { - if(data.movingNormalViolationsInARow > 0) log = false; - data.movingNormalViolationsInARow++; - actions = NoCheatConfiguration.movingActionNormal; - } + // If it is the first violation, store the "from" location for potential later use + if(data.movingSetBackPoint == null) { + data.movingSetBackPoint = event.getFrom().clone(); + } - if(Level.SEVERE.equals(vl)) { - if(data.movingHeavyViolationsInARow > 0) log = false; - data.movingHeavyViolationsInARow++; - actions = NoCheatConfiguration.movingActionHeavy; - } + // Find out with what actions to treat the violation(s) + if(Level.INFO.equals(vl)) { + data.movingMinorViolationsInARow++; - action(event, actions, log); - } + actions = NoCheatConfiguration.movingActionMinor; + + // React only after the freebee illegal moves have all been used + if(data.movingMinorViolationsInARow % (NoCheatConfiguration.movingFreeMoves) != 0) { + vl = null; + actions = null; + } + + if(data.movingMinorViolationsInARow != NoCheatConfiguration.movingFreeMoves) { + log = false; + } + + // using up all free moves 4 times in a row counts as one normal violation + if(data.movingMinorViolationsInARow % (NoCheatConfiguration.movingFreeMoves * 4) == 0) { + vl = Level.WARNING; + log = true; + } + } + + if(Level.WARNING.equals(vl)) { + if(data.movingNormalViolationsInARow > 0) log = false; + data.movingNormalViolationsInARow++; + actions = NoCheatConfiguration.movingActionNormal; + } + + if(Level.SEVERE.equals(vl)) { + if(data.movingHeavyViolationsInARow > 0) log = false; + data.movingHeavyViolationsInARow++; + actions = NoCheatConfiguration.movingActionHeavy; + } + + action(event, actions, log); + } } - - + + /** * Perform actions that were specified by the player * @param event * @param actions */ private static void action(PlayerMoveEvent event, String actions, boolean log) { - + if(actions == null) return; // LOGGING IF NEEDED if(log && actions.contains("log")) { NoCheatPlugin.logAction(actions, "Moving violation: "+event.getPlayer().getName()+" from " + String.format("(%.5f, %.5f, %.5f) to (%.5f, %.5f, %.5f)", event.getFrom().getX(), event.getFrom().getY(), event.getFrom().getZ(), event.getTo().getX(), event.getTo().getY(), event.getTo().getZ())); } - + // RESET IF NEEDED if(actions.contains("reset")) { resetPlayer(event); @@ -341,12 +341,12 @@ public class MovingCheck { NoCheatPlugin.logAction(NoCheatConfiguration.movingActionMinor, "Moving violation ended: "+event.getPlayer().getName()+ " total Events: "+ data.movingMinorViolationsInARow); data.movingMinorViolationsInARow = 0; } - + data.movingMinorViolationsInARow = 0; data.movingSetBackPoint = null; } - + private static Level max(Level l1, Level l2) { if(l1 == null) return l2; if(l2 == null) return l1; @@ -360,9 +360,9 @@ public class MovingCheck { * @param event */ private static void resetPlayer(PlayerMoveEvent event) { - + NoCheatData data = NoCheatPlugin.getPlayerData(event.getPlayer()); - + // Still not a perfect solution. After resetting a player his vertical momentum gets lost // Therefore we can't expect him to fall big distances in his next move, therefore we have to // set his flying phase to something he can work with. @@ -372,7 +372,7 @@ public class MovingCheck { // If we have stored a location for the player, we put him back there if(data.movingSetBackPoint != null) { - + // Lets try it that way. Maybe now people don't "disappear" any longer event.setFrom(data.movingSetBackPoint); event.setTo(data.movingSetBackPoint); @@ -386,66 +386,66 @@ public class MovingCheck { } } - - /** - * Check the four edges of the player's approximated Bounding Box for blocks or ladders, - * at his own height (values[2]) and below his feet (values[2]-1). Also, check at his "head" - * for ladders. - * - * If there is one, the player is considered as standing on it/hanging to it. - * - * Not perfect at all and will produce some false negatives. Probably will be refined - * later. - * - * @param w The world the coordinates belong to - * @param values The coordinates [lowerX, higherX, Y, lowerZ, higherZ] - * @return - */ - private static boolean playerIsOnGround(World w, int values[], Location l) { - - // Completely revamped collision detection - // What it does: - // Check the blocks below the player. If they aren't not solid (sic!) and the blocks directly above - // them aren't solid, The player is considered to be standing on the lower block - // Plus the player can hang onto a ladder that is one field above him - - // Check the four borders of the players hitbox for something he could be standing on - if(types[w.getBlockTypeIdAt(values[0], values[2]-1, values[3])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[1], values[2]-1, values[3])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[0], values[2]-1, values[4])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[1], values[2]-1, values[4])] != BlockType.NONSOLID ) - return true; - // Check if he is hanging onto a ladder - else if(types[w.getBlockTypeIdAt(l.getBlockX(), l.getBlockY(), l.getBlockZ())] == BlockType.LADDER || - types[w.getBlockTypeIdAt(l.getBlockX(), l.getBlockY()+1, l.getBlockZ())] == BlockType.LADDER) - return true; - // check if he is standing "in" an block that's potentially solid (we give him the benefit of a doubt and see that as a legit move) - // If it is not legit, the MC server already has a safeguard against that (You'll get "xy moved wrongly" on the console in that case) - else if(types[w.getBlockTypeIdAt(values[0], values[2], values[3])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[1], values[2], values[3])] != BlockType.NONSOLID|| - types[w.getBlockTypeIdAt(values[0], values[2], values[4])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[1], values[2], values[4])] != BlockType.NONSOLID) - return true; - // check if his head is "stuck" in an block that's potentially solid (we give him the benefit of a doubt and see that as a legit move) - // If it is not legit, the MC server already has a safeguard against that (You'll get "xy moved wrongly" on the console in that case) - else if(types[w.getBlockTypeIdAt(values[0], values[2]+1, values[3])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[1], values[2]+1, values[3])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[0], values[2]+1, values[4])] != BlockType.NONSOLID || - types[w.getBlockTypeIdAt(values[1], values[2]+1, values[4])] != BlockType.NONSOLID) - return true; - // Allow using a bug called "water elevator" - else if(types[w.getBlockTypeIdAt(values[0]+1, values[2]-1, values[3]+1)] == BlockType.LIQUID || - types[w.getBlockTypeIdAt(values[0]+1, values[2], values[3]+1)] == BlockType.LIQUID || - types[w.getBlockTypeIdAt(values[0]+1, values[2]+1, values[3]+1)] == BlockType.LIQUID) - return true; - else - return false; - } - - - public static int floor_double(double d) - { - int i = (int)d; - return d > (double)i ? i : i - 1; - } + + /** + * Check the four edges of the player's approximated Bounding Box for blocks or ladders, + * at his own height (values[2]) and below his feet (values[2]-1). Also, check at his "head" + * for ladders. + * + * If there is one, the player is considered as standing on it/hanging to it. + * + * Not perfect at all and will produce some false negatives. Probably will be refined + * later. + * + * @param w The world the coordinates belong to + * @param values The coordinates [lowerX, higherX, Y, lowerZ, higherZ] + * @return + */ + private static boolean playerIsOnGround(World w, int values[], Location l) { + + // Completely revamped collision detection + // What it does: + // Check the blocks below the player. If they aren't not solid (sic!) and the blocks directly above + // them aren't solid, The player is considered to be standing on the lower block + // Plus the player can hang onto a ladder that is one field above him + + // Check the four borders of the players hitbox for something he could be standing on + if(types[w.getBlockTypeIdAt(values[0], values[2]-1, values[3])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[1], values[2]-1, values[3])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[0], values[2]-1, values[4])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[1], values[2]-1, values[4])] != BlockType.NONSOLID ) + return true; + // Check if he is hanging onto a ladder + else if(types[w.getBlockTypeIdAt(l.getBlockX(), l.getBlockY(), l.getBlockZ())] == BlockType.LADDER || + types[w.getBlockTypeIdAt(l.getBlockX(), l.getBlockY()+1, l.getBlockZ())] == BlockType.LADDER) + return true; + // check if he is standing "in" an block that's potentially solid (we give him the benefit of a doubt and see that as a legit move) + // If it is not legit, the MC server already has a safeguard against that (You'll get "xy moved wrongly" on the console in that case) + else if(types[w.getBlockTypeIdAt(values[0], values[2], values[3])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[1], values[2], values[3])] != BlockType.NONSOLID|| + types[w.getBlockTypeIdAt(values[0], values[2], values[4])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[1], values[2], values[4])] != BlockType.NONSOLID) + return true; + // check if his head is "stuck" in an block that's potentially solid (we give him the benefit of a doubt and see that as a legit move) + // If it is not legit, the MC server already has a safeguard against that (You'll get "xy moved wrongly" on the console in that case) + else if(types[w.getBlockTypeIdAt(values[0], values[2]+1, values[3])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[1], values[2]+1, values[3])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[0], values[2]+1, values[4])] != BlockType.NONSOLID || + types[w.getBlockTypeIdAt(values[1], values[2]+1, values[4])] != BlockType.NONSOLID) + return true; + // Allow using a bug called "water elevator" + else if(types[w.getBlockTypeIdAt(values[0]+1, values[2]-1, values[3]+1)] == BlockType.LIQUID || + types[w.getBlockTypeIdAt(values[0]+1, values[2], values[3]+1)] == BlockType.LIQUID || + types[w.getBlockTypeIdAt(values[0]+1, values[2]+1, values[3]+1)] == BlockType.LIQUID) + return true; + else + return false; + } + + + public static int floor_double(double d) + { + int i = (int)d; + return d > (double)i ? i : i - 1; + } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/SpeedhackCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/SpeedhackCheck.java index 268bd32a..10805930 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/SpeedhackCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/SpeedhackCheck.java @@ -14,12 +14,12 @@ import cc.co.evenprime.bukkit.nocheat.NoCheatPlugin; */ public class SpeedhackCheck { - - private static final long interval = 1000; - private static final int violationsLimit = 3; - + + private static final long interval = 1000; + private static final int violationsLimit = 3; + public static void check(NoCheatData data, PlayerMoveEvent event) { - + // Should we check at all? if(NoCheatPlugin.Permissions != null && NoCheatPlugin.Permissions.has(event.getPlayer(), "nocheat.speedhack")) { return; @@ -27,10 +27,10 @@ public class SpeedhackCheck { else if(NoCheatPlugin.Permissions == null && event.getPlayer().isOp() ) { return; } - + // Get the time of the server long time = System.currentTimeMillis(); - + // Is it time for a speedhack check now? if(time > interval + data.speedhackLastCheck ) { // Yes @@ -41,11 +41,11 @@ public class SpeedhackCheck { int limitMed = (int)((NoCheatConfiguration.speedhackLimitMed * (time - data.speedhackLastCheck)) / interval); int limitHigh = (int)((NoCheatConfiguration.speedhackLimitHigh * (time - data.speedhackLastCheck)) / interval); - + if(data.speedhackEventsSinceLastCheck > limitHigh) action = NoCheatConfiguration.speedhackActionHeavy; else if(data.speedhackEventsSinceLastCheck > limitMed) action = NoCheatConfiguration.speedhackActionNormal; else if(data.speedhackEventsSinceLastCheck > limitLow) action = NoCheatConfiguration.speedhackActionMinor; - + if(action == null) { data.speedhackSetBackPoint = event.getFrom().clone(); data.speedhackViolationsInARow = 0; @@ -53,22 +53,22 @@ public class SpeedhackCheck { else { data.speedhackViolationsInARow++; } - + if(data.speedhackViolationsInARow >= violationsLimit) { action(action, event, data); } - + // Reset values for next check data.speedhackEventsSinceLastCheck = 0; data.speedhackLastCheck = time; - + } - + data.speedhackEventsSinceLastCheck++; } - + private static void action(String actions, PlayerMoveEvent event, NoCheatData data) { - + if(actions == null) return; // LOGGING IF NEEDED if(actions.contains("log")) { @@ -79,12 +79,12 @@ public class SpeedhackCheck { resetPlayer(event, data); } } - + private static void resetPlayer(PlayerMoveEvent event, NoCheatData data) { - + // If we have stored a location for the player, we put him back there if(data.speedhackSetBackPoint != null) { - + // Lets try it that way. Maybe now people don't "disappear" any longer event.setFrom(data.speedhackSetBackPoint); event.setTo(data.speedhackSetBackPoint); diff --git a/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatBlockListener.java b/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatBlockListener.java index fa3e77dc..ef72088e 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatBlockListener.java +++ b/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatBlockListener.java @@ -14,11 +14,11 @@ import cc.co.evenprime.bukkit.nocheat.checks.AirbuildCheck; */ public class NoCheatBlockListener extends BlockListener { - + public NoCheatBlockListener() { } - + @Override public void onBlockPlace(BlockPlaceEvent event) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatEntityListener.java b/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatEntityListener.java index 070ad19f..ade830f7 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatEntityListener.java +++ b/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatEntityListener.java @@ -7,11 +7,16 @@ import org.bukkit.event.entity.EntityListener; import cc.co.evenprime.bukkit.nocheat.NoCheatConfiguration; import cc.co.evenprime.bukkit.nocheat.checks.DupebydeathCheck; +/** + * + * @author Evenprime + * + */ public class NoCheatEntityListener extends EntityListener { @Override public void onEntityDeath(EntityDeathEvent event) { - + if(NoCheatConfiguration.dupebydeathCheckActive) { DupebydeathCheck.playerDeath(event); } diff --git a/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatPlayerListener.java b/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatPlayerListener.java index a6cdd9c9..4607fabe 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatPlayerListener.java +++ b/src/cc/co/evenprime/bukkit/nocheat/listeners/NoCheatPlayerListener.java @@ -1,8 +1,5 @@ package cc.co.evenprime.bukkit.nocheat.listeners; - - -import org.bukkit.entity.Entity; import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerListener; import org.bukkit.event.player.PlayerMoveEvent; @@ -21,42 +18,33 @@ import cc.co.evenprime.bukkit.nocheat.checks.SpeedhackCheck; */ public class NoCheatPlayerListener extends PlayerListener { - - - - public NoCheatPlayerListener() { } - - @Override - public void onPlayerQuit(PlayerEvent event) { - NoCheatPlugin.playerData.remove(event.getPlayer()); - } - - public void ingoreNextXEvents(Entity player, int count) { - NoCheatData data = NoCheatPlugin.playerData.get(player); - if(data != null) { - data.movingIgnoreNextXEvents = count; - } - } - - @Override - public void onPlayerMove(PlayerMoveEvent event) { - + public NoCheatPlayerListener() { } + + @Override + public void onPlayerQuit(PlayerEvent event) { + NoCheatPlugin.playerData.remove(event.getPlayer()); + } + + @Override + public void onPlayerMove(PlayerMoveEvent event) { + // Get the player-specific data NoCheatData data = NoCheatPlugin.getPlayerData(event.getPlayer()); - + if(!event.isCancelled() && NoCheatConfiguration.speedhackCheckActive) - SpeedhackCheck.check(data, event); - + SpeedhackCheck.check(data, event); + if(!event.isCancelled() && NoCheatConfiguration.movingCheckActive) MovingCheck.check(data, event); - - } - @Override - public void onPlayerTeleport(PlayerMoveEvent event) { + + } + + @Override + public void onPlayerTeleport(PlayerMoveEvent event) { if(!event.isCancelled() && NoCheatConfiguration.bedteleportCheckActive) { BedteleportCheck.check(event); } - } + } }