diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 56550141..00000000 --- a/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# Eclipse stuff -/.classpath -/.project -/.settings - -# netbeans -/nbproject - -# we use maven! -/build.xml - -# maven -/target - -# vim -.*.sw[a-p] - -# various other potential build files -/build -/bin -/dist -/manifest.mf - -# Mac filesystem dust -/.DS_Store - -# intellij -*.iml -*.ipr -*.iws -.idea/ -/auth.properties diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..3dc3f329 --- /dev/null +++ b/pom.xml @@ -0,0 +1,132 @@ + + 4.0.0 + + + NoCheatPlus + 3.7 + Detect and fight the exploitation of various flaws/bugs in Minecraft. + http://dev.bukkit.org/server-mods/nocheatplus + + fr.neatmonster.nocheatplus + NoCheatPlus + jar + + + + + GNU General Public License v3 + http://www.gnu.org/licenses/gpl-3.0.html + repo + + + + + + scm:git:git@github.com:NeatMonster/${project.name}.git + scm:git:git://github.com/NeatMonster/${project.name}.git + https://github.com/NeatMonster/${project.name} + + + + + + bukkit + Bukkit + http://repo.bukkit.org/content/groups/public/ + + + + + + + org.bukkit + craftbukkit + 1.3.1-R1.0 + jar + compile + + + + + + clean package + ${basedir}/src + + + . + true + ${basedir} + + plugin.yml + LICENSE.txt + Instructions.txt + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + NoCheatPlus + + false + false + + false + false + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + deploy-build + install + + + + + + + + + run + + + + + + org.apache.ant + ant-jsch + 1.8.4 + + + + + + + + + UTF-8 + + \ No newline at end of file diff --git a/src/fr/neatmonster/nocheatplus/checks/chat/ChatListener.java b/src/fr/neatmonster/nocheatplus/checks/chat/ChatListener.java index 88835ee3..e2439b10 100644 --- a/src/fr/neatmonster/nocheatplus/checks/chat/ChatListener.java +++ b/src/fr/neatmonster/nocheatplus/checks/chat/ChatListener.java @@ -131,11 +131,11 @@ public class ChatListener implements Listener { * |_| |_|\__,_|\__, |\___|_| \___/ \___/|_|_| |_| * |___/ */ - final Player player = event.getPlayer(); - final ChatConfig cc = ChatConfig.getConfig(player); // Non critical use (concurrency). + final Player player = event.getPlayer(); + final ChatConfig cc = ChatConfig.getConfig(player); - // Then the no pwnage check, if the login isn't already disallowed. - if (event.getResult() != Result.KICK_OTHER && noPwnage.check(player)) + // Execute the no pwnage check. + if (noPwnage.isEnabled(player) && noPwnage.check(player)) event.disallow(Result.KICK_OTHER, cc.noPwnageReloginKickMessage); } } diff --git a/src/fr/neatmonster/nocheatplus/checks/fight/InstantHeal.java b/src/fr/neatmonster/nocheatplus/checks/fight/InstantHeal.java index 179924d9..d5c0edbc 100644 --- a/src/fr/neatmonster/nocheatplus/checks/fight/InstantHeal.java +++ b/src/fr/neatmonster/nocheatplus/checks/fight/InstantHeal.java @@ -44,7 +44,7 @@ public class InstantHeal extends Check { return false; } - final long delta = System.currentTimeMillis() - (data.instantHealLastTime + 3500L); + final long delta = System.currentTimeMillis() - (data.instantHealLastTime + 3000L); data.instantHealBuffer += delta; if (data.instantHealBuffer < 0) { diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java index a2bf592e..a1d985ea 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java @@ -67,6 +67,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(); @@ -313,10 +316,13 @@ public class MovingListener implements Listener { if ((player.getGameMode() == GameMode.CREATIVE || player.getAllowFlight()) && creativeFly.isEnabled(player)) // If the player is handled by the creative fly check, execute it. newTo = creativeFly.check(player, from, to); - else if (survivalFly.isEnabled(player)) + else if (survivalFly.isEnabled(player)) { // If he is handled by the survival fly check, execute it. newTo = survivalFly.check(player, from, to); - else + if (newTo == null && noFall.isEnabled(player)) + // If he is handled by the no fall check, execute it. + noFall.check(player, from, to); + } else // He isn't handled by any fly check, clear his data. data.clearFlyData(); diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java b/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java index 45c7c2c3..a4282f32 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/NoFall.java @@ -104,7 +104,7 @@ public class NoFall extends Check { // feeling. if (from.getY() > to.getY()) { final float deltaY = (float) (from.getY() - to.getY()); - data.noFallDistance += deltaY * 0.75F; // Magic number. :) + data.noFallDistance += deltaY * 0.75D; // Magic number. :) if (deltaY > 1F) { data.noFallLastAddedDistance = deltaY; @@ -114,7 +114,7 @@ public class NoFall extends Check { } else data.noFallLastAddedDistance = 0F; - if (to.isOnGround()) + if (to.isOnGround() || from.isOnStairs()) data.noFallDistance = 0F; // Reduce violation level. diff --git a/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java b/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java index a475d745..ba3f1c09 100644 --- a/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java +++ b/src/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java @@ -84,7 +84,7 @@ public class SurvivalFly extends Check { private static final double SOULSAND_SPRINTING_MOVE = 0.18D; /** The horizontal speed limit when sprinting. */ - private static final double SPRINTING_MOVE = 0.37D; + 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; @@ -95,9 +95,6 @@ public class SurvivalFly extends Check { /** The horizontal speed limit when moving into water. */ private static final double WATER_MOVE = 0.18D; - /** The no fall check. */ - private final NoFall noFall = new NoFall(); - /** * Instantiates a new survival fly check. */ @@ -177,7 +174,7 @@ public class SurvivalFly extends Check { hAllowedDistance = cc.survivalFlyBlockingSpeed / 100D * BLOCKING_MOVE; else if (from.isInWater() && to.isInWater()) hAllowedDistance = cc.survivalFlyWaterSpeed / 100D * WATER_MOVE; - else if (player.isSprinting() && player.getFoodLevel() > 5) + else if (sprinting) hAllowedDistance = cc.survivalFlySprintingSpeed / 100D * SPRINTING_MOVE; if (data.survivalFlyOnIce > 0) @@ -221,6 +218,16 @@ public class SurvivalFly extends Check { hDistanceAboveLimit = Math.max(0D, hDistanceAboveLimit); + 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; + } + // Potion effect "Jump". double jumpAmplifier = 1D; if (entity.hasEffect(MobEffectList.JUMP)) { @@ -288,7 +295,8 @@ public class SurvivalFly extends Check { data.survivalFlyLastDistances[1] = data.survivalFlyLastDistances[0]; data.survivalFlyLastDistances[0] = vDistance; - double vAllowedDistance = (data.verticalFreedom + 1.35D) * data.jumpAmplifier; + 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; @@ -352,10 +360,6 @@ public class SurvivalFly extends Check { data.survivalFlyJumpPhase = 0; } - if (noFall.isEnabled(player)) - // Execute the NoFall check. - noFall.check(player, from, to); - return null; } diff --git a/src/fr/neatmonster/nocheatplus/players/Permissions.java b/src/fr/neatmonster/nocheatplus/players/Permissions.java index b1750f9e..9e3ab661 100644 --- a/src/fr/neatmonster/nocheatplus/players/Permissions.java +++ b/src/fr/neatmonster/nocheatplus/players/Permissions.java @@ -13,7 +13,7 @@ package fr.neatmonster.nocheatplus.players; * The various permission nodes used by NoCheatPlus. */ public class Permissions { - private static final String NOCHEATPLUS = "nocheatplus"; + private static final String NOCHEATPLUS = "nocheatplus"; /* * e Y8b 888 ,e, ,e, d8 d8 ,e, @@ -22,10 +22,10 @@ public class Permissions { * d888888888b Y888 888 888 888 888 888 888 888 888 Y88D 888 888 ,ee 888 888 888 Y888 888P 888 888 * d8888888b Y8b "88 888 888 888 888 888 888 888 888 d,dP 888 888 "88 888 888 888 "88 88" 888 888 */ - private static final String ADMINISTRATION = NOCHEATPLUS + ".admin"; - public static final String ADMINISTRATION_NOTIFY = ADMINISTRATION + ".notify"; - public static final String ADMINISTRATION_PLUGINS = ADMINISTRATION + ".plugins"; - public static final String ADMINISTRATION_RELOAD = ADMINISTRATION + ".reload"; + private static final String ADMINISTRATION = NOCHEATPLUS + ".admin"; + public static final String ADMINISTRATION_NOTIFY = ADMINISTRATION + ".notify"; + public static final String ADMINISTRATION_PLUGINS = ADMINISTRATION + ".plugins"; + public static final String ADMINISTRATION_RELOAD = ADMINISTRATION + ".reload"; /* * e e 888 ,e, dP,e, ,e, d8 ,e, @@ -34,36 +34,36 @@ public class Permissions { * d8b Y8b Y8b Y888 888P Y888 888 888 888 888 Y888 , ,ee 888 888 888 Y888 888P 888 888 Y88D * d888b Y8b Y8b "88 88" "88 888 888 888 888 "88,e8' "88 888 888 888 "88 88" 888 888 d,dP */ - private static final String MODS = NOCHEATPLUS + ".mods"; + private static final String MODS = NOCHEATPLUS + ".mods"; - private static final String CJB = MODS + ".cjb"; - public static final String CJB_FLY = CJB + ".fly"; - public static final String CJB_XRAY = CJB + ".xray"; - public static final String CJB_RADAR = CJB + ".radar"; + private static final String CJB = MODS + ".cjb"; + public static final String CJB_FLY = CJB + ".fly"; + public static final String CJB_XRAY = CJB + ".xray"; + public static final String CJB_RADAR = CJB + ".radar"; - private static final String MINECRAFTAUTOMAP = MODS + ".minecraftautomap"; - public static final String MINECRAFTAUTOMAP_ORES = MINECRAFTAUTOMAP + ".ores"; - public static final String MINECRAFTAUTOMAP_CAVE = MINECRAFTAUTOMAP + ".cave"; - public static final String MINECRAFTAUTOMAP_RADAR = MINECRAFTAUTOMAP + ".radar"; + private static final String MINECRAFTAUTOMAP = MODS + ".minecraftautomap"; + public static final String MINECRAFTAUTOMAP_ORES = MINECRAFTAUTOMAP + ".ores"; + public static final String MINECRAFTAUTOMAP_CAVE = MINECRAFTAUTOMAP + ".cave"; + public static final String MINECRAFTAUTOMAP_RADAR = MINECRAFTAUTOMAP + ".radar"; - private static final String REI = MODS + ".rei"; - public static final String REI_CAVE = REI + ".cave"; - public static final String REI_RADAR = REI + ".radar"; + private static final String REI = MODS + ".rei"; + public static final String REI_CAVE = REI + ".cave"; + public static final String REI_RADAR = REI + ".radar"; - private static final String SMARTMOVING = MODS + ".smartmoving"; - public static final String SMARTMOVING_CLIMBING = SMARTMOVING + ".climbing"; - public static final String SMARTMOVING_SWIMMING = SMARTMOVING + ".swimming"; - public static final String SMARTMOVING_CRAWLING = SMARTMOVING + ".crawling"; - public static final String SMARTMOVING_SLIDING = SMARTMOVING + ".sliding"; - public static final String SMARTMOVING_JUMPING = SMARTMOVING + ".jumping"; - public static final String SMARTMOVING_FLYING = SMARTMOVING + ".flying"; + private static final String SMARTMOVING = MODS + ".smartmoving"; + public static final String SMARTMOVING_CLIMBING = SMARTMOVING + ".climbing"; + public static final String SMARTMOVING_SWIMMING = SMARTMOVING + ".swimming"; + public static final String SMARTMOVING_CRAWLING = SMARTMOVING + ".crawling"; + public static final String SMARTMOVING_SLIDING = SMARTMOVING + ".sliding"; + public static final String SMARTMOVING_JUMPING = SMARTMOVING + ".jumping"; + public static final String SMARTMOVING_FLYING = SMARTMOVING + ".flying"; - private static final String ZOMBE = MODS + ".zombe"; - public static final String ZOMBE_FLY = ZOMBE + ".fly"; - public static final String ZOMBE_NOCLIP = ZOMBE + ".noclip"; - public static final String ZOMBE_CHEAT = ZOMBE + ".cheat"; + private static final String ZOMBE = MODS + ".zombe"; + public static final String ZOMBE_FLY = ZOMBE + ".fly"; + public static final String ZOMBE_NOCLIP = ZOMBE + ".noclip"; + public static final String ZOMBE_CHEAT = ZOMBE + ".cheat"; - private static final String CHECKS = NOCHEATPLUS + ".checks"; + private static final String CHECKS = NOCHEATPLUS + ".checks"; /* * 888 88b, 888 888 888 88b, 888 @@ -72,11 +72,11 @@ public class Permissions { * 888 88b, 888 Y888 888P Y888 , 888 b 888 88b, 888 888 , ,ee 888 888 b * 888 88P' 888 "88 88" "88,e8' 888 8b 888 88P' 888 "YeeP" "88 888 888 8b */ - private static final String BLOCKBREAK = CHECKS + ".blockbreak"; - public static final String BLOCKBREAK_DIRECTION = BLOCKBREAK + ".direction"; - public static final String BLOCKBREAK_FASTBREAK = BLOCKBREAK + ".fastbreak"; - public static final String BLOCKBREAK_NOSWING = BLOCKBREAK + ".noswing"; - public static final String BLOCKBREAK_REACH = BLOCKBREAK + ".reach"; + private static final String BLOCKBREAK = CHECKS + ".blockbreak"; + public static final String BLOCKBREAK_DIRECTION = BLOCKBREAK + ".direction"; + public static final String BLOCKBREAK_FASTBREAK = BLOCKBREAK + ".fastbreak"; + public static final String BLOCKBREAK_NOSWING = BLOCKBREAK + ".noswing"; + public static final String BLOCKBREAK_REACH = BLOCKBREAK + ".reach"; /* * 888 88b, 888 888 888 d8 d8 @@ -85,9 +85,9 @@ public class Permissions { * 888 88b, 888 Y888 888P Y888 , 888 b 888 888 888 888 888 , 888 ,ee 888 Y888 , 888 * 888 88P' 888 "88 88" "88,e8' 888 8b 888 888 888 888 "YeeP" 888 "88 888 "88,e8' 888 */ - private static final String BLOCKINTERACT = CHECKS + ".blockinteract"; - public static final String BLOCKINTERACT_DIRECTION = BLOCKINTERACT + ".direction"; - public static final String BLOCKINTERACT_REACH = BLOCKINTERACT + ".reach"; + private static final String BLOCKINTERACT = CHECKS + ".blockinteract"; + public static final String BLOCKINTERACT_DIRECTION = BLOCKINTERACT + ".direction"; + public static final String BLOCKINTERACT_REACH = BLOCKINTERACT + ".reach"; /* * 888 88b, 888 888 888 88e 888 @@ -96,12 +96,12 @@ public class Permissions { * 888 88b, 888 Y888 888P Y888 , 888 b 888 888 ,ee 888 Y888 , 888 , * 888 88P' 888 "88 88" "88,e8' 888 8b 888 888 "88 888 "88,e8' "YeeP" */ - private static final String BLOCKPLACE = CHECKS + ".blockplace"; - public static final String BLOCKPLACE_DIRECTION = BLOCKPLACE + ".direction"; - public static final String BLOCKPLACE_FASTPLACE = BLOCKPLACE + ".fastplace"; - public static final String BLOCKPLACE_NOSWING = BLOCKPLACE + ".noswing"; - public static final String BLOCKPLACE_REACH = BLOCKPLACE + ".reach"; - public static final String BLOCKPLACE_SPEED = BLOCKPLACE + ".speed"; + private static final String BLOCKPLACE = CHECKS + ".blockplace"; + public static final String BLOCKPLACE_DIRECTION = BLOCKPLACE + ".direction"; + public static final String BLOCKPLACE_FASTPLACE = BLOCKPLACE + ".fastplace"; + public static final String BLOCKPLACE_NOSWING = BLOCKPLACE + ".noswing"; + public static final String BLOCKPLACE_REACH = BLOCKPLACE + ".reach"; + public static final String BLOCKPLACE_SPEED = BLOCKPLACE + ".speed"; /* * e88'Y88 888 d8 @@ -110,10 +110,9 @@ public class Permissions { * Y888 ,d 888 888 ,ee 888 888 * "88,d88 888 888 "88 888 888 */ - private static final String CHAT = CHECKS + ".chat"; - public static final String CHAT_ARRIVALS = CHAT + ".arrivals"; - public static final String CHAT_COLOR = CHAT + ".color"; - public static final String CHAT_NOPWNAGE = CHAT + ".nopwnage"; + private static final String CHAT = CHECKS + ".chat"; + public static final String CHAT_COLOR = CHAT + ".color"; + public static final String CHAT_NOPWNAGE = CHAT + ".nopwnage"; /* * 888'Y88 ,e, 888 d8 @@ -124,16 +123,16 @@ public class Permissions { * , 88P * "8",P" */ - private static final String FIGHT = CHECKS + ".fight"; - public static final String FIGHT_ANGLE = FIGHT + ".angle"; - public static final String FIGHT_CRITICAL = FIGHT + ".critical"; - public static final String FIGHT_DIRECTION = FIGHT + ".direction"; - public static final String FIGHT_GODMODE = FIGHT + ".godmode"; - 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"; - public static final String FIGHT_SPEED = FIGHT + ".speed"; + private static final String FIGHT = CHECKS + ".fight"; + public static final String FIGHT_ANGLE = FIGHT + ".angle"; + public static final String FIGHT_CRITICAL = FIGHT + ".critical"; + public static final String FIGHT_DIRECTION = FIGHT + ".direction"; + public static final String FIGHT_GODMODE = FIGHT + ".godmode"; + 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"; + public static final String FIGHT_SPEED = FIGHT + ".speed"; /* * 888 d8 @@ -144,10 +143,10 @@ public class Permissions { * 888 * 888 */ - private static final String INVENTORY = CHECKS + ".inventory"; - public static final String INVENTORY_DROP = INVENTORY + ".drop"; - public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow"; - public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat"; + private static final String INVENTORY = CHECKS + ".inventory"; + public static final String INVENTORY_DROP = INVENTORY + ".drop"; + public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow"; + public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat"; /* * e e ,e, @@ -158,13 +157,14 @@ public class Permissions { * , 88P * "8",P" */ - private static final String MOVING = CHECKS + ".moving"; - public static final String MOVING_BOATSANYWHERE = MOVING + ".boatsanywhere"; - 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_NOFALL = MOVING + ".nofall"; - public static final String MOVING_SURVIVALFLY = MOVING + ".survivalfly"; - public static final String MOVING_SURVIVALFLY_BLOCKING = MOVING_SURVIVALFLY + ".blocking"; - public static final String MOVING_SURVIVALFLY_SNEAKING = MOVING_SURVIVALFLY + ".sneaking"; + private static final String MOVING = CHECKS + ".moving"; + public static final String MOVING_BOATSANYWHERE = MOVING + ".boatsanywhere"; + 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_NOFALL = MOVING + ".nofall"; + public static final String MOVING_SURVIVALFLY = MOVING + ".survivalfly"; + public static final String MOVING_SURVIVALFLY_BLOCKING = MOVING_SURVIVALFLY + ".blocking"; + public static final String MOVING_SURVIVALFLY_SNEAKING = MOVING_SURVIVALFLY + ".sneaking"; + public static final String MOVING_SURVIVALFLY_SPRINTING = MOVING_SURVIVALFLY + ".sprinting"; } diff --git a/src/fr/neatmonster/nocheatplus/utilities/PlayerLocation.java b/src/fr/neatmonster/nocheatplus/utilities/PlayerLocation.java index 257f2ba2..81810f68 100644 --- a/src/fr/neatmonster/nocheatplus/utilities/PlayerLocation.java +++ b/src/fr/neatmonster/nocheatplus/utilities/PlayerLocation.java @@ -102,6 +102,9 @@ public class PlayerLocation { /** Is the player on soul sand? */ private final CustomBoolean onSoulSand = new CustomBoolean(); + /** Is the player on stairs? */ + private final CustomBoolean onStairs = new CustomBoolean(); + /** The bounding box of the player. */ private final AxisAlignedBB boundingBox; @@ -348,4 +351,30 @@ 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()) { + 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); + } + return onStairs.get(); + } }