diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/MovingConfig.java b/src/fr/neatmonster/nocheatplus/checks/moving/MovingConfig.java index 0737d1f7..f90186e2 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/MovingConfig.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/MovingConfig.java @@ -79,6 +79,7 @@ public class MovingConfig extends ACheckConfig { public final ActionList morePacketsVehicleActions; public final boolean noFallCheck; + public final boolean noFallDealDamage; public final ActionList noFallActions; public final boolean passableCheck; @@ -92,6 +93,7 @@ public class MovingConfig extends ACheckConfig { public final int survivalFlySwimmingSpeed; public final int survivalFlyWalkingSpeed; public final boolean survivalFlyCobwebHack; + public final boolean survivalFlyAccounting; public final ActionList survivalFlyActions; // Special tolerance values: @@ -125,6 +127,7 @@ public class MovingConfig extends ACheckConfig { Permissions.MOVING_MOREPACKETS); noFallCheck = data.getBoolean(ConfPaths.MOVING_NOFALL_CHECK); + noFallDealDamage = data.getBoolean(ConfPaths.MOVING_NOFALL_DEALDAMAGE); noFallActions = data.getActionList(ConfPaths.MOVING_NOFALL_ACTIONS, Permissions.MOVING_NOFALL); passableCheck = data.getBoolean(ConfPaths.MOVING_PASSABLE_CHECK); @@ -139,6 +142,7 @@ public class MovingConfig extends ACheckConfig { survivalFlySwimmingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_SWIMMINGSPEED, 100); survivalFlyWalkingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_WALKINGSPEED, 100); survivalFlyCobwebHack = data.getBoolean(ConfPaths.MOVING_SURVIVALFLY_COBWEBHACK, true); + survivalFlyAccounting = data.getBoolean(ConfPaths.MOVING_SURVIVALFLY_ACCOUNTING); survivalFlyActions = data.getActionList(ConfPaths.MOVING_SURVIVALFLY_ACTIONS, Permissions.MOVING_SURVIVALFLY); yOnGround = data.getDouble(ConfPaths.MOVING_YONGROUND, 0.001, 2.0, 0.001); diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java b/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java index b224f503..bf4e2a97 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/MovingData.java @@ -9,6 +9,7 @@ import org.bukkit.entity.Player; import fr.neatmonster.nocheatplus.checks.access.ACheckData; import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory; import fr.neatmonster.nocheatplus.checks.access.ICheckData; +import fr.neatmonster.nocheatplus.utilities.ActionFrequency; import fr.neatmonster.nocheatplus.utilities.PlayerLocation; /* @@ -101,9 +102,11 @@ public class MovingData extends ACheckData { public Location morePacketsVehicleSetback; // Data of the no fall check. - public double noFallFallDistance; - public boolean noFallOnGround; - public boolean noFallWasOnGround; + public float noFallFallDistance; +// public boolean noFallOnGround; +// public boolean noFallWasOnGround; + /** Last y coordinate from when the player was on ground. */ + public double noFallMaxY; // Passable check. public double passableVL; @@ -118,9 +121,10 @@ public class MovingData extends ACheckData { // Accounting info. // TODO: optimize later. -// public final ActionFrequency hDistSum = new ActionFrequency(3, 333); -// public final ActionFrequency vDistSum = new ActionFrequency(3, 333); -// public final ActionFrequency hvDistCount = new ActionFrequency(3, 333); + public final ActionFrequency hDistSum = new ActionFrequency(3, 333); + public final ActionFrequency vDistSum = new ActionFrequency(3, 333); + public final ActionFrequency hDistCount = new ActionFrequency(3, 333); + public final ActionFrequency vDistCount = new ActionFrequency(3, 333); // Locations shared between all checks. public final PlayerLocation from = new PlayerLocation(); @@ -130,20 +134,24 @@ public class MovingData extends ACheckData { public final PlayerLocation to = new PlayerLocation(); /** - * Clear the data of the fly checks. + * Clear the data of the fly checks (not more-packets). */ public void clearFlyData() { bunnyhopDelay = 0; - noFallFallDistance = 0D; survivalFlyJumpPhase = 0; setBack = null; -// final long now = System.currentTimeMillis(); -// hDistSum.clear(now); -// vDistSum.clear(now); -// hvDistCount.clear(now); + clearAccounting(); clearNoFallData(); } + public void clearAccounting() { + final long now = System.currentTimeMillis(); + hDistSum.clear(now); + vDistSum.clear(now); + hDistCount.clear(now); + vDistCount.clear(now); + } + /** * Clear the data of the more packets checks. */ @@ -156,7 +164,8 @@ public class MovingData extends ACheckData { * Clear the data of the new fall check. */ public void clearNoFallData() { - noFallOnGround = noFallWasOnGround = true; - noFallFallDistance = 0D; +// noFallOnGround = noFallWasOnGround = true; + noFallFallDistance = 0; + noFallMaxY = 0D; } } diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java index 2b153bdf..47799f3a 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java @@ -12,6 +12,8 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerBedEnterEvent; import org.bukkit.event.player.PlayerBedLeaveEvent; import org.bukkit.event.player.PlayerChangedWorldEvent; @@ -448,6 +450,7 @@ public class MovingListener implements Listener { data.clearMorePacketsData(); // Always drop data from fly checks, as it always loses its validity after teleports. Always! + // TODO: NoFall might be necessary to be checked here ? data.teleported = null; data.clearFlyData(); } @@ -549,4 +552,27 @@ public class MovingListener implements Listener { } }.set(vehicle, newTo), 1L); } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) + public void onEntityDamage(final EntityDamageEvent event){ + if (event.getCause() != DamageCause.FALL) return; + final Entity entity = event.getEntity(); + if (!(entity instanceof Player)) return; + final Player player = (Player) entity; + if (!survivalFly.isEnabled(player)) return; + if (!noFall.isEnabled(player)) return; + final MovingConfig cc = MovingConfig.getConfig(player); + final MovingData data = MovingData.getData(player); + final float fallDistance = player.getFallDistance(); + final int damage = event.getDamage(); + if (cc.debug) System.out.println(player.getName() + " damage(FALL): " + damage + " / dist=" + player.getFallDistance() + " nf=" + data.noFallFallDistance); + // Fall-back check. + final int maxD = NoFall.getDamage(Math.max(fallDistance, Math.max(data.noFallFallDistance, (float) (data.noFallMaxY - player.getLocation().getY())))); + if (maxD > damage){ + event.setDamage(maxD); + if (cc.debug) System.out.println(player.getName() + " Adjust fall damage to: " + maxD); + } + data.clearNoFallData(); + // Entity fall-distance should be reset elsewhere. + } } diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java b/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java index b6da10f9..669013b1 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java @@ -3,11 +3,14 @@ package fr.neatmonster.nocheatplus.checks.moving; import java.util.Locale; import java.util.Map; +import net.minecraft.server.DamageSource; import net.minecraft.server.EntityPlayer; -import org.bukkit.Location; +import org.bukkit.Bukkit; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import fr.neatmonster.nocheatplus.actions.ParameterName; import fr.neatmonster.nocheatplus.checks.Check; @@ -35,6 +38,43 @@ public class NoFall extends Check { public NoFall() { super(CheckType.MOVING_NOFALL); } + + /** + * Calculate the damage in hearts from the given fall distance. + * @param fallDistance + * @return + */ + protected static final int getDamage(final float fallDistance){ + return 1 + (int) (fallDistance - 3.5); + } + + /** + * Deal damage if appropriate. To be used for if the player is on ground somehow. + * @param mcPlayer + * @param data + * @param y + */ + private static final void handleOnGround(final EntityPlayer mcPlayer, final MovingData data, final double y, final MovingConfig cc) { +// final int pD = getDamage(mcPlayer.fallDistance); +// final int nfD = getDamage(data.noFallFallDistance); +// final int yD = getDamage((float) (data.noFallMaxY - y)); +// final int maxD = Math.max(Math.max(pD, nfD), yD); + final int maxD = getDamage(Math.max(mcPlayer.fallDistance, Math.max(data.noFallFallDistance, (float) (data.noFallMaxY - y)))); + if (maxD > 0){ + // Damage to be dealt. + // TODO: more effects like sounds, maybe use custom event with violation added. + if (cc.debug) System.out.println(mcPlayer.name + " NoFall deal damage: " + maxD); + final EntityDamageEvent event = new EntityDamageEvent(mcPlayer.getBukkitEntity(), DamageCause.FALL, maxD); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()){ + mcPlayer.damageEntity(DamageSource.FALL, event.getDamage()); + } + // TODO: let this be done by the damage event (!). +// data.clearNoFallData(); // -> currently done in the damage eventhandling method. + mcPlayer.fallDistance = 0; + } + else data.clearNoFallData(); + } /** * Checks a player. @@ -49,52 +89,120 @@ public class NoFall extends Check { public void check(final Player player, final MovingData data, final MovingConfig cc) { final PlayerLocation from = data.from; final PlayerLocation to = data.to; - + + // Reset the on ground properties only if necessary. if (from.getY() > to.getY()){ - // Reset the on ground properties only if necessary. - if (from.getyOnGround() != cc.noFallyOnGround && (from.getY() - (double) Location.locToBlock(from.getY()) < cc.noFallyOnGround)) + if (from.getyOnGround() != cc.noFallyOnGround && from.getY() - from.getBlockY() < cc.noFallyOnGround) from.setyOnGround(cc.noFallyOnGround); - if (to.getyOnGround() != cc.noFallyOnGround && (to.getY() - (double) Location.locToBlock(to.getY()) < cc.noFallyOnGround)) + if (to.getyOnGround() != cc.noFallyOnGround && to.getY() - to.getBlockY() < cc.noFallyOnGround) to.setyOnGround(cc.noFallyOnGround); } - - data.noFallWasOnGround = data.noFallOnGround; - data.noFallOnGround = to.isOnGround(); - - // If the player is on the ground, is falling into a liquid, in web or is on a ladder. - if (from.isOnGround() && to.isOnGround() || to.isInLiquid() || to.isInWeb() || to.isOnLadder()) - data.noFallFallDistance = 0D; - - // If the player just touched the ground for the server. - if (!data.noFallWasOnGround && data.noFallOnGround) { - // 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() > 0.1D && data.noFallFallDistance > 3) { - // 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, data.noFallFallDistance - player.getFallDistance(), - cc.noFallActions)) - // 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 - // Reward the player by lowering his violation level. - data.noFallVL *= 0.95D; - - // The player has touched the ground somewhere, reset his fall distance. - if (!data.noFallWasOnGround && data.noFallOnGround || data.noFallWasOnGround && !data.noFallOnGround) - data.noFallFallDistance = 0D; - - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - if (to.getY() > 0 && entityPlayer.locY > to.getY()) - data.noFallFallDistance += entityPlayer.locY - to.getY(); + + // TODO: Distinguish water depth vs. fall distance! + + final boolean fromOnGround = from.isOnGround(); + final boolean fromReset = from.isInLiquid() || from.isInWeb() || from.isOnLadder(); + final boolean toOnGround = to.isOnGround(); + final boolean toReset = to.isInLiquid() || to.isInWeb() || to.isOnLadder(); + + final EntityPlayer mcPlayer = ((CraftPlayer) player).getHandle(); + + // TODO: early returns (...) + + if (fromReset){ + // Just reset. + data.clearNoFallData(); + } + else if (fromOnGround){ + // Check if to deal damage (fall back damage check). + if (cc.noFallDealDamage) handleOnGround(mcPlayer, data, from.getY(), cc); + else data.clearNoFallData(); + } + else if (toReset){ + // Just reset. + data.clearNoFallData(); + } + else if (toOnGround){ + // Check if to deal damage. + if (cc.noFallDealDamage) handleOnGround(mcPlayer, data, to.getY(), cc); + else data.clearNoFallData(); + } + else{ + // Ensure fall distance is correct ? or anyway ! + } + + // Set reference y for nofall (always). + data.noFallMaxY = Math.max(Math.max(from.getY(), to.getY()), data.noFallMaxY); + + // TODO: fall distance might be behind (!) + // TODO: should be the data.noFallMaxY be counted in ? + if (cc.debug) System.out.println(player.getName() + " NoFall: mc="+mcPlayer.fallDistance +" / nf=" + data.noFallFallDistance); + data.noFallFallDistance = Math.max(mcPlayer.fallDistance, data.noFallFallDistance); + + final double yDiff = to.getY() - from.getY(); + // Add y distance. + if (!toReset && !toOnGround && yDiff < 0){ + data.noFallFallDistance -= yDiff; + } + +// // OLD ---------------------------------------- +// +// +// data.noFallWasOnGround = data.noFallOnGround; +// data.noFallOnGround = to.isOnGround(); +// +// // If the player is on the ground, is falling into a liquid, in web or is on a ladder. +// if (from.isOnGround() && to.isOnGround() || to.isInLiquid() || to.isInWeb() || to.isOnLadder()) +// data.noFallFallDistance = 0; +// +// // If the player just touched the ground for the server. +// if (data.noFallFallDistance > 3.5){ +// +// +// +// if (!data.noFallWasOnGround && data.noFallOnGround) { +// // If the difference between the fall distance recorded by Bukkit and NoCheatPlus is too big and the fall +// // distance bigger than 2. +// +// // TODO: 3.5 ? +// if (data.noFallFallDistance - player.getFallDistance() > 0.1D) { +// // 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, data.noFallFallDistance - player.getFallDistance(), +// cc.noFallActions)) +// // Set the fall distance to its right value. +// if (cc.noFallDealDamage){ +// // TODO: round ? +// ((CraftPlayer) player).getHandle().damageEntity(DamageSource.FALL, 1 + (int) (data.noFallFallDistance - 3.5)); +// data.clearNoFallData(); +// } +// else player.setFallDistance((float) data.noFallFallDistance); +// } else +// // Reward the player by lowering his violation level. +// data.noFallVL *= 0.95D; +// } else{ +// // Reward the player by lowering his violation level. +// data.noFallVL *= 0.95D; +// if (cc.noFallDealDamage && data.noFallOnGround){ +// // TODO: round ? +// ((CraftPlayer) player).getHandle().damageEntity(DamageSource.FALL, 1 + (int) (data.noFallFallDistance - 3.5)); +// data.clearNoFallData(); +// } +// } +// } +// else data.noFallVL *= 0.95D; +// +// // The player has touched the ground somewhere, reset his fall distance. +// if (!data.noFallWasOnGround && data.noFallOnGround || data.noFallWasOnGround && !data.noFallOnGround) +// data.noFallFallDistance = 0; +// +// if (to.getY() > 0 && from.getY() > to.getY()) +// data.noFallFallDistance += from.getY() - to.getY(); } - - @Override + + @Override protected Map getParameterMap(final ViolationData violationData) { final Map parameters = super.getParameterMap(violationData); parameters.put(ParameterName.FALL_DISTANCE, String.format(Locale.US, "%.2f", MovingData.getData(violationData.player).noFallFallDistance)); diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java b/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java index c6d6aea5..15bfd05e 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java @@ -207,16 +207,18 @@ public class SurvivalFly extends Check { // If the player has touched the ground but it hasn't been noticed by the plugin, the workaround is here. final double setBackYDistance = to.getY() - data.setBack.getY(); - if (!fromOnGround - && (from.getY() < data.survivalFlyLastFromY && yDistance > 0D && yDistance < 0.5D + if (!fromOnGround && (from.getY() < data.survivalFlyLastFromY && yDistance > 0D && yDistance < 0.5D && setBackYDistance > 0D && setBackYDistance <= 1.5D || !toOnGround && to.isAboveStairs())) { -// System.out.println("*** reset setback."); // Set the new setBack and reset the jumpPhase. + + // TODO: this allows exploits ! + data.setBack = from.getLocation(); data.setBack.setY(Math.floor(data.setBack.getY())); data.survivalFlyJumpPhase = 0; // Reset the no fall data. data.clearNoFallData(); + if (cc.debug) System.out.println(player.getName() + " RESET NOFALL (WORKAROUND)"); } data.survivalFlyLastFromY = from.getY(); @@ -226,7 +228,7 @@ public class SurvivalFly extends Check { // Very simple: force players to descend or stay. vAllowedDistance = from.isOnGround() ? 0.1D : 0; data.jumpAmplifier = 0; - vDistanceAboveLimit = to.getY() - from.getY(); + vDistanceAboveLimit = yDistance; if (cc.survivalFlyCobwebHack && vDistanceAboveLimit > 0 && hDistanceAboveLimit <= 0){ if (now - data.survivalFlyCobwebTime > 3000){ data.survivalFlyCobwebTime = now; @@ -253,14 +255,43 @@ public class SurvivalFly extends Check { // System.out.println("vda = " +vDistanceAboveLimit + " / vc = " + data.verticalVelocityCounter + " / vf = " + data.verticalFreedom + " / v = " + player.getVelocity().length()); // Step can also be blocked. - if (fromOnGround && toOnGround && Math.abs(to.getY() - from.getY() - 1D) <= cc.yStep && vDistanceAboveLimit <= 0D + if (fromOnGround && toOnGround && Math.abs(yDistance - 1D) <= cc.yStep && vDistanceAboveLimit <= 0D && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_STEP)) - vDistanceAboveLimit = Math.max(vDistanceAboveLimit, Math.abs(to.getY() - from.getY())); + vDistanceAboveLimit = Math.max(vDistanceAboveLimit, Math.abs(yDistance)); } if (fromOnGround || toOnGround) data.jumpAmplifier = 0D; + final boolean resetFrom = fromOnGround || from.isInLiquid() || from.isOnLadder() || from.isInWeb(); + + if (cc.survivalFlyAccounting && !resetFrom){ + final boolean useH = data.horizontalFreedom <= 0.001D; + final boolean useV = data.verticalFreedom <= 0.001D; + if (useH){ + data.hDistSum.add(now, (float) hDistance); + data.hDistCount.add(now, 1f); + } + if (useV){ + data.vDistSum.add(now, (float) (yDistance)); + data.vDistCount.add(now, 1f); + } + if (useH && data.hDistCount.getScore(2) > 0){ + final float hsc0 = data.hDistSum.getScore(1); + final float hsc1 = data.hDistSum.getScore(2); + if (hsc0 < hsc1 || hDistance < 3.9 && hsc0 == hsc1){ + hDistanceAboveLimit = Math.max(hDistanceAboveLimit, hsc0 - hsc1); + } + } + if (useV && data.vDistCount.getScore(2) > 0){ + final float vsc0 = data.vDistSum.getScore(1); + final float vsc1 = data.vDistSum.getScore(2); + if (vsc0 < vsc1 || yDistance < 3.9 && vsc0 == vsc1){ + vDistanceAboveLimit = Math.max(vDistanceAboveLimit, vsc0 - vsc1); + } + } + } + final double result = (Math.max(hDistanceAboveLimit, 0D) + Math.max(vDistanceAboveLimit, 0D)) * 100D; data.survivalFlyJumpPhase++; @@ -268,15 +299,11 @@ public class SurvivalFly extends Check { // Slowly reduce the level with each event. data.survivalFlyVL *= 0.95D; -// data.hDistSum.add(now, (float) hDistance); -// data.vDistSum.add(now, (float) (to.getY() - from.getY())); -// data.hvDistCount.add(now, 1f); - if (cc.debug){ System.out.println(player.getName() + " vertical freedom: " + data.verticalFreedom + " ("+data.verticalVelocity+"/"+data.verticalVelocityCounter+")"); - System.out.println(player.getName() + " hDist: " + hDistance + " / " + hAllowedDistance + " , vDist: " + (to.getY() - from.getY()) + " ("+player.getVelocity().getY()+")" + " / " + vAllowedDistance + " / from passable: " + BlockProperties.isPassable(from)); + System.out.println(player.getName() + " hDist: " + hDistance + " / " + hAllowedDistance + " , vDist: " + (yDistance) + " ("+player.getVelocity().getY()+")" + " / " + vAllowedDistance); System.out.println(player.getName() + " y: " + from.getY() +"(" + player.getLocation().getY() + ") -> " + to.getY()) ; -// System.out.println(player.getName() + " h=" + data.hDistSum.getScore(1f)+"/" + data.hDistSum.getScore(1) + " , v=" + data.vDistSum.getScore(1f)+"/"+data.vDistSum.getScore(1) ); + if (cc.survivalFlyAccounting) System.out.println(player.getName() + " h=" + data.hDistSum.getScore(1f)+"/" + data.hDistSum.getScore(1) + " , v=" + data.vDistSum.getScore(1f)+"/"+data.vDistSum.getScore(1) ); } // Did the player move in unexpected ways?// Did the player move in unexpected ways? @@ -284,49 +311,55 @@ public class SurvivalFly extends Check { // System.out.println(BlockProperties.isStairs(from.getTypeIdBelow()) + " / " + BlockProperties.isStairs(to.getTypeIdBelow())); // Increment violation counter. data.survivalFlyVL += result; - + data.clearAccounting(); + data.survivalFlyJumpPhase = 0; // If the other plugins haven't decided to cancel the execution of the actions, then do it. If one of the // actions was a cancel, cancel it. - if (executeActions(player, data.survivalFlyVL, result, MovingConfig.getConfig(player).survivalFlyActions)) + if (executeActions(player, data.survivalFlyVL, result, MovingConfig.getConfig(player).survivalFlyActions)){ // Compose a new location based on coordinates of "newTo" and viewing direction of "event.getTo()" to // allow the player to look somewhere else despite getting pulled back by NoCheatPlus. return new Location(player.getWorld(), data.setBack.getX(), data.setBack.getY(), data.setBack.getZ(), to.getYaw(), to.getPitch()); + } else if (to.isInLiquid() || to.isInWeb() || toOnGround || to.isOnLadder()) { // In case it only gets logged, not stopped by NoCheatPlus, update the setback location at least a bit. data.setBack = to.getLocation(); - data.survivalFlyJumpPhase = 0; } } - + else{ + final boolean resetTo = toOnGround || to.isInLiquid() || to.isOnLadder()|| to.isInWeb(); +// if (to.isInLiquid()) { +// // If the player moved into liquid. +// data.setBack = to.getLocation(); +// data.setBack.setY(Math.ceil(data.setBack.getY())); +// data.survivalFlyJumpPhase = 0; +// data.clearAccounting(); +// } else if (resetTo && (from.getY() >= to.getY() || data.setBack.getY() <= Math.floor(to.getY()))) { +// // Set set back and jump phase, if: +// // 1. Moving onto ladder/vine. +// /* +// * 2. If the player moved down "onto" the ground or in web and ... +// * the new setback point is higher up than the old or at +// * least at the same height. +// */ +// data.setBack = to.getLocation(); +// data.survivalFlyJumpPhase = 0; +// data.clearAccounting(); +// } else + if (resetTo){ + // The player has moved onto ground. + data.setBack = to.getLocation(); + data.survivalFlyJumpPhase = 0; + data.clearAccounting(); + } + else if (resetFrom){ + // The player moved from ground. + data.setBack = from.getLocation(); + data.clearAccounting(); + } + } // Decide if we should create a new setBack point. These are the result of a lot of bug reports, experience and // trial and error. - else if (to.isInLiquid()) { - // If the player moved into liquid. - data.setBack = to.getLocation(); - data.setBack.setY(Math.ceil(data.setBack.getY())); - data.survivalFlyJumpPhase = 0; - } else if (to.isOnLadder() - || (to.isInWeb() || toOnGround) && (from.getY() >= to.getY() || data.setBack.getY() <= Math.floor(to.getY()))) { - // Set set back and jump phase, if: - // 1. Moving onto ladder/vine. - /* - * 2. If the player moved down "onto" the ground or in web and ... - * the new setback point is higher up than the old or at - * least at the same height. - */ - data.setBack = to.getLocation(); - data.survivalFlyJumpPhase = 0; - } else { - if (from.isInLiquid() || fromOnGround || from.isInWeb() || from.isOnLadder()){ - data.setBack = from.getLocation(); - if ( to.isInLiquid() || to.isInWeb() || toOnGround || to.isOnLadder()){ - // The player at least touched the ground somehow. - data.survivalFlyJumpPhase = 0; - } - } - } - return null; } diff --git a/src/fr/neatmonster/nocheatplus/config/ConfPaths.java b/src/fr/neatmonster/nocheatplus/config/ConfPaths.java index ec6cd083..71bc51d3 100644 --- a/src/fr/neatmonster/nocheatplus/config/ConfPaths.java +++ b/src/fr/neatmonster/nocheatplus/config/ConfPaths.java @@ -452,6 +452,7 @@ public abstract class ConfPaths { private static final String MOVING_NOFALL = MOVING + "nofall."; public static final String MOVING_NOFALL_CHECK = MOVING_NOFALL + "active"; + public static final String MOVING_NOFALL_DEALDAMAGE = MOVING_NOFALL + "dealdamage"; public static final String MOVING_NOFALL_ACTIONS = MOVING_NOFALL + "actions"; public static final String MOVING_PASSABLE = MOVING + "passable."; @@ -467,6 +468,7 @@ public abstract class ConfPaths { public static final String MOVING_SURVIVALFLY_SWIMMINGSPEED = MOVING_SURVIVALFLY + "swimmingspeed"; public static final String MOVING_SURVIVALFLY_WALKINGSPEED = MOVING_SURVIVALFLY + "walkingspeed"; public static final String MOVING_SURVIVALFLY_COBWEBHACK = MOVING_SURVIVALFLY + "cobwebhack"; + public static final String MOVING_SURVIVALFLY_ACCOUNTING = MOVING_SURVIVALFLY + "accounting"; public static final String MOVING_SURVIVALFLY_ACTIONS = MOVING_SURVIVALFLY + "actions"; // Special (to be sorted in or factored out). diff --git a/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java b/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java index 61086aea..fc440032 100644 --- a/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java +++ b/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java @@ -345,16 +345,18 @@ public class DefaultConfig extends ConfigFile { "cancel vl>10 log:morepackets:0:2:if cancel"); set(ConfPaths.MOVING_NOFALL_CHECK, true); + set(ConfPaths.MOVING_NOFALL_DEALDAMAGE, true); set(ConfPaths.MOVING_NOFALL_ACTIONS, "cancel vl>0 log:nofall:0:5:if cancel vl>6 log:nofall:0:5:icf cancel"); set(ConfPaths.MOVING_PASSABLE_CHECK, true); set(ConfPaths.MOVING_PASSABLE_ACTIONS, "cancel vl>5 log:passable:0:5:if cancel vl>50 log:passable:0:5:icf cancel"); set(ConfPaths.MOVING_SURVIVALFLY_CHECK, true); + set(ConfPaths.MOVING_SURVIVALFLY_ACCOUNTING, true); // The settings aren't enabled by default. Simply write them yourself in the configuration file. // set(ConfPaths.MOVING_SURVIVALFLY_BLOCKINGSPEED, 100); // set(ConfPaths.MOVING_SURVIVALFLY_SNEAKINGSPEED, 100); - // set(ConfPaths.MOVING_SURVIVALFLY_SPEEDINGSPEED, 100); + // set(ConfPaths.MOVING_SURVIVALFLY_SPEEDINGSPEED, 200); // set(ConfPaths.MOVING_SURVIVALFLY_SPRINTINGSPEED, 100); // set(ConfPaths.MOVING_SURVIVALFLY_SWIMMINGSPEED, 100); // set(ConfPaths.MOVING_SURVIVALFLY_WALKINGSPEED, 100);