NoFall, SurvivalFly and Reach now throw less false positive. A new

permission (nocheatplus.checks.moving.nobukkitcheck) has been added to
disable the Bukkit internal moving events checking.
This commit is contained in:
NeatMonster 2012-08-12 04:01:43 +02:00
parent 65fa26d66d
commit f1f95d0a21
13 changed files with 142 additions and 287 deletions

View File

@ -1,5 +1,5 @@
name: NoCheatPlus
version: ${project.version}
name: ${project.name}
version: ${project.pluginVersion}
description: ${project.description}
author: NeatMonster
@ -110,6 +110,8 @@ 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:

View File

@ -1,11 +1,12 @@
package fr.neatmonster.nocheatplus;
import net.minecraft.server.AxisAlignedBB;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.INetworkManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.NetServerHandler;
import net.minecraft.server.Packet10Flying;
import fr.neatmonster.nocheatplus.checks.moving.MovingListener;
import fr.neatmonster.nocheatplus.players.Permissions;
/*
* MM'""""'YMM dP M"""""""`YM dP
@ -29,21 +30,6 @@ import net.minecraft.server.Packet10Flying;
*/
public class CustomNetServerHandler extends NetServerHandler {
/** The distance the player has falled. */
public double fallDistance;
/** Is the player on the ground? Client-side value. */
public boolean onGroundClient;
/** Is the player on the ground? Server-side value. */
public boolean onGroundServer;
/** Was the player on the ground? Client-side value. */
public boolean wasOnGroundClient;
/** Was the player on the ground? Server-side value. */
public boolean wasOnGroundServer;
/**
* Instantiates a new custom net server handler.
*
@ -64,16 +50,9 @@ public class CustomNetServerHandler extends NetServerHandler {
*/
@Override
public void a(final Packet10Flying packet) {
wasOnGroundClient = onGroundClient;
wasOnGroundServer = onGroundServer;
onGroundClient = packet.g;
final AxisAlignedBB boundingBoxGround = player.boundingBox.clone().d(packet.x - player.locX,
packet.y - player.locY - 0.001D, packet.z - player.locZ);
onGroundServer = player.world.getCubes(player, boundingBoxGround).size() > 0;
if (packet.hasPos && wasOnGroundServer && !onGroundServer)
fallDistance = 0D;
else if (packet.hasPos && player.locY - packet.y > 0D)
fallDistance += player.locY - packet.y;
if (player.getBukkitEntity().hasPermission(Permissions.MOVING_NOBUKKITCHECK))
checkMovement = false;
MovingListener.noFall.handlePacket(player, packet);
super.a(packet);
}
}

View File

@ -89,5 +89,4 @@ public class FightData implements CheckData {
// Data of the speed check.
public int speedAttacks;
public long speedTime;
}

View File

