From 7a0fa252bd9c091fbe53690dd3d7c49a3fe6c27b Mon Sep 17 00:00:00 2001 From: NeatMonster Date: Sun, 12 Aug 2012 19:26:26 +0200 Subject: [PATCH] Removed the workaround for the "Bukkit blocks Zombe" issue, improved the NoFall and SurvivalFly checks. --- plugin.yml | 4 +- .../nocheatplus/CustomNetServerHandler.java | 2 - .../neatmonster/nocheatplus/NoCheatPlus.java | 24 ++-- .../nocheatplus/checks/moving/MovingData.java | 2 +- .../checks/moving/MovingListener.java | 19 +-- .../nocheatplus/checks/moving/NoFall.java | 115 ++++-------------- .../checks/moving/NoFallDamageEvent.java | 18 --- .../checks/moving/SurvivalFly.java | 24 +++- .../nocheatplus/players/Permissions.java | 1 - 9 files changed, 61 insertions(+), 148 deletions(-) delete mode 100644 src/fr/neatmonster/nocheatplus/checks/moving/NoFallDamageEvent.java diff --git a/plugin.yml b/plugin.yml index 3863a50d..6a597c76 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,5 +1,5 @@ name: ${project.name} -version: ${project.Version}-b${BUILD_NUMBER} +version: ${project.version}-b${BUILD_NUMBER} description: ${project.description} author: NeatMonster @@ -110,8 +110,6 @@ permissions: description: Allow the player to bypass the MorePackets check. nocheatplus.checks.moving.morepacketsvehicle: description: Allow the player to bypass the MorePacketsVehicle check. - nocheatplus.checks.moving.nobukkitcheck: - description: Allwo the player to bypass the internal Bukkit check. nocheatplus.checks.moving.nofall: description: Allow the player to bypass the NoFall check. nocheatplus.checks.moving.survivalfly: diff --git a/src/fr/neatmonster/nocheatplus/CustomNetServerHandler.java b/src/fr/neatmonster/nocheatplus/CustomNetServerHandler.java index 6fb5eef1..35509804 100644 --- a/src/fr/neatmonster/nocheatplus/CustomNetServerHandler.java +++ b/src/fr/neatmonster/nocheatplus/CustomNetServerHandler.java @@ -49,8 +49,6 @@ public class CustomNetServerHandler extends NetServerHandler { */ @Override public void a(final Packet10Flying packet) { -// if (player.getBukkitEntity().hasPermission(Permissions.MOVING_NOBUKKITCHECK)) -// checkMovement = false; MovingListener.noFall.handlePacket(player, packet); super.a(packet); } diff --git a/src/fr/neatmonster/nocheatplus/NoCheatPlus.java b/src/fr/neatmonster/nocheatplus/NoCheatPlus.java index 9dfa658f..3c6f31fb 100644 --- a/src/fr/neatmonster/nocheatplus/NoCheatPlus.java +++ b/src/fr/neatmonster/nocheatplus/NoCheatPlus.java @@ -17,7 +17,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; @@ -122,17 +121,6 @@ public class NoCheatPlus extends JavaPlugin implements Listener { final void onExecuteActions(final ExecuteActionsEvent event) { event.executeActions(); } - - /** - * Setting the net server handler at the earliest possible point. - * @param event - */ - @EventHandler( - priority = EventPriority.LOWEST) - public void onPlayerJoinLowest(final PlayerJoinEvent event) { - // Set the NetServerHandler of the player. - setCustomNetServerHandler(event.getPlayer()); - } /** * This event handler is used to send all the disabling messages to the client. @@ -224,6 +212,18 @@ public class NoCheatPlus extends JavaPlugin implements Listener { player.sendMessage(message); } + /** + * Setting the net server handler at the earliest possible point. + * + * @param event + */ + @EventHandler( + priority = EventPriority.LOWEST) + public void onPlayerJoinLowest(final PlayerJoinEvent event) { + // Set the NetServerHandler of the player. + setCustomNetServerHandler(event.getPlayer()); + } + private boolean setCustomNetServerHandler(final Player player) { final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); final NetServerHandler oldNSH = entityPlayer.netServerHandler; diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java b/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java index b29df430..6a1248ba 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java @@ -84,11 +84,11 @@ public class MovingData implements CheckData { // Data of the no fall check. public double noFallFallDistance; + public double noFallNewFallDistance; public boolean noFallOnGroundClient; public boolean noFallOnGroundServer; public boolean noFallWasOnGroundClient; public boolean noFallWasOnGroundServer; - public double noFallY; // Absolute reference might be good with packet inspections. // Data of the survival fly check. public int survivalFlyJumpPhase; diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java index 1414c816..a1162928 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java @@ -479,30 +479,21 @@ public class MovingListener implements Listener { */ // Don't care if a player isn't inside the vehicle, for movements that are very high distance or to another // world (such that it is very likely the event dataFactory was modified by another plugin before we got it). - final Location to = event.getTo(); if (event.getVehicle().getPassenger() == null || !(event.getVehicle().getPassenger() instanceof Player) - || !event.getFrom().getWorld().equals(to.getWorld()) - || event.getFrom().distanceSquared(to) > 400D) + || !event.getFrom().getWorld().equals(event.getTo().getWorld()) + || event.getFrom().distanceSquared(event.getTo()) > 400D) return; final Player player = (Player) event.getVehicle().getPassenger(); Location newTo = null; - - // Emergency fix attempt: - final MovingData data = MovingData.getData(player); - data.clearFlyData(); - player.setFallDistance(0.0f); - data.noFallY = to.getY(); - + if (morePacketsVehicle.isEnabled(player)) // If the player is handled by the more packets vehicle check, execute it. - newTo = morePacketsVehicle.check(player, event.getFrom(), to); + newTo = morePacketsVehicle.check(player, event.getFrom(), event.getTo()); else // Otherwise we need to clear his dataFactory. - data.clearMorePacketsData(); - - + MovingData.getData(player).clearMorePacketsData(); // Did one of the checks decide we need a new "to"-location? if (newTo != null) diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java b/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java index 87c5161c..ad063a3c 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java @@ -3,13 +3,12 @@ package fr.neatmonster.nocheatplus.checks.moving; import java.util.Locale; import net.minecraft.server.AxisAlignedBB; +import net.minecraft.server.DamageSource; import net.minecraft.server.EntityPlayer; import net.minecraft.server.Packet10Flying; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import fr.neatmonster.nocheatplus.actions.ParameterName; import fr.neatmonster.nocheatplus.checks.Check; @@ -51,102 +50,48 @@ public class NoFall extends Check { public void check(final Player player, final PlayerLocation from, final PlayerLocation to) { final MovingConfig cc = MovingConfig.getConfig(player); final MovingData data = MovingData.getData(player); - - if (player.isInsideVehicle()){ - // Emergency fix attempt: - data.clearFlyData(); - data.noFallFallDistance = 0D; - data.noFallY = to.getY(); - player.setFallDistance(0.0f); - return; - } - + // If the player has just started falling, is falling into a liquid, in web or is on a ladder. - if (to.isInLiquid()){ - // TODO: check if it is deep liquid - final double dist = data.noFallY - to.getY(); - if (dist > 0 ){ - // TODO: ? different model, at least distinguish water, lava, flowing. - final double fFLuid = 0.55; - data.noFallY = to.getY() + dist *fFLuid; - data.noFallFallDistance *= fFLuid; - } - } - else if (to.isInWeb() || to.isOnLadder()){ + if (to.isInLiquid() || to.isInWeb() || to.isOnLadder()) // Reset his fall distance. - data.noFallFallDistance = 0D; - data.noFallY = to.getY(); - player.setFallDistance(0.0f); - return; - } - - -// data.noFallFallDistance = data.noFallFallDistance; - - /* - * TODO: This might actually (probably) calculated before ordinary fall damage can be dealt (!) - * So NoCheatPlus takes over ALL fall damage dealing, currently :) - - * This should not lead to alerts and trigger normal fall damage, probably, - * in case it is not cheating (how to distinguish...). - */ + data.noFallFallDistance = data.noFallNewFallDistance = 0D; // If the player just touched the ground for the server, but no for the client. if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer && (data.noFallWasOnGroundClient || !data.noFallOnGroundClient)) { - // Calculate the fall damages to be dealt. - final int fallDamage = (int) data.noFallFallDistance - 2; // Blocks - 3 ? - // TODO: set accurate fall damage (Boots with feather falling or protection). - + final int fallDamage = (int) data.noFallFallDistance - 2; if (fallDamage > 0) { // Add the fall distance to the violation level. data.noFallVL += data.noFallFallDistance; // Execute the actions to find out if we need to cancel the event or not. - if (executeActions(player, data.noFallVL, cc.noFallActions)){ - // Deal the fall damages to the player. - if (player.getGameMode() != GameMode.CREATIVE){ - final NoFallDamageEvent damageEvent = new NoFallDamageEvent(player, DamageCause.FALL, fallDamage); - Bukkit.getPluginManager().callEvent(damageEvent); - if (!damageEvent.isCancelled()) player.damage(damageEvent.getDamage()); - } - // Reset fall distances: - data.noFallFallDistance = 0.0; - data.noFallY = to.getY(); - player.setFallDistance(0.0f); - } - + if (executeActions(player, data.noFallVL, cc.noFallActions)) + // Calling this method will send the event for us. + ((CraftPlayer) player).getHandle().damageEntity(DamageSource.FALL, fallDamage); } } // If the player just touched the ground for the server. else if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer) { - // Calculate the difference between the fall distance calculated by the server and by the plugin. - - // TODO: What does the divisor do, is this experience ? - final double difference = (data.noFallFallDistance - player.getFallDistance()) / data.noFallFallDistance; - - // If the difference is too big and the fall distance calculated by the plugin should hurt the player. - if (difference > 0.15D && (int) data.noFallFallDistance > 2) { + // If the difference between the fall distance recorded by Bukkit and NoCheatPlus is too big and the fall + // distance bigger than 2. + if (data.noFallFallDistance - player.getFallDistance() > 1D && (int) data.noFallFallDistance > 2) { // Add the difference to the violation level. data.noFallVL += data.noFallFallDistance - player.getFallDistance(); // Execute the actions to find out if we need to cancel the event or not. - if (executeActions(player, data.noFallVL, cc.noFallActions)){ - // Set the fall distance to its right value. + if (executeActions(player, data.noFallVL, cc.noFallActions)) + // player.sendMessage(""); + // Set the fall distance to its right value. player.setFallDistance((float) data.noFallFallDistance); - } - + } else // Reward the player by lowering his violation level. data.noFallVL *= 0.95D; - } else + } else // Reward the player by lowering his violation level. data.noFallVL *= 0.95D; - if (data.noFallOnGroundServer){ - data.noFallY = to.getY(); - data.noFallFallDistance = 0.0; - } } /* (non-Javadoc) @@ -171,33 +116,17 @@ public class NoFall extends Check { */ public void handlePacket(final EntityPlayer player, final Packet10Flying packet) { final MovingData data = MovingData.getData(player.getBukkitEntity()); - - // Attempt to fix vehicle problems: - if (player.getBukkitEntity().isInsideVehicle()){ - // rely on vehicle-move for most. - data.noFallFallDistance = 0.0; - data.noFallY = player.locY; - return; - } - - // Suggestion: use reference y position in data and calculate difference to that one! - data.noFallWasOnGroundClient = data.noFallOnGroundClient; data.noFallWasOnGroundServer = data.noFallOnGroundServer; data.noFallOnGroundClient = packet.g; final AxisAlignedBB boundingBoxGround = player.boundingBox.clone().d(packet.x - player.locX, packet.y - player.locY - 0.001D, packet.z - player.locZ); data.noFallOnGroundServer = player.world.getCubes(player, boundingBoxGround).size() > 0; - // make use of data.noFallY (absolute reference for falling height). - if (packet.hasPos){ - // TODO: not 100% sure which to use as reference... - if (data.noFallWasOnGroundServer && !data.noFallOnGroundServer){ - data.noFallFallDistance = 0D; - data.noFallY = player.locY; - } - else if (data.noFallY - packet.y > 0D) - data.noFallFallDistance = Math.max(0.0, data.noFallY - packet.y); //+= player.locY - packet.y; - else if (data.noFallOnGroundServer) data.noFallY = player.locY; + if (packet.hasPos && packet.y > 0 && data.noFallWasOnGroundServer && !data.noFallOnGroundServer) + data.noFallFallDistance = data.noFallNewFallDistance = 0D; + else if (packet.hasPos && packet.y > 0 && player.locY - packet.y > 0D) { + data.noFallFallDistance = data.noFallNewFallDistance; + data.noFallNewFallDistance += player.locY - packet.y; } } } diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/NoFallDamageEvent.java b/src/fr/neatmonster/nocheatplus/checks/moving/NoFallDamageEvent.java deleted file mode 100644 index 8ff04145..00000000 --- a/src/fr/neatmonster/nocheatplus/checks/moving/NoFallDamageEvent.java +++ /dev/null @@ -1,18 +0,0 @@ -package fr.neatmonster.nocheatplus.checks.moving; - -import org.bukkit.entity.Entity; -import org.bukkit.event.entity.EntityDamageEvent; - - -/** - * Very simple version to allow canceling. - * @author mc_dev - * - */ -public class NoFallDamageEvent extends EntityDamageEvent { - - public NoFallDamageEvent(Entity damagee, DamageCause cause, int damage) { - super(damagee, cause, damage); - } - -} diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java b/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java index 8f211705..6e8368a8 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java @@ -82,6 +82,7 @@ public class SurvivalFly extends Check { // A player is considered sprinting if the flag is set and if he has enough food level. final boolean sprinting = player.isSprinting() && player.getFoodLevel() > 5; + // If we don't have any setBack, choose the location the player comes from. if (data.setBack == null) data.setBack = from.getLocation(); @@ -91,6 +92,7 @@ public class SurvivalFly extends Check { else if (data.survivalFlyOnIce > 0) data.survivalFlyOnIce--; + // Choose the right horizontal speed limit for the current activity. double hAllowedDistance = 0D; if (player.isSneaking() && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SNEAKING)) hAllowedDistance = 0.14D * cc.survivalFlySneakingSpeed / 100D; @@ -167,15 +169,24 @@ public class SurvivalFly extends Check { if (jumpAmplifier > data.jumpAmplifier) data.jumpAmplifier = jumpAmplifier; - double vAllowedDistance = 1.35D + data.verticalFreedom; + // If the player has made a "double-jump" which hasn't been noticed by the plugin, the issue is fixed here. + if (!from.isOnGround() && to.isOnGround() && to.getY() - from.getY() > 0D && to.getY() - from.getY() <= 0.5D + && to.getY() - data.setBack.getY() > 0D && to.getY() - data.setBack.getY() <= 1.5D) { + data.setBack = to.getLocation(); + data.survivalFlyJumpPhase = 0; + } + + // Calculate the vertical speed limit based on the current jump phase. + double vAllowedDistance = (!from.isOnGround() && !to.isOnGround() ? 1.45D : 1.35D) + data.verticalFreedom; vAllowedDistance *= data.jumpAmplifier; if (data.survivalFlyJumpPhase > 6 + data.jumpAmplifier) vAllowedDistance -= (data.survivalFlyJumpPhase - 6) * 0.15D; + // If the player has touched the ground and this actions hasn't been noticed by the plugin, the issue is fixed + // here. final double vDistance = to.getY() - data.setBack.getY(); if (data.survivalFlyLastDistances[0] < data.survivalFlyLastDistances[1] - && vDistance > data.survivalFlyLastDistances[0] && data.survivalFlyJumpPhase >= 7 - && data.survivalFlyJumpPhase <= 8) + && vDistance > data.survivalFlyLastDistances[0] && vDistance > 0 && vDistance < 0.5D) data.survivalFlyJumpPhase = 0; else if (vDistance <= 0D) data.survivalFlyJumpPhase = 0; @@ -183,10 +194,15 @@ public class SurvivalFly extends Check { data.survivalFlyLastDistances[0] = vDistance; double vDistanceAboveLimit = vDistance - vAllowedDistance; + + // Fix for the issue with stairs. if (from.isOnStairs() || to.isOnStairs() && vDistanceAboveLimit < 0.15D) { data.jumpAmplifier = 0D; + data.noFallOnGroundClient = data.noFallOnGroundServer = true; vDistanceAboveLimit = 0D; - } else if (from.isOnGround() || to.isOnGround()) + } + + if (from.isOnGround() || to.isOnGround()) data.jumpAmplifier = 0D; final double result = (Math.max(hDistanceAboveLimit, 0D) + Math.max(vDistanceAboveLimit, 0D)) * 100D; diff --git a/src/fr/neatmonster/nocheatplus/players/Permissions.java b/src/fr/neatmonster/nocheatplus/players/Permissions.java index a6433a5f..f07a546b 100644 --- a/src/fr/neatmonster/nocheatplus/players/Permissions.java +++ b/src/fr/neatmonster/nocheatplus/players/Permissions.java @@ -126,7 +126,6 @@ public class Permissions { public static final String MOVING_CREATIVEFLY = MOVING + ".creativefly"; public static final String MOVING_MOREPACKETS = MOVING + ".morepackets"; public static final String MOVING_MOREPACKETSVEHICLE = MOVING + ".morepacketsvehicle"; - public static final String MOVING_NOBUKKITCHECK = MOVING + ".nobukkitcheck"; public static final String MOVING_NOFALL = MOVING + ".nofall"; public static final String MOVING_SURVIVALFLY = MOVING + ".survivalfly"; public static final String MOVING_SURVIVALFLY_BLOCKING = MOVING_SURVIVALFLY + ".blocking";