From 32d09868d9e37c0482477033e888668331f265e8 Mon Sep 17 00:00:00 2001 From: Evenprime Date: Thu, 1 Mar 2012 19:27:33 +0100 Subject: [PATCH] Even more documentation --- .../checks/blockplace/DirectionCheck.java | 2 +- .../nocheat/checks/fight/DirectionCheck.java | 32 ++++++--- .../nocheat/checks/fight/FightCheck.java | 21 +++++- .../checks/fight/FightCheckListener.java | 72 +++++++++++++++---- .../nocheat/checks/fight/FightConfig.java | 14 ++-- .../nocheat/checks/fight/FightData.java | 14 ++++ .../nocheat/checks/fight/GodmodeCheck.java | 28 ++++++-- .../nocheat/checks/fight/NoswingCheck.java | 12 +++- .../nocheat/checks/fight/ReachCheck.java | 34 +++++---- .../nocheat/checks/fight/SpeedCheck.java | 16 ++++- 10 files changed, 196 insertions(+), 49 deletions(-) diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/DirectionCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/DirectionCheck.java index 68059b9a..de969c06 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/DirectionCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/blockplace/DirectionCheck.java @@ -82,7 +82,7 @@ public class DirectionCheck extends BlockPlaceCheck { // If the player is still in penalty time, cancel the event anyway if(data.directionLastViolationTime + cc.directionPenaltyTime > time) { - // A saveguard to avoid people getting stuck in penalty time + // A safeguard to avoid people getting stuck in penalty time // indefinitely in case the system time of the server gets changed if(data.directionLastViolationTime > time) { data.directionLastViolationTime = 0; diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java index da30a333..d896cf86 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java @@ -11,6 +11,11 @@ import cc.co.evenprime.bukkit.nocheat.checks.CheckUtil; import cc.co.evenprime.bukkit.nocheat.config.Permissions; import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id; +/** + * The DirectionCheck will find out if a player tried to interact with something + * that's not in his field of view. + * + */ public class DirectionCheck extends FightCheck { public DirectionCheck(NoCheat plugin) { @@ -23,7 +28,7 @@ public class DirectionCheck extends FightCheck { final long time = System.currentTimeMillis(); - // Get the width of the damagee + // Get the damagee (entity that got hit) Entity entity = data.damagee; // Safeguard, if entity is complex, this check will fail @@ -32,40 +37,51 @@ public class DirectionCheck extends FightCheck { return false; } + // Find out how wide the entity is final float width = entity.length > entity.width ? entity.length : entity.width; - // entity.height is broken and will always be 0, therefore calculate height instead + // entity.height is broken and will always be 0, therefore + // calculate height instead based on boundingBox final double height = entity.boundingBox.e - entity.boundingBox.b; + // How far "off" is the player with his aim. We calculate from the + // players eye location and view direction to the center of the target + // entity. If the line of sight is more too far off, "off" will be + // bigger than 0 final double off = CheckUtil.directionCheck(player, entity.locX, entity.locY + (height / 2D), entity.locZ, width, height, cc.directionPrecision); if(off < 0.1D) { // Player did probably nothing wrong - // reduce violation counter + // reduce violation counter to reward him data.directionVL *= 0.80D; } else { // Player failed the check - // Increment violation counter + // Increment violation counter and statistics, but only if there + // wasn't serious lag if(!plugin.skipCheck()) { double sqrt = Math.sqrt(off); data.directionVL += sqrt; incrementStatistics(player, Id.FI_DIRECTION, sqrt); } + // Execute whatever actions are associated with this check and the + // violation level and find out if we should cancel the event cancel = executeActions(player, cc.directionActions, data.directionVL); if(cancel) { - // Needed to calculate penalty times + // if we should cancel, remember the current time too data.directionLastViolationTime = time; } } // If the player is still in penalty time, cancel the event anyway if(data.directionLastViolationTime + cc.directionPenaltyTime > time) { + // A safeguard to avoid people getting stuck in penalty time + // indefinitely in case the system time of the server gets changed if(data.directionLastViolationTime > time) { - System.out.println("Nocheat noted that your time ran backwards for " + (data.directionLastViolationTime - time) + " ms"); - // Security check for server time changed situations data.directionLastViolationTime = 0; } + + // He is in penalty time, therefore request cancelling of the event return true; } @@ -81,7 +97,7 @@ public class DirectionCheck extends FightCheck { public String getParameter(ParameterName wildcard, NoCheatPlayer player) { if(wildcard == ParameterName.VIOLATIONS) - return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).directionVL); + return String.format(Locale.US, "%d", (int) getData(player).directionVL); else return super.getParameter(wildcard, player); } 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 5ce1b15e..84f4f207 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java @@ -24,7 +24,15 @@ public abstract class FightCheck extends Check { public abstract boolean isEnabled(FightConfig cc); - public static FightData getData(DataStore base) { + /** + * Get the "FightData" object that belongs to the player. Will ensure + * that such a object exists and if not, create one + * + * @param player + * @return + */ + public static FightData getData(NoCheatPlayer player) { + DataStore base = player.getDataStore(); FightData data = base.get(id); if(data == null) { data = new FightData(); @@ -33,6 +41,17 @@ public abstract class FightCheck extends Check { return data; } + /** + * Get the FightConfig object that belongs to the world that the player + * currently resides in. + * + * @param player + * @return + */ + public static FightConfig getConfig(NoCheatPlayer player) { + return getConfig(player.getConfigurationStore()); + } + public static FightConfig getConfig(ConfigurationCacheStore cache) { FightConfig config = cache.get(id); if(config == null) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheckListener.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheckListener.java index d1e4285b..0ace56b4 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheckListener.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheckListener.java @@ -19,8 +19,12 @@ import cc.co.evenprime.bukkit.nocheat.EventManager; import cc.co.evenprime.bukkit.nocheat.NoCheat; import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer; import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore; -import cc.co.evenprime.bukkit.nocheat.config.Permissions; +/** + * Central location to listen to events that are + * relevant for the fight checks + * + */ public class FightCheckListener implements Listener, EventManager { private final List checks; @@ -30,7 +34,9 @@ public class FightCheckListener implements Listener, EventManager { public FightCheckListener(NoCheat plugin) { - this.checks = new ArrayList(3); + this.checks = new ArrayList(4); + + // Keep these in a list, because they can be executed in a bundle this.checks.add(new SpeedCheck(plugin)); this.checks.add(new NoswingCheck(plugin)); this.checks.add(new DirectionCheck(plugin)); @@ -41,9 +47,14 @@ public class FightCheckListener implements Listener, EventManager { this.plugin = plugin; } + /** + * We listen to EntityDamage events for obvious reasons + * @param event The EntityDamage Event + */ @EventHandler(priority = EventPriority.LOWEST) public void entityDamage(final EntityDamageEvent event) { + // Filter some unwanted events right now if(event.isCancelled() || !(event instanceof EntityDamageByEntityEvent)) return; @@ -59,44 +70,55 @@ public class FightCheckListener implements Listener, EventManager { } } + /** + * We listen to EntityDamage events (again) for obvious reasons + * @param event The EntityDamage Event + */ @EventHandler(priority = EventPriority.LOW) public void entityDamageForGodmodeCheck(final EntityDamageEvent event) { if(event.isCancelled()) return; + // Filter unwanted events right here final Entity entity = event.getEntity(); if(!(entity instanceof Player) || entity.isDead()) { return; } NoCheatPlayer player = plugin.getPlayer((Player) entity); - FightConfig cc = FightCheck.getConfig(player.getConfigurationStore()); + FightConfig cc = FightCheck.getConfig(player); if(!godmodeCheck.isEnabled(cc) || player.hasPermission(godmodeCheck.permission)) { return; } - FightData data = FightCheck.getData(player.getDataStore()); + FightData data = FightCheck.getData(player); + + // Run the godmode check on the attacked player boolean cancelled = godmodeCheck.check(plugin.getPlayer((Player) entity), data, cc); + + // It requested to "cancel" the players invulnerability, so set his + // noDamageTicks to 0 if(cancelled) { // Remove the invulnerability from the player player.getPlayer().setNoDamageTicks(0); } } + /** + * A player attacked something with DamageCause ENTITY_ATTACK. That's most + * likely what we want to really check. + * + * @param event The EntityDamageByEntityEvent + */ private void normalDamage(final EntityDamageByEntityEvent event) { final Player damager = (Player) event.getDamager(); final NoCheatPlayer player = plugin.getPlayer(damager); - final FightConfig cc = FightCheck.getConfig(player.getConfigurationStore()); - - if(!cc.damageChecks || player.hasPermission(Permissions.FIGHT)) { - return; - } - - final FightData data = FightCheck.getData(player.getDataStore()); + final FightConfig cc = FightCheck.getConfig(player); + final FightData data = FightCheck.getData(player); // For some reason we decided to skip this event anyway if(data.skipNext) { @@ -106,9 +128,10 @@ public class FightCheckListener implements Listener, EventManager { boolean cancelled = false; - // Get the attacked entity + // Get the attacked entity and remember it data.damagee = ((CraftEntity) event.getEntity()).getHandle(); + // Run through the four main checks for(FightCheck check : checks) { // If it should be executed, do it if(!cancelled && check.isEnabled(cc) && !player.hasPermission(check.permission)) { @@ -116,18 +139,27 @@ public class FightCheckListener implements Listener, EventManager { } } + // Forget the attacked entity (to allow garbage collecting etc. data.damagee = null; + // One of the checks requested the event to be cancelled, so do it if(cancelled) event.setCancelled(cancelled); } + /** + * There is an unofficial agreement that if a plugin wants an attack to + * not get checked by NoCheat, it either has to use a Damage type different + * from ENTITY_ATTACK or fire an event with damage type CUSTOM and damage + * 0 directly before the to-be-ignored event. + * @param event The EntityDamageByEntityEvent + */ private void customDamage(final EntityDamageByEntityEvent event) { final Player damager = (Player) event.getDamager(); final NoCheatPlayer player = plugin.getPlayer(damager); - final FightData data = FightCheck.getData(player.getDataStore()); + final FightData data = FightCheck.getData(player); // Skip the next damage event, because it is with high probability // something from the Heroes plugin @@ -136,8 +168,15 @@ public class FightCheckListener implements Listener, EventManager { return; } + /** + * We listen to death events to prevent a very specific method of doing + * godmode. + * + * @param event The EntityDeathEvent + */ @EventHandler(priority = EventPriority.MONITOR) protected void death(final EntityDeathEvent event) { + // Only interested in dying players if(!(event.getEntity() instanceof CraftPlayer)) { return; } @@ -145,9 +184,14 @@ public class FightCheckListener implements Listener, EventManager { godmodeCheck.death((CraftPlayer) event.getEntity()); } + /** + * We listen to PlayerAnimationEvent because it is used for arm swinging + * @param event The PlayerAnimationEvent + */ @EventHandler(priority = EventPriority.MONITOR) protected void armSwing(final PlayerAnimationEvent event) { - FightCheck.getData(plugin.getPlayer(event.getPlayer()).getDataStore()).armswung = true; + // Set a flag telling us that the arm has been swung + FightCheck.getData(plugin.getPlayer(event.getPlayer())).armswung = true; } public List getActiveChecks(ConfigurationCacheStore cc) { diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightConfig.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightConfig.java index e8132bdb..532d2755 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightConfig.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightConfig.java @@ -6,26 +6,34 @@ import cc.co.evenprime.bukkit.nocheat.config.ConfPaths; import cc.co.evenprime.bukkit.nocheat.config.NoCheatConfiguration; import cc.co.evenprime.bukkit.nocheat.config.Permissions; +/** + * Configurations specific for the "Fight" checks + * Every world gets one of these assigned to it, or if a world doesn't get + * it's own, it will use the "global" version + * + */ public class FightConfig implements ConfigItem { public final boolean directionCheck; public final double directionPrecision; public final ActionList directionActions; public final long directionPenaltyTime; + public final boolean noswingCheck; public final ActionList noswingActions; + public final boolean reachCheck; public final double reachLimit; public final long reachPenaltyTime; public final ActionList reachActions; + public final int speedAttackLimit; public final ActionList speedActions; public final boolean speedCheck; + public final boolean godmodeCheck; public final ActionList godmodeActions; - public final boolean damageChecks; - public FightConfig(NoCheatConfiguration data) { directionCheck = data.getBoolean(ConfPaths.FIGHT_DIRECTION_CHECK); @@ -44,7 +52,5 @@ public class FightConfig implements ConfigItem { godmodeCheck = data.getBoolean(ConfPaths.FIGHT_GODMODE_CHECK); godmodeActions = data.getActionList(ConfPaths.FIGHT_GODMODE_ACTIONS, Permissions.FIGHT_GODMODE); - - damageChecks = directionCheck || noswingCheck || reachCheck || speedCheck; } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightData.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightData.java index 5cf0d38d..a738c37a 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightData.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightData.java @@ -3,24 +3,38 @@ package cc.co.evenprime.bukkit.nocheat.checks.fight; import net.minecraft.server.Entity; import cc.co.evenprime.bukkit.nocheat.DataItem; +/** + * Player specific data for the fight checks + * + */ public class FightData implements DataItem { + // Keep track of the violation levels of the checks public double directionVL; public double noswingVL; public double reachVL; public int speedVL; public double godmodeVL; + // For checks that have penalty time public long directionLastViolationTime; public long reachLastViolationTime; + + // godmode check needs to know these public long godmodeLastDamageTime; public int godmodeLastAge; public int godmodeBuffer = 40; + // While handling an event, use this to keep the attacked entity public Entity damagee; + + // The player swung his arm public boolean armswung = true; + + // For some reason the next event should be ignored public boolean skipNext = false; + // Keep track of time and amount of attacks public long speedTime; public int speedAttackCount; diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/GodmodeCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/GodmodeCheck.java index 979206ff..43c37494 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/GodmodeCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/GodmodeCheck.java @@ -10,6 +10,11 @@ import cc.co.evenprime.bukkit.nocheat.actions.ParameterName; import cc.co.evenprime.bukkit.nocheat.config.Permissions; import cc.co.evenprime.bukkit.nocheat.data.Statistics; +/** + * The Godmode Check will find out if a player tried to stay invulnerable after + * being hit or after dying + * + */ public class GodmodeCheck extends FightCheck { public GodmodeCheck(NoCheat plugin) { @@ -22,6 +27,7 @@ public class GodmodeCheck extends FightCheck { boolean cancelled = false; long time = System.currentTimeMillis(); + // Check at most once a second if(data.godmodeLastDamageTime + 1000L < time) { data.godmodeLastDamageTime = time; @@ -34,14 +40,18 @@ public class GodmodeCheck extends FightCheck { int nodamageTicks = player.getPlayer().getNoDamageTicks(); if(nodamageTicks > 0 && ageDiff < 15) { - // He is invulnerable and didn't age fast enough, that costs some points + // He is invulnerable and didn't age fast enough, that costs + // some points data.godmodeBuffer -= (15 - ageDiff); // Still points left? if(data.godmodeBuffer <= 0) { - // No + // No, that means VL and statistics increased data.godmodeVL -= data.godmodeBuffer; incrementStatistics(player, Statistics.Id.FI_GODMODE, -data.godmodeBuffer); + + // Execute whatever actions are associated with this check and the + // violation level and find out if we should cancel the event cancelled = executeActions(player, cc.godmodeActions, data.godmodeVL); } } else { @@ -51,8 +61,10 @@ public class GodmodeCheck extends FightCheck { } if(data.godmodeBuffer < 0) { + // Can't have less than 0 data.godmodeBuffer = 0; } else if(data.godmodeBuffer > 30) { + // And 30 is enough for simple lag situations data.godmodeBuffer = 30; } @@ -72,27 +84,33 @@ public class GodmodeCheck extends FightCheck { public String getParameter(ParameterName wildcard, NoCheatPlayer player) { if(wildcard == ParameterName.VIOLATIONS) - return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).godmodeVL); + return String.format(Locale.US, "%d", (int) getData(player).godmodeVL); else return super.getParameter(wildcard, player); } /** * If a player apparently died, make sure he really dies after some time - * if he didn't already. + * if he didn't already, by setting up a Bukkit task * - * @param player + * @param player The player */ public void death(CraftPlayer player) { + // First check if the player is really dead (e.g. another plugin could + // have just fired an artificial event) if(player.getHealth() <= 0 && player.isDead()) { try { final EntityPlayer entity = player.getHandle(); + // Schedule a task to be executed in roughly 1.5 seconds Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { public void run() { try { + // Check again if the player should be dead, and + // if the game didn't mark him as dead if(entity.getHealth() <= 0 && !entity.dead) { + // Artifically "kill" him entity.deathTicks = 19; entity.a(true); } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/NoswingCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/NoswingCheck.java index ebd08dd9..3139aace 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/NoswingCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/NoswingCheck.java @@ -7,6 +7,11 @@ import cc.co.evenprime.bukkit.nocheat.actions.ParameterName; import cc.co.evenprime.bukkit.nocheat.config.Permissions; import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id; +/** + * We require that the player moves his arm between attacks, this is + * what gets checked here. + * + */ public class NoswingCheck extends FightCheck { public NoswingCheck(NoCheat plugin) { @@ -19,12 +24,16 @@ public class NoswingCheck extends FightCheck { // did he swing his arm before? if(data.armswung) { + // Yes, reward him with reduction of his vl data.armswung = false; data.noswingVL *= 0.90D; } else { + // No, increase vl and statistics data.noswingVL += 1; incrementStatistics(player, Id.FI_NOSWING, 1); + // Execute whatever actions are associated with this check and the + // violation level and find out if we should cancel the event cancel = executeActions(player, cc.noswingActions, data.noswingVL); } @@ -36,10 +45,11 @@ public class NoswingCheck extends FightCheck { return cc.noswingCheck; } + @Override public String getParameter(ParameterName wildcard, NoCheatPlayer player) { if(wildcard == ParameterName.VIOLATIONS) - return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).noswingVL); + return String.format(Locale.US, "%d", (int) getData(player).noswingVL); else return super.getParameter(wildcard, player); } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/ReachCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/ReachCheck.java index 7cc653da..1d3fc612 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/ReachCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/ReachCheck.java @@ -4,7 +4,6 @@ import java.util.Locale; import net.minecraft.server.Entity; import net.minecraft.server.EntityComplex; import net.minecraft.server.EntityComplexPart; -import net.minecraft.server.EntityGiantZombie; import cc.co.evenprime.bukkit.nocheat.NoCheat; import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer; import cc.co.evenprime.bukkit.nocheat.actions.ParameterName; @@ -12,6 +11,11 @@ import cc.co.evenprime.bukkit.nocheat.checks.CheckUtil; import cc.co.evenprime.bukkit.nocheat.config.Permissions; import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id; +/** + * The reach check will find out if a player interacts with something that's + * too far away + * + */ public class ReachCheck extends FightCheck { public ReachCheck(NoCheat plugin) { @@ -29,45 +33,48 @@ public class ReachCheck extends FightCheck { // Safeguard, if entity is Giant or Ender Dragon, this check will fail // due to giant and hard to define hitboxes - if(entity instanceof EntityComplex || entity instanceof EntityComplexPart || entity instanceof EntityGiantZombie) { + if(entity instanceof EntityComplex || entity instanceof EntityComplexPart) { return false; } - // height = 2.0D as minecraft doesn't store the height of entities, - // and that should be enough. Because entityLocations are always set - // to center bottom of the hitbox, increase "y" location by 1/2 - // height to get the "center" of the hitbox + // Distance is calculated from eye location to center of targeted + // If the player is further away from his target than allowed, the + // difference will be assigned to "distance" final double off = CheckUtil.reachCheck(player, entity.locX, entity.locY + 1.0D, entity.locZ, cc.reachLimit); if(off < 0.1D) { // Player did probably nothing wrong - // reduce violation counter + // reduce violation counter to reward him data.reachVL *= 0.80D; } else { // Player failed the check - // Increment violation counter - // This is influenced by lag, so don't do it if there was server lag + // Increment violation counter and statistics + // This is influenced by lag, so don't do it if there was lag if(!plugin.skipCheck()) { double sqrt = Math.sqrt(off); data.reachVL += sqrt; incrementStatistics(player, Id.FI_REACH, sqrt); } + // Execute whatever actions are associated with this check and the + // violation level and find out if we should cancel the event cancel = executeActions(player, cc.reachActions, data.reachVL); if(cancel) { - // Needed to calculate penalty times + // if we should cancel, remember the current time too data.reachLastViolationTime = time; } } // If the player is still in penalty time, cancel the event anyway if(data.reachLastViolationTime + cc.reachPenaltyTime > time) { + // A safeguard to avoid people getting stuck in penalty time + // indefinitely in case the system time of the server gets changed if(data.reachLastViolationTime > time) { - System.out.println("Nocheat noted that your time ran backwards for " + (data.reachLastViolationTime - time) + " ms"); - // Security check for server time changed situations data.reachLastViolationTime = 0; } + + // He is in penalty time, therefore request cancelling of the event return true; } @@ -79,10 +86,11 @@ public class ReachCheck extends FightCheck { return cc.reachCheck; } + @Override public String getParameter(ParameterName wildcard, NoCheatPlayer player) { if(wildcard == ParameterName.VIOLATIONS) - return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).reachVL); + return String.format(Locale.US, "%d", (int) getData(player).reachVL); else return super.getParameter(wildcard, player); } diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/SpeedCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/SpeedCheck.java index b58c5131..4596afa1 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/SpeedCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/SpeedCheck.java @@ -7,6 +7,11 @@ import cc.co.evenprime.bukkit.nocheat.actions.ParameterName; import cc.co.evenprime.bukkit.nocheat.config.Permissions; import cc.co.evenprime.bukkit.nocheat.data.Statistics.Id; +/** + * The speed check will find out if a player interacts with something that's + * too far away + * + */ public class SpeedCheck extends FightCheck { public SpeedCheck(NoCheat plugin) { @@ -19,20 +24,26 @@ public class SpeedCheck extends FightCheck { final long time = System.currentTimeMillis(); - if(data.speedTime + 1000 <= time) { + // Check if one second has passed and reset counters and vl in that case + if(data.speedTime + 1000L <= time) { data.speedTime = time; data.speedAttackCount = 0; data.speedVL = 0; } + // count the attack data.speedAttackCount++; + // too many attacks if(data.speedAttackCount > cc.speedAttackLimit) { + // if there was lag, don't count it towards statistics and vl if(!plugin.skipCheck()) { data.speedVL += 1; incrementStatistics(player, Id.FI_SPEED, 1); } + // Execute whatever actions are associated with this check and the + // violation level and find out if we should cancel the event cancel = executeActions(player, cc.speedActions, data.speedVL); } @@ -44,10 +55,11 @@ public class SpeedCheck extends FightCheck { return cc.speedCheck; } + @Override public String getParameter(ParameterName wildcard, NoCheatPlayer player) { if(wildcard == ParameterName.VIOLATIONS) - return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).speedVL); + return String.format(Locale.US, "%d", (int) getData(player).speedVL); else if(wildcard == ParameterName.LIMIT) return String.format(Locale.US, "%d", (int) getConfig(player.getConfigurationStore()).speedAttackLimit); else