@ -28,7 +28,7 @@ public class Reach extends Check {
public final double CREATIVE_DISTANCE = 6D;
/** The maximum distance allowed to interact with an entity in survival mode. */
public final double SURVIVAL_DISTANCE = 3.6D;
public final double SURVIVAL_DISTANCE = 4D;
/**
* Instantiates a new reach check.

View File

@ -78,14 +78,10 @@ public class MovingConfig implements CheckConfig {
public final boolean survivalFlyCheck;
public final int survivalFlyBlockingSpeed;
public final int survivalFlyCobWebSpeed;
public final int survivalFlyLadderSpeed;
public final int survivalFlyLavaSpeed;
public final int survivalFlyMoveSpeed;
public final int survivalFlySneakingSpeed;
public final int survivalFlySoulSandSpeed;
public final int survivalFlySprintingSpeed;
public final int survivalFlyWaterSpeed;
public final int survivalFlySwimmingSpeed;
public final int survivalFlyWalkingSpeed;
public final ActionList survivalFlyActions;
/**
@ -114,14 +110,10 @@ public class MovingConfig implements CheckConfig {
survivalFlyCheck = data.getBoolean(ConfPaths.MOVING_SURVIVALFLY_CHECK);
// Default values are specified here because this settings aren't showed by default into the configuration file.
survivalFlyBlockingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_BLOCKINGSPEED, 100);
survivalFlyCobWebSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_COBWEBSPEED, 100);
survivalFlyLadderSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_LADDERSPEED, 100);
survivalFlyLavaSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_LAVASPEED, 100);
survivalFlyMoveSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_MOVESPEED, 100);
survivalFlySneakingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_SNEAKINGSPEED, 100);
survivalFlySoulSandSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_SOULSANDSPEED, 100);
survivalFlySprintingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_SPRINTINGSPEED, 100);
survivalFlyWaterSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_WATERSPEED, 100);
survivalFlySwimmingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_SWIMMINGSPEED, 100);
survivalFlyWalkingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_WALKINGSPEED, 100);
survivalFlyActions = data.getActionList(ConfPaths.MOVING_SURVIVALFLY_ACTIONS, Permissions.MOVING_SURVIVALFLY);
}

View File

@ -84,14 +84,15 @@ public class MovingData implements CheckData {
// Data of the no fall check.
public double noFallFallDistance;
public boolean noFallOnGroundClient;
public boolean noFallOnGroundServer;
public boolean noFallWasOnGroundClient;
public boolean noFallWasOnGroundServer;
// Data of the survival fly check.
public long survivalFlyInLavaSince;
public long survivalFlyInWaterSince;
public int survivalFlyJumpPhase;
public double[] survivalFlyLastDistances = new double[] {0D, 0D};
public int survivalFlyOnIce;
public long survivalFlyOnLadderSince;
public boolean survivalFlyWasInBed;
// Locations shared between all checks.
@ -105,8 +106,10 @@ public class MovingData implements CheckData {
*/
public void clearFlyData() {
bunnyhopDelay = 0;
setBack = null;
noFallFallDistance = 0D;
noFallOnGroundClient = noFallOnGroundServer = noFallWasOnGroundClient = noFallWasOnGroundServer = true;
survivalFlyJumpPhase = 0;
setBack = null;
}
/**

View File

@ -55,9 +55,25 @@ import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
*/
public class MovingListener implements Listener {
/** The no fall check. **/
public final static NoFall noFall = new NoFall();
/**
* Checks if a material is liquid.
*
* @param material
* the material
* @return true, if the material is liquid
*/
public static boolean isLiquid(final Material material) {
return material == Material.LAVA || material == Material.STATIONARY_LAVA
|| material == Material.STATIONARY_WATER || material == Material.WATER;
}
/** The instance of NoCheatPlus. */
private final NoCheatPlus plugin = (NoCheatPlus) Bukkit.getPluginManager().getPlugin(
"NoCheatPlus");
/** The creative fly check. */
private final CreativeFly creativeFly = new CreativeFly();
@ -67,24 +83,9 @@ public class MovingListener implements Listener {
/** The more packets vehicle check. */
private final MorePacketsVehicle morePacketsVehicle = new MorePacketsVehicle();
/** The no fall check. **/
private final NoFall noFall = new NoFall();
/** The survival fly check. */
private final SurvivalFly survivalFly = new SurvivalFly();
/**
* Checks if a material is liquid.
*
* @param material
* the material
* @return true, if the material is liquid
*/
private boolean isLiquid(final Material material) {
return material == Material.LAVA || material == Material.STATIONARY_LAVA
|| material == Material.STATIONARY_WATER || material == Material.WATER;
}
/**
* A workaround for players placing blocks below them getting pushed off the block by NoCheatPlus.
*

View File

@ -2,10 +2,12 @@ package fr.neatmonster.nocheatplus.checks.moving;
import java.util.Locale;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import net.minecraft.server.AxisAlignedBB;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.Packet10Flying;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.CustomNetServerHandler;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
@ -47,24 +49,21 @@ public class NoFall extends Check {
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingData data = MovingData.getData(player);
// Get the CustomNetServerHandler of the player.
final CustomNetServerHandler customNSH = (CustomNetServerHandler) ((CraftPlayer) player).getHandle().netServerHandler;
// 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.
customNSH.fallDistance = 0D;
data.noFallFallDistance = 0D;
data.noFallFallDistance = customNSH.fallDistance;
data.noFallFallDistance = data.noFallFallDistance;
// If the player just touched the ground for the server, but no for the client.
if (!customNSH.wasOnGroundServer && customNSH.onGroundServer
&& (customNSH.wasOnGroundClient || !customNSH.onGroundClient)) {
if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer
&& (data.noFallWasOnGroundClient || !data.noFallOnGroundClient)) {
// Calculate the fall damages to be dealt.
final int fallDamage = (int) customNSH.fallDistance - 2;
final int fallDamage = (int) data.noFallFallDistance - 2;
if (fallDamage > 0) {
// Add the fall distance to the violation level.
data.noFallVL += customNSH.fallDistance;
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))
@ -74,19 +73,19 @@ public class NoFall extends Check {
}
// If the player just touched the ground for the server.
else if (!customNSH.wasOnGroundServer && customNSH.onGroundServer) {
else if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer) {
// Calculate the difference between the fall distance calculated by the server and by the plugin.
final double difference = (customNSH.fallDistance - player.getFallDistance()) / customNSH.fallDistance;
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) customNSH.fallDistance > 2) {
if (difference > 0.15D && (int) data.noFallFallDistance > 2) {
// Add the difference to the violation level.
data.noFallVL += customNSH.fallDistance - player.getFallDistance();
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.
player.setFallDistance((float) customNSH.fallDistance);
player.setFallDistance((float) data.noFallFallDistance);
} else
// Reward the player by lowering his violation level.
data.noFallVL *= 0.95D;
@ -106,4 +105,26 @@ public class NoFall extends Check {
else
return super.getParameter(wildcard, violationData);
}
/**
* Handle a movement packet to extract its precious information.
*
* @param player
* the player
* @param packet
* the packet
*/
public void handlePacket(final EntityPlayer player, final Packet10Flying packet) {
final MovingData data = MovingData.getData(player.getBukkitEntity());
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;
if (packet.hasPos && data.noFallWasOnGroundServer && !data.noFallOnGroundServer)
data.noFallFallDistance = 0D;
else if (packet.hasPos && player.locY - packet.y > 0D)
data.noFallFallDistance += player.locY - packet.y;
}
}

View File

@ -33,69 +33,6 @@ import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
*/
public class SurvivalFly extends Check {
/** The common margin of error for some speeds. */
private static final double MARGIN = 0.001D;
/** The horizontal speed limit when blocking. */
private static final double BLOCKING_MOVE = 0.16D;
/** The vertical speed limit when ascending into web. */
private static final double COBWEB_ASCEND = 0.02D + MARGIN;
/** The vertical speed limit when descending into web. */
private static final double COBWEB_DESCEND = 0.09D + MARGIN;
/** The horizontal speed limit when moving into web. */
private static final double COBWEB_MOVE = 0.11D;
/** The horizontal speed amplifier when being on ice. */
private static final double ICE_AMPLIFIER = 2.5D;
/** The number of events contained in a jump phase. */
private static final int JUMP_PHASE = 6;
/** The distance removed after each jumping event. */
private static final double JUMP_STEP = 0.15D;
/** The vertical speed limit when ascending on a ladder. */
private static final double LADDER_ASCEND = 0.225D + MARGIN;
/** The vertical speed limit when descending on a ladder. */
private static final double LADDER_DESCEND = 0.15D + MARGIN;
/** The vertical speed limit when ascending into lava. */
private static final double LAVA_ASCEND = 0.08D + MARGIN;
/** The vertical speed limit when descending into lava. */
private static final double LAVA_DESCEND = 0.085D + MARGIN;
/** The horizontal speed limit when moving into lava. */
private static final double LAVA_MOVE = 0.12D;
/** The horizontal and usual speed limit when moving. */
private static final double MOVE = 0.22D;
/** The horizontal speed limit when sneaking. */
private static final double SNEAKING_MOVE = 0.14D;
/** The horizontal speed limit when moving on soul sand. */
private static final double SOULSAND_MOVE = 0.13D;
/** The horizontal speed limit when sprinting on soul sand. */
private static final double SOULSAND_SPRINTING_MOVE = 0.18D;
/** The horizontal speed limit when sprinting. */
private static final double SPRINTING_MOVE = 0.35D;
/** The vertical speed limit when ascending into water. */
private static final double WATER_ASCEND = 0.13D + MARGIN;
/** The vertical speed limit when descending into water. */
private static final double WATER_DESCEND = 0.17D + MARGIN;
/** The horizontal speed limit when moving into water. */
private static final double WATER_MOVE = 0.18D;
/**
* Instantiates a new survival fly check.
*/
@ -142,6 +79,9 @@ public class SurvivalFly extends Check {
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingData data = MovingData.getData(player);
// 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 (data.setBack == null)
data.setBack = from.getLocation();
@ -151,35 +91,21 @@ public class SurvivalFly extends Check {
else if (data.survivalFlyOnIce > 0)
data.survivalFlyOnIce--;
// 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;
boolean useBuffer = true;
// Handle all the special cases.
double hAllowedDistance = cc.survivalFlyMoveSpeed / 100D * MOVE;
if (from.isInWeb() && to.isInWeb()) {
hAllowedDistance = cc.survivalFlyCobWebSpeed / 100D * COBWEB_MOVE;
useBuffer = false;
} else if (from.isOnSoulSand() && to.isOnSoulSand() && !sprinting) {
hAllowedDistance = cc.survivalFlySoulSandSpeed / 100D * SOULSAND_MOVE;
useBuffer = false;
} else if (from.isInLava() && to.isInLava())
hAllowedDistance = cc.survivalFlyLavaSpeed / 100D * LAVA_MOVE;
else if (from.isOnSoulSand() && to.isOnSoulSand() && sprinting) {
hAllowedDistance = cc.survivalFlySoulSandSpeed / 100D * SOULSAND_SPRINTING_MOVE;
useBuffer = false;
} else if (player.isSneaking() && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SNEAKING))
hAllowedDistance = cc.survivalFlySneakingSpeed / 100D * SNEAKING_MOVE;
double hAllowedDistance = 0D;
if (player.isSneaking() && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SNEAKING))
hAllowedDistance = 0.14D * cc.survivalFlySneakingSpeed / 100D;
else if (player.isBlocking() && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_BLOCKING))
hAllowedDistance = cc.survivalFlyBlockingSpeed / 100D * BLOCKING_MOVE;
hAllowedDistance = 0.16D * cc.survivalFlyBlockingSpeed / 100D;
else if (from.isInWater() && to.isInWater())
hAllowedDistance = cc.survivalFlyWaterSpeed / 100D * WATER_MOVE;
else if (sprinting)
hAllowedDistance = cc.survivalFlySprintingSpeed / 100D * SPRINTING_MOVE;
hAllowedDistance = 0.18D * cc.survivalFlySwimmingSpeed / 100D;
else if (!sprinting)
hAllowedDistance = 0.22D * cc.survivalFlyWalkingSpeed / 100D;
else
hAllowedDistance = 0.35D * cc.survivalFlySprintingSpeed / 100D;
// If the player is on ice, give him an higher maximum speed.
if (data.survivalFlyOnIce > 0)
hAllowedDistance *= ICE_AMPLIFIER;
hAllowedDistance *= 2.5D;
// Taken directly from Minecraft code, should work.
final EntityPlayer entity = ((CraftPlayer) player).getHandle();
@ -190,45 +116,45 @@ public class SurvivalFly extends Check {
final double xDistance = to.getX() - from.getX();
final double zDistance = to.getZ() - from.getZ();
final double hDistance = Math.sqrt(xDistance * xDistance + zDistance * zDistance);
double hDistanceAboveLimit = hDistance - hAllowedDistance - data.horizontalFreedom;
data.bunnyhopDelay--;
// Prevent players from walking on a liquid.
if (hDistanceAboveLimit <= 0D && hDistance > 0.1D && from.getY() == to.getY()
&& MovingListener.isLiquid(to.getLocation().getBlock().getType()) && !to.isOnGround()
&& to.getY() % 1D < 0.8D)
hDistanceAboveLimit = hDistance;
if (useBuffer) {
// Did he go too far?
if (hDistanceAboveLimit > 0D && sprinting)
// Try to treat it as a the "bunnyhop" problem.
if (data.bunnyhopDelay <= 0 && hDistanceAboveLimit > 0.05D && hDistanceAboveLimit < 0.4D) {
data.bunnyhopDelay = 9;
hDistanceAboveLimit = 0D;
}
if (hDistanceAboveLimit > 0D) {
// Try to consume the "buffer".
hDistanceAboveLimit -= data.horizontalBuffer;
data.horizontalBuffer = 0D;
// Put back the "overconsumed" buffer.
if (hDistanceAboveLimit < 0D)
data.horizontalBuffer = -hDistanceAboveLimit;
} else
// He was within limits, give the difference as buffer.
data.horizontalBuffer = Math.min(1D, data.horizontalBuffer - hDistanceAboveLimit);
}
hDistanceAboveLimit = Math.max(0D, hDistanceAboveLimit);
if (hDistanceAboveLimit == 0D && sprinting && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SPRINTING)) {
// 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();
// Prevent players from sprinting if they're moving backwards.
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)
hDistanceAboveLimit = hDistance;
}
data.bunnyhopDelay--;
// Did he go too far?
if (hDistanceAboveLimit > 0 && sprinting)
// Try to treat it as a the "bunnyhop" problem.
if (data.bunnyhopDelay <= 0 && hDistanceAboveLimit > 0.05D && hDistanceAboveLimit < 0.28D) {
data.bunnyhopDelay = 9;
hDistanceAboveLimit = 0D;
}
if (hDistanceAboveLimit > 0D) {
// Try to consume the "buffer".
hDistanceAboveLimit -= data.horizontalBuffer;
data.horizontalBuffer = 0D;
// Put back the "overconsumed" buffer.
if (hDistanceAboveLimit < 0D)
data.horizontalBuffer = -hDistanceAboveLimit;
} else
data.horizontalBuffer = Math.min(1D, data.horizontalBuffer - hDistanceAboveLimit);
// Potion effect "Jump".
double jumpAmplifier = 1D;
if (entity.hasEffect(MobEffectList.JUMP)) {
@ -241,78 +167,29 @@ public class SurvivalFly extends Check {
if (jumpAmplifier > data.jumpAmplifier)
data.jumpAmplifier = jumpAmplifier;
// Remember since when the player is in lava/in water/on ladder.
if (from.isInLava() && !to.isInLava())
data.survivalFlyInLavaSince = 0L;
else if (!from.isInLava() && to.isInLava())
data.survivalFlyInLavaSince = System.currentTimeMillis();
if (from.isInWater() && !to.isInWater())
data.survivalFlyInWaterSince = 0L;
else if (!from.isInWater() && to.isInWater())
data.survivalFlyInWaterSince = System.currentTimeMillis();
if (from.isOnLadder() && !to.isOnLadder())
data.survivalFlyOnLadderSince = 0L;
else if (!from.isOnLadder() && to.isOnLadder())
data.survivalFlyOnLadderSince = System.currentTimeMillis();
double vAllowedDistance = 1.35D + data.verticalFreedom;
vAllowedDistance *= data.jumpAmplifier;
if (data.survivalFlyJumpPhase > 6 + data.jumpAmplifier)
vAllowedDistance -= (data.survivalFlyJumpPhase - 6) * 0.15D;
double vDistance = to.getY() - from.getY();
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)
data.survivalFlyJumpPhase = 0;
else if (vDistance <= 0D)
data.survivalFlyJumpPhase = 0;
data.survivalFlyLastDistances[1] = data.survivalFlyLastDistances[0];
data.survivalFlyLastDistances[0] = vDistance;
// Handle all the special cases.
double vDistanceAboveLimit = 0D;
if (from.isInLava() && to.isInLava() && data.survivalFlyInLavaSince > 0L
&& System.currentTimeMillis() - data.survivalFlyInLavaSince > 1000L) {
if (vDistance > cc.survivalFlyLavaSpeed / 100D * LAVA_ASCEND)
vDistanceAboveLimit = vDistance - cc.survivalFlyLavaSpeed / 100D * LAVA_ASCEND;
else if (vDistance < cc.survivalFlyLavaSpeed / 100D * -LAVA_DESCEND)
vDistanceAboveLimit = cc.survivalFlyLavaSpeed / 100D * -LAVA_DESCEND - vDistance;
} else if (from.isInWater() && to.isInWater() && data.survivalFlyInWaterSince > 0L
&& System.currentTimeMillis() - data.survivalFlyInWaterSince > 1000L) {
if (vDistance > cc.survivalFlyWaterSpeed / 100D * WATER_ASCEND)
vDistanceAboveLimit = vDistance - cc.survivalFlyWaterSpeed / 100D * WATER_ASCEND;
else if (vDistance < cc.survivalFlyWaterSpeed / 100D * -WATER_DESCEND)
vDistanceAboveLimit = cc.survivalFlyWaterSpeed / 100D * -WATER_DESCEND - vDistance;
} else if (from.isInWeb() && to.isInWeb()) {
if (vDistance > cc.survivalFlyCobWebSpeed / 100D * COBWEB_ASCEND)
vDistanceAboveLimit = vDistance - cc.survivalFlyCobWebSpeed / 100D * COBWEB_ASCEND;
else if (vDistance < cc.survivalFlyCobWebSpeed / 100D * -COBWEB_DESCEND)
vDistanceAboveLimit = cc.survivalFlyCobWebSpeed / 100D * -COBWEB_DESCEND - vDistance;
} else if (from.isOnLadder(true) && to.isOnLadder(true) && data.survivalFlyOnLadderSince > 0L
&& System.currentTimeMillis() - data.survivalFlyOnLadderSince > 1000L) {
if (vDistance > cc.survivalFlyLadderSpeed / 100D * LADDER_ASCEND)
vDistanceAboveLimit = vDistance - cc.survivalFlyLadderSpeed / 100D * LADDER_ASCEND;
else if (vDistance < cc.survivalFlyLadderSpeed / 100D * -LADDER_DESCEND)
vDistanceAboveLimit = cc.survivalFlyLadderSpeed / 100D * -LADDER_DESCEND - vDistance;
} else {
vDistance = to.getY() - data.setBack.getY();
if (data.survivalFlyLastDistances[0] < data.survivalFlyLastDistances[1]
&& vDistance > data.survivalFlyLastDistances[0] && data.survivalFlyJumpPhase >= 7
&& data.survivalFlyJumpPhase <= 8)
data.survivalFlyJumpPhase = 0;
else if (vDistance <= 0D)
data.survivalFlyJumpPhase = 0;
data.survivalFlyLastDistances[1] = data.survivalFlyLastDistances[0];
data.survivalFlyLastDistances[0] = vDistance;
double vAllowedDistance = (data.verticalFreedom + (!from.isOnGround() && to.isOnGround() ? 1.5D : 1.35D))
* data.jumpAmplifier;
if (data.survivalFlyJumpPhase > JUMP_PHASE + data.jumpAmplifier)
vAllowedDistance -= (data.survivalFlyJumpPhase - JUMP_PHASE) * JUMP_STEP;
vDistanceAboveLimit = Math.max(0D, vDistance - vAllowedDistance);
}
// Handle slabs placed into a liquid.
if ((to.isOnGround() && to.getY() - from.getY() == 0.5D || !from.isOnGround() && to.isOnGround() || from
.isOnGround() && !to.isOnGround())
&& from.isInLiquid() && to.isInLiquid())
double vDistanceAboveLimit = vDistance - vAllowedDistance;
if (from.isOnStairs() || to.isOnStairs() && vDistanceAboveLimit < 0.15D) {
data.jumpAmplifier = 0D;
vDistanceAboveLimit = 0D;
if (from.isOnGround() || to.isOnGround())
} else if (from.isOnGround() || to.isOnGround())
data.jumpAmplifier = 0D;
final double result = (hDistanceAboveLimit + vDistanceAboveLimit) * 100D;
final double result = (Math.max(hDistanceAboveLimit, 0D) + Math.max(vDistanceAboveLimit, 0D)) * 100D;
data.survivalFlyJumpPhase++;

View File

@ -314,14 +314,10 @@ public abstract class ConfPaths {
private static final String MOVING_SURVIVALFLY = MOVING + "survivalfly.";
public static final String MOVING_SURVIVALFLY_CHECK = MOVING_SURVIVALFLY + "active";
public static final String MOVING_SURVIVALFLY_BLOCKINGSPEED = MOVING_SURVIVALFLY + "blockingspeed";
public static final String MOVING_SURVIVALFLY_COBWEBSPEED = MOVING_SURVIVALFLY + "cobwebspeed";
public static final String MOVING_SURVIVALFLY_LAVASPEED = MOVING_SURVIVALFLY + "lavaspeed";
public static final String MOVING_SURVIVALFLY_LADDERSPEED = MOVING_SURVIVALFLY + "ladderspeed";
public static final String MOVING_SURVIVALFLY_MOVESPEED = MOVING_SURVIVALFLY + "movespeed";
public static final String MOVING_SURVIVALFLY_SNEAKINGSPEED = MOVING_SURVIVALFLY + "sneakingspeed";
public static final String MOVING_SURVIVALFLY_SOULSANDSPEED = MOVING_SURVIVALFLY + "soulsandspeed";
public static final String MOVING_SURVIVALFLY_SPRINTINGSPEED = MOVING_SURVIVALFLY + "sprintingspeed";
public static final String MOVING_SURVIVALFLY_WATERSPEED = MOVING_SURVIVALFLY + "waterspeed";
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_ACTIONS = MOVING_SURVIVALFLY + "actions";
/*

View File

@ -273,14 +273,10 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.MOVING_SURVIVALFLY_CHECK, 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_COBWEBSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_LADDERSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_LAVASPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_MOVESPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SNEAKINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SOULSANDSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SPRINTINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_WATERSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SWIMMINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_WALKINGSPEED, 100);
set(ConfPaths.MOVING_SURVIVALFLY_ACTIONS,
"log:flyshort:3:5:f cancel vl>100 log:flyshort:0:5:if cancel vl>400 log:flylong:0:5:cif cancel");

View File

@ -126,6 +126,7 @@ 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";

View File

@ -359,21 +359,9 @@ public class PlayerLocation {
*/
public boolean isOnStairs() {
if (!onStairs.isSet()) {
AxisAlignedBB boundingBoxGround = boundingBox.clone();
boundingBoxGround = boundingBoxGround.d(0D, -0.5D, 0D);
for (final Object object : world.getCubes(entity, boundingBoxGround)) {
final AxisAlignedBB aabbCube = (AxisAlignedBB) object;
final int blockX = (int) Math.floor(aabbCube.a);
final int blockY = (int) Math.floor(aabbCube.b);
final int blockZ = (int) Math.floor(aabbCube.c);
final int id = world.getTypeId(blockX, blockY, blockZ);
if (!onStairs.get()
&& (id == 53 || id == 67 || id == 108 || id == 109 || id == 114 || id == 128 || id == 134
|| id == 135 || id == 136))
onStairs.set(true);
}
if (!onStairs.isSet())
onStairs.set(false);
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();
}