From 4bb82a4a209f9266a416e4cc5a6c8047d6d70324 Mon Sep 17 00:00:00 2001 From: NeatMonster Date: Sun, 5 Aug 2012 17:06:00 +0200 Subject: [PATCH] [Development] Reach check added, it really needs to be tested! --- .../nocheatplus/checks/blockbreak/Reach.java | 3 +- .../nocheatplus/checks/blockplace/Reach.java | 2 +- .../nocheatplus/checks/fight/Angle.java | 1 - .../nocheatplus/checks/fight/Direction.java | 1 - .../nocheatplus/checks/fight/FightConfig.java | 8 ++ .../nocheatplus/checks/fight/FightData.java | 4 + .../nocheatplus/checks/fight/Knockback.java | 1 - .../nocheatplus/checks/fight/NoSwing.java | 2 - .../nocheatplus/checks/fight/Reach.java | 126 ++++++++++++++++++ .../nocheatplus/config/ConfPaths.java | 5 + .../nocheatplus/config/DefaultConfig.java | 5 + .../nocheatplus/players/Permissions.java | 1 + 12 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 src/fr/neatmonster/nocheatplus/checks/fight/Reach.java diff --git a/src/fr/neatmonster/nocheatplus/checks/blockbreak/Reach.java b/src/fr/neatmonster/nocheatplus/checks/blockbreak/Reach.java index d43e786c..86094255 100644 --- a/src/fr/neatmonster/nocheatplus/checks/blockbreak/Reach.java +++ b/src/fr/neatmonster/nocheatplus/checks/blockbreak/Reach.java @@ -41,7 +41,7 @@ public class Reach extends Check { } /** The maximum distance allowed to interact with a block. */ - public final double DISTANCE = 5D; + public final double DISTANCE = 5D; // TODO: Test with creative mode. /** * Checks a player. @@ -57,6 +57,7 @@ public class Reach extends Check { final BlockBreakData data = BlockBreakData.getData(player); boolean cancel = false; + // Distance is calculated from eye location to center of targeted block. If the player is further away from his // target than allowed, the difference will be assigned to "distance". final double distance = Math.max(CheckUtils.distance(player, location) - DISTANCE, 0D); diff --git a/src/fr/neatmonster/nocheatplus/checks/blockplace/Reach.java b/src/fr/neatmonster/nocheatplus/checks/blockplace/Reach.java index b5643b35..7491e8b8 100644 --- a/src/fr/neatmonster/nocheatplus/checks/blockplace/Reach.java +++ b/src/fr/neatmonster/nocheatplus/checks/blockplace/Reach.java @@ -41,7 +41,7 @@ public class Reach extends Check { } /** The maximum distance allowed to interact with a block. */ - public final double DISTANCE = 5D; + public final double DISTANCE = 5D; // TODO: Test with creative mode. /** * Checks a player. diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/Angle.java b/src/fr/neatmonster/nocheatplus/checks/fight/Angle.java index 0e46668f..d27c944b 100644 --- a/src/fr/neatmonster/nocheatplus/checks/fight/Angle.java +++ b/src/fr/neatmonster/nocheatplus/checks/fight/Angle.java @@ -119,7 +119,6 @@ public class Angle extends Check { // Is the violation is superior to the threshold defined in the configuration? if (violation > cc.angleThreshold) { - // Has the server lagged? if (!LagMeasureTask.skipCheck()) // If it hasn't, increment the violation level. diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/Direction.java b/src/fr/neatmonster/nocheatplus/checks/fight/Direction.java index 5b39ab34..91bd2043 100644 --- a/src/fr/neatmonster/nocheatplus/checks/fight/Direction.java +++ b/src/fr/neatmonster/nocheatplus/checks/fight/Direction.java @@ -65,7 +65,6 @@ public class Direction extends Check { final Location maximum = new Location(player.getWorld(), damaged.boundingBox.d, damaged.boundingBox.e, damaged.boundingBox.f); if (!CheckUtils.intersects(player, minimum, maximum, OFFSET)) { - // Player failed the check. Let's try to guess how far he was from looking directly to the entity... final Vector direction = player.getEyeLocation().getDirection(); final Vector blockEyes = minimum.add(maximum).multiply(0.5D).subtract(player.getEyeLocation()).toVector(); diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/FightConfig.java b/src/fr/neatmonster/nocheatplus/checks/fight/FightConfig.java index 90f46126..9b5a8fe9 100644 --- a/src/fr/neatmonster/nocheatplus/checks/fight/FightConfig.java +++ b/src/fr/neatmonster/nocheatplus/checks/fight/FightConfig.java @@ -77,6 +77,10 @@ public class FightConfig { public final boolean noSwingCheck; public final ActionList noSwingActions; + public final boolean reachCheck; + public final long reachPenalty; + public final ActionList reachActions; + /** * Instantiates a new fight configuration. * @@ -109,5 +113,9 @@ public class FightConfig { noSwingCheck = data.getBoolean(ConfPaths.FIGHT_NOSWING_CHECK); noSwingActions = data.getActionList(ConfPaths.FIGHT_NOSWING_ACTIONS, Permissions.FIGHT_NOSWING); + + reachCheck = data.getBoolean(ConfPaths.FIGHT_REACH_CHECK); + reachPenalty = data.getLong(ConfPaths.FIGHT_REACH_PENALTY); + reachActions = data.getActionList(ConfPaths.FIGHT_REACH_ACTIONS, Permissions.FIGHT_REACH); } } diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/FightData.java b/src/fr/neatmonster/nocheatplus/checks/fight/FightData.java index 535b9fbe..dde10187 100644 --- a/src/fr/neatmonster/nocheatplus/checks/fight/FightData.java +++ b/src/fr/neatmonster/nocheatplus/checks/fight/FightData.java @@ -46,6 +46,7 @@ public class FightData { public double instantHealVL; public double knockbackVL; public double noSwingVL; + public double reachVL; // Data of the angle check. public TreeMap angleHits = new TreeMap(); @@ -68,4 +69,7 @@ public class FightData { // Data of the no swing check. public boolean noSwingArmSwung; + // Data of the reach check. + public long reachLastViolationTime; + } diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/Knockback.java b/src/fr/neatmonster/nocheatplus/checks/fight/Knockback.java index 6402e8ed..b5d3c95d 100644 --- a/src/fr/neatmonster/nocheatplus/checks/fight/Knockback.java +++ b/src/fr/neatmonster/nocheatplus/checks/fight/Knockback.java @@ -55,7 +55,6 @@ public class Knockback extends Check { // How long ago has the player started sprinting? if (data.knockbackSprintTime > 0L && System.currentTimeMillis() - data.knockbackSprintTime < cc.knockbackInterval) { - // Player failed the check, but this is influenced by lag, so don't do it if there was lag. if (!LagMeasureTask.skipCheck()) // Increment the violation level diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/NoSwing.java b/src/fr/neatmonster/nocheatplus/checks/fight/NoSwing.java index 0a27ddbf..80ef2897 100644 --- a/src/fr/neatmonster/nocheatplus/checks/fight/NoSwing.java +++ b/src/fr/neatmonster/nocheatplus/checks/fight/NoSwing.java @@ -54,12 +54,10 @@ public class NoSwing extends Check { // Did he swing his arm before? if (data.noSwingArmSwung) { - // Yes, reward him with reduction of his violation level. data.noSwingArmSwung = false; data.noSwingVL *= 0.9D; } else { - // No, increase his violation level. data.noSwingVL += 1D; diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/Reach.java b/src/fr/neatmonster/nocheatplus/checks/fight/Reach.java new file mode 100644 index 00000000..d162a1f3 --- /dev/null +++ b/src/fr/neatmonster/nocheatplus/checks/fight/Reach.java @@ -0,0 +1,126 @@ +package fr.neatmonster.nocheatplus.checks.fight; + +import net.minecraft.server.Entity; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import fr.neatmonster.nocheatplus.actions.ParameterName; +import fr.neatmonster.nocheatplus.checks.Check; +import fr.neatmonster.nocheatplus.checks.CheckEvent; +import fr.neatmonster.nocheatplus.players.Permissions; +import fr.neatmonster.nocheatplus.utilities.CheckUtils; +import fr.neatmonster.nocheatplus.utilities.LagMeasureTask; + +/* + * MM"""""""`MM dP + * MM mmmm, M 88 + * M' .M .d8888b. .d8888b. .d8888b. 88d888b. + * MM MMMb. "M 88ooood8 88' `88 88' `"" 88' `88 + * MM MMMMM M 88. ... 88. .88 88. ... 88 88 + * MM MMMMM M `88888P' `88888P8 `88888P' dP dP + * MMMMMMMMMMMM + */ +/** + * The Reach check will find out if a player interacts with something that's too far away. + */ +public class Reach extends Check { + + /** + * The event triggered by this check. + */ + public class ReachEvent extends CheckEvent { + + /** + * Instantiates a new reach event. + * + * @param player + * the player + */ + public ReachEvent(final Player player) { + super(player); + } + } + + /** The maximum distance allowed to interact with an entity. */ + public final double DISTANCE = 4D; // TODO: Needs testing. + + /** + * Checks a player. + * + * @param player + * the player + * @param damaged + * the damaged + * @return true, if successful + */ + public boolean check(final Player player, final Entity damaged) { + final FightConfig cc = FightConfig.getConfig(player); + final FightData data = FightData.getData(player); + + boolean cancel = false; + + final Location minimum = new Location(player.getWorld(), damaged.boundingBox.a, damaged.boundingBox.b, + damaged.boundingBox.c); + final Location maximum = new Location(player.getWorld(), damaged.boundingBox.d, damaged.boundingBox.e, + damaged.boundingBox.f); + final Location location = minimum.add(maximum).multiply(0.5D); + + // 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 distance = Math.max(CheckUtils.distance(player, location) - DISTANCE, 0D); + + if (distance > 0) { + // He failed, increment violation level. This is influenced by lag, so don't do it if there was lag. + if (!LagMeasureTask.skipCheck()) + data.reachVL += distance; + + // Dispatch a reach event (API). + final ReachEvent e = new ReachEvent(player); + Bukkit.getPluginManager().callEvent(e); + + // Execute whatever actions are associated with this check and the violation level and find out if we should + // cancel the event. + cancel = !e.isCancelled() && executeActions(player, cc.reachActions, data.reachVL); + + if (cancel) + // If we should cancel, remember the current time too. + data.reachLastViolationTime = System.currentTimeMillis(); + } else + // Player passed the check, reward him. + data.reachVL *= 0.8D; + + // If the player is still in penalty time, cancel the event anyway. + if (data.reachLastViolationTime + cc.reachPenalty > System.currentTimeMillis()) { + // A safeguard to avoid people getting stuck in penalty time indefinitely in case the system time of the + // server gets changed. + if (data.reachLastViolationTime > System.currentTimeMillis()) + data.reachLastViolationTime = 0; + + // He is in penalty time, therefore request cancelling of the event. + return true; + } + + return cancel; + } + + /* (non-Javadoc) + * @see fr.neatmonster.nocheatplus.checks.Check#getParameter(fr.neatmonster.nocheatplus.actions.ParameterName, org.bukkit.entity.Player) + */ + @Override + public String getParameter(final ParameterName wildcard, final Player player) { + if (wildcard == ParameterName.VIOLATIONS) + return String.valueOf(Math.round(FightData.getData(player).reachVL)); + else + return super.getParameter(wildcard, player); + } + + /* (non-Javadoc) + * @see fr.neatmonster.nocheatplus.checks.Check#isEnabled(org.bukkit.entity.Player) + */ + @Override + protected boolean isEnabled(final Player player) { + return !player.hasPermission(Permissions.FIGHT_REACH) && FightConfig.getConfig(player).reachCheck; + } +} diff --git a/src/fr/neatmonster/nocheatplus/config/ConfPaths.java b/src/fr/neatmonster/nocheatplus/config/ConfPaths.java index b5d435b0..43e22861 100644 --- a/src/fr/neatmonster/nocheatplus/config/ConfPaths.java +++ b/src/fr/neatmonster/nocheatplus/config/ConfPaths.java @@ -230,6 +230,11 @@ public abstract class ConfPaths { public static final String FIGHT_NOSWING_CHECK = FIGHT_NOSWING + "active"; public static final String FIGHT_NOSWING_ACTIONS = FIGHT_NOSWING + "actions"; + private static final String FIGHT_REACH = FIGHT + "reach."; + public static final String FIGHT_REACH_CHECK = FIGHT_REACH + "active"; + public static final String FIGHT_REACH_PENALTY = FIGHT_REACH + "penalty"; + public static final String FIGHT_REACH_ACTIONS = FIGHT_REACH + "actions"; + /* * e e ,e, * d8b d8b e88 88e Y8b Y888P " 888 8e e88 888 diff --git a/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java b/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java index f0a64b70..c9a50a60 100644 --- a/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java +++ b/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java @@ -204,6 +204,10 @@ public class DefaultConfig extends ConfigFile { set(ConfPaths.FIGHT_NOSWING_CHECK, true); set(ConfPaths.FIGHT_NOSWING_ACTIONS, "log:noswing:0:5:cif cancel"); + set(ConfPaths.FIGHT_REACH_CHECK, true); + set(ConfPaths.FIGHT_REACH_PENALTY, 500); + set(ConfPaths.FIGHT_REACH_ACTIONS, "cancel vl>10 log:freach:2:5:if cancel"); + /* * e e ,e, * d8b d8b e88 88e Y8b Y888P " 888 8e e88 888 @@ -272,6 +276,7 @@ public class DefaultConfig extends ConfigFile { set(ConfPaths.STRINGS + ".flyshort", start + "tried to move unexpectedly" + end); set(ConfPaths.STRINGS + ".flylong", start + "tried to move from [locationfrom] to [locationto] over a distance of [distance] block(s)" + end); + set(ConfPaths.STRINGS + ".freach", start + "tried to attack entity out of reach" + end); set(ConfPaths.STRINGS + ".godmode", start + "avoided taking damage or lagging" + end); set(ConfPaths.STRINGS + ".instantheal", start + "tried to regenerate health faster than normal" + end); set(ConfPaths.STRINGS + ".kick", "kick [player]"); diff --git a/src/fr/neatmonster/nocheatplus/players/Permissions.java b/src/fr/neatmonster/nocheatplus/players/Permissions.java index 3c8f42b0..510c93b0 100644 --- a/src/fr/neatmonster/nocheatplus/players/Permissions.java +++ b/src/fr/neatmonster/nocheatplus/players/Permissions.java @@ -120,6 +120,7 @@ public class Permissions { public static final String FIGHT_INSTANTHEAL = FIGHT + ".instantheal"; public static final String FIGHT_KNOCKBACK = FIGHT + ".knockback"; public static final String FIGHT_NOSWING = FIGHT + ".noswing"; + public static final String FIGHT_REACH = FIGHT + ".reach"; /* * e e ,e,