Improved NoFall and SurvivalFly checks, again I know...

This commit is contained in:
NeatMonster 2012-08-15 14:18:38 +02:00
parent 6bcd26b6dc
commit 0f0e22a993
5 changed files with 72 additions and 73 deletions

View File

@ -92,7 +92,7 @@ public class MovingData implements CheckData {
// Data of the survival fly check.
public int survivalFlyJumpPhase;
public double[] survivalFlyLastDistances = new double[] {0D, 0D};
public double survivalFlyLastFromY;
public int survivalFlyOnIce;
public boolean survivalFlyWasInBed;
@ -120,4 +120,8 @@ public class MovingData implements CheckData {
morePacketsSetback = null;
morePacketsVehicleSetback = null;
}
public void resetNoFallDistances() {
noFallFallDistance = noFallNewFallDistance = 0D;
}
}

View File

@ -51,10 +51,9 @@ public class NoFall extends Check {
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingData data = MovingData.getData(player);
// If the player has just started falling, is falling into a liquid, in web or is on a ladder.
if (to.isInLiquid() || to.isInWeb() || to.isOnLadder())
// Reset his fall distance.
data.noFallFallDistance = data.noFallNewFallDistance = 0D;
// 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.resetNoFallDistances();
// If the player just touched the ground for the server, but no for the client.
if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer
@ -76,22 +75,26 @@ public class NoFall extends Check {
else if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer) {
// 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) {
if (data.noFallFallDistance - player.getFallDistance() > Math.pow(1D, -3D)
&& (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))
// 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
// 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.noFallWasOnGroundServer && data.noFallOnGroundServer || data.noFallWasOnGroundServer
&& !data.noFallOnGroundServer)
data.resetNoFallDistances();
}
/* (non-Javadoc)
@ -122,9 +125,7 @@ public class NoFall extends Check {
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;
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) {
if (packet.hasPos && packet.y > 0 && player.locY - packet.y > 0D) {
data.noFallFallDistance = data.noFallNewFallDistance;
data.noFallNewFallDistance += player.locY - packet.y;
}

View File

@ -116,23 +116,23 @@ public class SurvivalFly extends Check {
// Calculate some distances.
final double xDistance = to.getX() - from.getX();
final double yDistance = to.getY() - from.getY();
final double zDistance = to.getZ() - from.getZ();
final double hDistance = Math.sqrt(xDistance * xDistance + zDistance * zDistance);
double hDistanceAboveLimit = hDistance - hAllowedDistance - data.horizontalFreedom;
// Prevent players from walking on a liquid.
if (hDistanceAboveLimit <= 0D && hDistance > 0.1D && from.getY() == to.getY()
if (hDistanceAboveLimit <= 0D && hDistance > 0.1D && yDistance == 0D
&& MovingListener.isLiquid(to.getLocation().getBlock().getType()) && !to.isOnGround()
&& to.getY() % 1D < 0.8D)
hDistanceAboveLimit = hDistance;
// Prevent players from sprinting if they're moving backwards.
if (hDistanceAboveLimit <= 0D && sprinting && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SPRINTING)) {
final double dX = to.getX() - from.getX();
final double dZ = to.getZ() - from.getZ();
final float yaw = from.getYaw();
if (dX < 0D && dZ > 0D && yaw > 180F && yaw < 270F || dX < 0D && dZ < 0D && yaw > 270F && yaw < 360F
|| dX > 0D && dZ < 0D && yaw > 0F && yaw < 90F || dX > 0D && dZ > 0D && yaw > 90F && yaw < 180F)
if (xDistance < 0D && zDistance > 0D && yaw > 180F && yaw < 270F || xDistance < 0D && zDistance < 0D
&& yaw > 270F && yaw < 360F || xDistance > 0D && zDistance < 0D && yaw > 0F && yaw < 90F
|| xDistance > 0D && zDistance > 0D && yaw > 90F && yaw < 180F)
hDistanceAboveLimit = hDistance;
}
@ -169,12 +169,19 @@ public class SurvivalFly extends Check {
if (jumpAmplifier > data.jumpAmplifier)
data.jumpAmplifier = jumpAmplifier;
// 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();
// 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 (!from.isOnGround()
&& (from.getY() < data.survivalFlyLastFromY && yDistance > 0D && yDistance < 0.5D
&& setBackYDistance > 0D && setBackYDistance <= 1.5D || !to.isOnGround() && to.isAboveStairs())) {
// Set the new setBack and reset the jumpPhase.
data.setBack = from.getLocation();
data.setBack.setY(Math.floor(data.setBack.getY()));
data.survivalFlyJumpPhase = 0;
// Reset the no fall data.
data.resetNoFallDistances();
}
data.survivalFlyLastFromY = from.getY();
// Calculate the vertical speed limit based on the current jump phase.
double vAllowedDistance = (!from.isOnGround() && !to.isOnGround() ? 1.45D : 1.35D) + data.verticalFreedom;
@ -182,25 +189,7 @@ public class SurvivalFly extends Check {
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] && vDistance > 0 && vDistance < 0.5D)
data.survivalFlyJumpPhase = 0;
else if (vDistance <= 0D)
data.survivalFlyJumpPhase = 0;
data.survivalFlyLastDistances[1] = data.survivalFlyLastDistances[0];
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;
}
final double vDistanceAboveLimit = to.getY() - data.setBack.getY() - vAllowedDistance;
if (from.isOnGround() || to.isOnGround())
data.jumpAmplifier = 0D;

View File

@ -22,7 +22,9 @@ public class DefaultConfig extends ConfigFile {
public DefaultConfig() {
super();
options().header("Main configuration file for NoCheatPlus. Read \"Instructions.txt\".");
options().header(
"Main configuration file for NoCheatPlus. "
+ "For more information, visit http://dev.bukkit.org/server-mods/nocheatplus/.");
/*
* 888 ,e,

View File

@ -1,12 +1,14 @@
package fr.neatmonster.nocheatplus.utilities;
import java.util.Arrays;
import net.minecraft.server.AxisAlignedBB;
import net.minecraft.server.Block;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.Material;
import net.minecraft.server.WorldServer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
@ -75,47 +77,51 @@ public class PlayerLocation {
}
}
private static final Material[] STAIRS = new Material[] {Material.WOOD_STAIRS, Material.COBBLESTONE_STAIRS,
Material.BRICK_STAIRS, Material.SMOOTH_STAIRS, Material.NETHER_BRICK_STAIRS, Material.SANDSTONE_STAIRS,
Material.SPRUCE_WOOD_STAIRS, Material.BIRCH_WOOD_STAIRS, Material.JUNGLE_WOOD_STAIRS};
/** The original location. */
private final Location location;
private final Location location;
/** Is the player above stairs? */
private final CustomBoolean aboveStairs = new CustomBoolean();
/** Is the player in lava? */
private final CustomBoolean inLava = new CustomBoolean();
private final CustomBoolean inLava = new CustomBoolean();
/** Is the player in water? */
private final CustomBoolean inWater = new CustomBoolean();
private final CustomBoolean inWater = new CustomBoolean();
/** Is the player is web? */
private final CustomBoolean inWeb = new CustomBoolean();
private final CustomBoolean inWeb = new CustomBoolean();
/** Is the player on the ground? */
private final CustomBoolean onGround = new CustomBoolean();
private final CustomBoolean onGround = new CustomBoolean();
/** Is the player on ice? */
private final CustomBoolean onIce = new CustomBoolean();
private final CustomBoolean onIce = new CustomBoolean();
/** Is the player on ladder? */
private final CustomBoolean onLadder = new CustomBoolean();
private final CustomBoolean onLadder = new CustomBoolean();
/** Is the player on ladder (ignoring unclimbable vines)? **/
private final CustomBoolean onLadderBis = new CustomBoolean();
private final CustomBoolean onLadderBis = new CustomBoolean();
/** Is the player on soul sand? */
private final CustomBoolean onSoulSand = new CustomBoolean();
/** Is the player on stairs? */
private final CustomBoolean onStairs = new CustomBoolean();
private final CustomBoolean onSoulSand = new CustomBoolean();
/** The bounding box of the player. */
private final AxisAlignedBB boundingBox;
private final AxisAlignedBB boundingBox;
/** The entity player. */
private final EntityPlayer entity;
private final EntityPlayer entity;
/** The x, y and z coordinates. */
private final int x, y, z;
private final int x, y, z;
/** The world. */
private final WorldServer world;
private final WorldServer world;
/**
* Instantiates a new player location.
@ -191,6 +197,17 @@ public class PlayerLocation {
return location.getZ();
}
/**
* Checks if the player is above stairs.
*
* @return true, if the player above on stairs
*/
public boolean isAboveStairs() {
if (!aboveStairs.isSet())
aboveStairs.set(Arrays.asList(STAIRS).contains(Material.getMaterial(world.getTypeId(x, y - 1, z))));
return aboveStairs.get();
}
/**
* Checks if the player is in lava.
*
@ -200,7 +217,7 @@ public class PlayerLocation {
if (!inLava.isSet()) {
AxisAlignedBB boundingBoxLava = boundingBox.clone();
boundingBoxLava = boundingBoxLava.grow(-0.10000000149011612D, -0.40000000596046448D, -0.10000000149011612D);
inLava.set(world.a(boundingBoxLava, Material.LAVA));
inLava.set(world.a(boundingBoxLava, net.minecraft.server.Material.LAVA));
}
return inLava.get();
}
@ -224,7 +241,7 @@ public class PlayerLocation {
AxisAlignedBB boundingBoxWater = boundingBox.clone();
boundingBoxWater = boundingBoxWater.grow(0.0D, -0.40000000596046448D, 0.0D);
boundingBoxWater = boundingBoxWater.shrink(0.001D, 0.001D, 0.001D);
inWater.set(world.a(boundingBoxWater, Material.WATER, entity));
inWater.set(world.a(boundingBoxWater, net.minecraft.server.Material.WATER, entity));
}
return inWater.get();
}
@ -351,18 +368,4 @@ public class PlayerLocation {
}
return onSoulSand.get();
}
/**
* Checks if the player is on stairs.
*
* @return true, if the player is on stairs
*/
public boolean isOnStairs() {
if (!onStairs.isSet()) {
final int id = world.getTypeId(x, y - 1, z);
onStairs.set(id == 53 || id == 67 || id == 108 || id == 109 || id == 114 || id == 128 || id == 134
|| id == 135 || id == 136);
}
return onStairs.get();
}
}