Hot fix for bounding box problems.

This commit is contained in:
asofold 2012-11-08 06:02:22 +01:00
parent 22f2a5c248
commit 462aeed412
5 changed files with 447 additions and 383 deletions

View File

@ -5,6 +5,7 @@ import org.bukkit.potion.PotionEffectType;
import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.LagMeasureTask; import fr.neatmonster.nocheatplus.utilities.LagMeasureTask;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation; import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
@ -45,6 +46,11 @@ public class Critical extends Check {
// We'll need the PlayerLocation to know some important stuff. // We'll need the PlayerLocation to know some important stuff.
final PlayerLocation location = new PlayerLocation(); final PlayerLocation location = new PlayerLocation();
location.set(player.getLocation(), player); location.set(player.getLocation(), player);
if (location.isIllegal()) {
location.cleanup();
CheckUtils.onIllegalMove(player);
return true;
}
// Check if the hit was a critical hit (positive fall distance, entity in the air, not on ladder, not in liquid // Check if the hit was a critical hit (positive fall distance, entity in the air, not on ladder, not in liquid
// and without blindness effect). // and without blindness effect).

View File

@ -45,6 +45,7 @@ import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.utilities.BlockCache; import fr.neatmonster.nocheatplus.utilities.BlockCache;
import fr.neatmonster.nocheatplus.utilities.BlockProperties; import fr.neatmonster.nocheatplus.utilities.BlockProperties;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation; import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
/* /*
@ -355,8 +356,30 @@ public class MovingListener implements Listener {
final MovingConfig cc = MovingConfig.getConfig(player); final MovingConfig cc = MovingConfig.getConfig(player);
moveInfo.set(player, from, to, cc.yOnGround); moveInfo.set(player, from, to, cc.yOnGround);
final MovingData data = MovingData.getData(player); final MovingData data = MovingData.getData(player);
if (pFrom.isIllegal() || pTo.isIllegal()) {
moveInfo.cleanup();
parkedInfo.add(moveInfo);
CheckUtils.onIllegalMove(player);
if (data.setBack != null){
event.setFrom(data.setBack);
event.setTo(data.setBack);
}
else{
pFrom.set(player.getLocation(), player);
if (!pFrom.isIllegal()){
event.setFrom(pFrom.getLocation());
event.setTo(pFrom.getLocation());
}
else{
NoCheatPlus.denyLogin(player.getName(), 24L*60L*60L*1000L);
CheckUtils.logSevere("[NCP] could not restore location for " + player.getName() + " deny login for 24 hours");
}
pFrom.cleanup();
}
return;
}
data.noFallAssumeGround = false; data.noFallAssumeGround = false;
data.teleported = null; data.teleported = null;

View File

@ -863,6 +863,11 @@ public class BlockProperties {
// return blockId != 0 && net.minecraft.server.Block.byId[blockId].//.c();// d(); // return blockId != 0 && net.minecraft.server.Block.byId[blockId].//.c();// d();
// Bit fat workaround, maybe put the object through from check listener ? // Bit fat workaround, maybe put the object through from check listener ?
pLoc.set(location, player, 0.3); pLoc.set(location, player, 0.3);
if (pLoc.isIllegal()) {
pLoc.cleanup();
CheckUtils.onIllegalMove(player);
return false;
}
final boolean onGround = pLoc.isOnGround(); final boolean onGround = pLoc.isOnGround();
pLoc.cleanup(); pLoc.cleanup();
return onGround; return onGround;

View File

@ -328,4 +328,9 @@ public class CheckUtils {
return Math.max(((LivingEntity) entity).getEyeHeight(), entityHeight); return Math.max(((LivingEntity) entity).getEyeHeight(), entityHeight);
} else return mcEntity.height; } else return mcEntity.height;
} }
public static void onIllegalMove(final Player player){
player.kickPlayer("Illegal move.");
logWarning("[NCP] Disconnect " + player.getName() + " due to illegal move!");
}
} }

View File

@ -37,423 +37,430 @@ import org.bukkit.util.Vector;
* MMMMMMMMMMM * MMMMMMMMMMM
*/ */
/** /**
* An utility class used to know a lot of things for a player and a location given. * An utility class used to know a lot of things for a player and a location
* given.
*/ */
public class PlayerLocation { public class PlayerLocation {
/** Box for one time use, no nesting, no extra storing this(!). */ /** Box for one time use, no nesting, no extra storing this(!). */
protected static final AxisAlignedBB useBox = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); protected static final AxisAlignedBB useBox = AxisAlignedBB.a(0, 0, 0, 0, 0, 0);
/** Type id of the block at the position. */ /** Type id of the block at the position. */
private Integer typeId; private Integer typeId;
/** Type id of the block below. */ /** Type id of the block below. */
private Integer typeIdBelow; private Integer typeIdBelow;
private Integer data; private Integer data;
/** Is the player above stairs? */ /** Is the player above stairs? */
private Boolean aboveStairs; private Boolean aboveStairs;
/** Is the player in lava? */ /** Is the player in lava? */
private Boolean inLava; private Boolean inLava;
/** Is the player in water? */ /** Is the player in water? */
private Boolean inWater; private Boolean inWater;
/** Is the player is web? */ /** Is the player is web? */
private Boolean inWeb; private Boolean inWeb;
/** Is the player on the ground? */ /** Is the player on the ground? */
private Boolean onGround; private Boolean onGround;
/** Is the player on ice? */ /** Is the player on ice? */
private Boolean onIce; private Boolean onIce;
/** Is the player on ladder? */ /** Is the player on ladder? */
private Boolean onLadder; private Boolean onLadder;
/** Simple test if the exact position is passable. */ /** Simple test if the exact position is passable. */
private Boolean passable; private Boolean passable;
/** Y parameter for growing the bounding box with the isOnGround check.*/ /** Y parameter for growing the bounding box with the isOnGround check. */
private double yOnGround = 0.001; private double yOnGround = 0.001;
/** The block coordinates. */ /** The block coordinates. */
private int blockX, blockY, blockZ; private int blockX, blockY, blockZ;
/** The exact coordinates. */ /** The exact coordinates. */
private double x,y,z; private double x, y, z;
private float yaw, pitch; private float yaw, pitch;
// Members that need cleanup: // Members that need cleanup:
/** The entityPlayer player. */ /** The entityPlayer player. */
private EntityPlayer entityPlayer; private EntityPlayer entityPlayer;
/** Bounding box of the player. */ /** Bounding box of the player. */
private double minX, maxX, minY, maxY, minZ, maxZ; private double minX, maxX, minY, maxY, minZ, maxZ;
/** Bukkit world. */ /** Bukkit world. */
private World world; private World world;
/** The worldServer. */ /** The worldServer. */
private WorldServer worldServer; private WorldServer worldServer;
/** Optional block property cache. */ /** Optional block property cache. */
private BlockCache blockCache; private BlockCache blockCache;
/** /**
* Gets the location. * Gets the location.
* *
* @return the location * @return the location
*/ */
public Location getLocation() { public Location getLocation() {
return new Location(world, x, y, z); return new Location(world, x, y, z);
} }
/** /**
* Gets the blockX. * Gets the blockX.
* *
* @return the blockX * @return the blockX
*/ */
public double getX() { public double getX() {
return x; return x;
} }
/** /**
* Gets the boundY. * Gets the boundY.
* *
* @return the boundY * @return the boundY
*/ */
public double getY() { public double getY() {
return y; return y;
} }
/** /**
* Gets the blockZ. * Gets the blockZ.
* *
* @return the blockZ * @return the blockZ
*/ */
public double getZ() { public double getZ() {
return z; return z;
} }
/** /**
* Gets the yaw. * Gets the yaw.
* *
* @return the yaw * @return the yaw
*/ */
public float getYaw() { public float getYaw() {
return yaw; return yaw;
} }
/** /**
* Gets the pitch. * Gets the pitch.
* *
* @return the pitch * @return the pitch
*/ */
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public Vector getVector() { public Vector getVector() {
return new Vector(x, y, z); return new Vector(x, y, z);
} }
public double getWidth(){ public double getWidth() {
return entityPlayer.width; return entityPlayer.width;
} }
public int getBlockX(){ public int getBlockX() {
return blockX; return blockX;
} }
public int getBlockY(){ public int getBlockY() {
return blockY; return blockY;
} }
public int getBlockZ(){ public int getBlockZ() {
return blockZ; return blockZ;
} }
/** /**
* Compares block coordinates (not the world). * Compares block coordinates (not the world).
* @param other *
* @return * @param other
*/ * @return
public final boolean isSameBlock(final PlayerLocation other) { */
return blockX == other.getBlockX() && blockZ == other.getBlockZ() && blockY == other.getBlockY(); public final boolean isSameBlock(final PlayerLocation other) {
} return blockX == other.getBlockX() && blockZ == other.getBlockZ() && blockY == other.getBlockY();
}
/** /**
* Compares exact coordinates (not the world). * Compares exact coordinates (not the world).
* @param loc *
* @return * @param loc
*/ * @return
public boolean isSamePos(final PlayerLocation loc) { */
return x == loc.getX() && z == loc.getZ() && y == loc.getY(); public boolean isSamePos(final PlayerLocation loc) {
} return x == loc.getX() && z == loc.getZ() && y == loc.getY();
}
/** /**
* Compares exact coordinates (not the world). * Compares exact coordinates (not the world).
* @param loc *
* @return * @param loc
*/ * @return
public boolean isSamePos(final Location loc) { */
return x == loc.getX() && z == loc.getZ() && y == loc.getY(); public boolean isSamePos(final Location loc) {
} return x == loc.getX() && z == loc.getZ() && y == loc.getY();
}
/** /**
* Checks if the player is above stairs. * Checks if the player is above stairs.
* *
* @return true, if the player above on stairs * @return true, if the player above on stairs
*/ */
public boolean isAboveStairs() { public boolean isAboveStairs() {
if (aboveStairs == null){ if (aboveStairs == null) {
// aboveStairs = BlockProperties.isStairs(getTypeIdBelow().intValue()); // aboveStairs =
// TODO: maybe distinguish upside down stairs and normal stairs ! // BlockProperties.isStairs(getTypeIdBelow().intValue());
final double diff = getWidth() + 0.001; // TODO: maybe distinguish upside down stairs and normal stairs !
aboveStairs = BlockProperties.collides(getBlockAccess(), x - diff, y + 0.25, z - diff, x + diff, y - 1.0, z + diff, BlockProperties.F_STAIRS); final double diff = getWidth() + 0.001;
} aboveStairs = BlockProperties.collides(getBlockAccess(), x - diff, y + 0.25, z - diff, x + diff, y - 1.0, z + diff, BlockProperties.F_STAIRS);
return aboveStairs; }
} return aboveStairs;
}
/** /**
* Checks if the player is in lava. * Checks if the player is in lava.
* *
* @return true, if the player is in lava * @return true, if the player is in lava
*/ */
public boolean isInLava() { public boolean isInLava() {
if (inLava == null) { if (inLava == null) {
final double dX = -0.10000000149011612D; final double dX = -0.10000000149011612D;
final double dY = -0.40000000596046448D; final double dY = -0.40000000596046448D;
final double dZ = dX; final double dZ = dX;
inLava = BlockProperties.collides(getBlockAccess(), minX - dX, minY - dY, minZ - dZ, maxX + dX, maxY + dY, maxZ + dZ, BlockProperties.F_LAVA); inLava = BlockProperties.collides(getBlockAccess(), minX - dX, minY - dY, minZ - dZ, maxX + dX, maxY + dY, maxZ + dZ, BlockProperties.F_LAVA);
} }
return inLava; return inLava;
} }
/** /**
* Checks if the player is in water. * Checks if the player is in water.
* *
* @return true, if the player is in water * @return true, if the player is in water
*/ */
public boolean isInWater() { public boolean isInWater() {
if (inWater == null) { if (inWater == null) {
final double dX = -0.001D; final double dX = -0.001D;
final double dY = -0.40000000596046448D - 0.001D; final double dY = -0.40000000596046448D - 0.001D;
final double dZ = -0.001D; final double dZ = -0.001D;
inWater = BlockProperties.collides(getBlockAccess(), minX - dX, minY - dY, minZ - dZ, maxX + dX, maxY + dY, maxZ + dZ, BlockProperties.F_WATER); inWater = BlockProperties.collides(getBlockAccess(), minX - dX, minY - dY, minZ - dZ, maxX + dX, maxY + dY, maxZ + dZ, BlockProperties.F_WATER);
} }
return inWater; return inWater;
} }
/** /**
* Checks if the player is in a liquid. * Checks if the player is in a liquid.
* *
* @return true, if the player is in a liquid * @return true, if the player is in a liquid
*/ */
public boolean isInLiquid() { public boolean isInLiquid() {
// TODO: optimize (check liquid first and only if liquid check further) // TODO: optimize (check liquid first and only if liquid check further)
return isInLava() || isInWater(); return isInLava() || isInWater();
} }
/**
* Checks if the player is on ice.
*
* @return true, if the player is on ice
*/
public boolean isOnIce() {
if (onIce == null) {
final org.bukkit.entity.Player entity = this.entityPlayer.getBukkitEntity();
if (entity.isSneaking() || entity.isBlocking()) onIce = getTypeId(blockX, Location.locToBlock(minY - 0.1D), blockZ) == Material.ICE.getId();
else onIce = getTypeIdBelow().intValue() == Material.ICE.getId();
}
return onIce;
}
/** /**
* Checks if the player is on ice. * Checks if the player is on a ladder or vine.
* *
* @return true, if the player is on ice * @return If so.
*/ */
public boolean isOnIce() { public boolean isOnLadder() {
if (onIce == null){ if (onLadder == null) {
final org.bukkit.entity.Player entity = this.entityPlayer.getBukkitEntity(); final int typeId = getTypeId();
if (entity.isSneaking() || entity.isBlocking()) onLadder = typeId == Material.LADDER.getId() || typeId == Material.VINE.getId();
onIce = getTypeId(blockX, Location.locToBlock(minY - 0.1D), blockZ) == Material.ICE.getId(); }
else return onLadder;
onIce = getTypeIdBelow().intValue() == Material.ICE.getId(); }
}
return onIce;
}
/** /**
* Checks if the player is on a ladder or vine. * Checks if the player is above a ladder or vine.<br>
* * Does not save back value to field.
* @return If so. *
*/ * @return If so.
public boolean isOnLadder() { */
if (onLadder == null){ public boolean isAboveLadder() {
final int typeId = getTypeId(); final int typeId = getTypeIdBelow();
onLadder = typeId == Material.LADDER.getId() || typeId == Material.VINE.getId(); return typeId == Material.LADDER.getId() || typeId == Material.VINE.getId();
} }
return onLadder;
}
/** /**
* Checks if the player is above a ladder or vine.<br> * Checks if the player is in web.
* Does not save back value to field. *
* * @return true, if the player is in web
* @return If so. */
*/ public boolean isInWeb() {
public boolean isAboveLadder() { final int webId = Material.WEB.getId();
final int typeId = getTypeIdBelow(); if (inWeb == null) {
return typeId == Material.LADDER.getId() || typeId == Material.VINE.getId(); for (int blockX = Location.locToBlock(minX + 0.001D); blockX <= Location.locToBlock(maxX - 0.001D); blockX++) {
} for (int blockY = Location.locToBlock(minY + 0.001D); blockY <= Location.locToBlock(maxY - 0.001D); blockY++) {
for (int blockZ = Location.locToBlock(minZ + 0.001D); blockZ <= Location.locToBlock(maxZ - 0.001D); blockZ++) {
if (getTypeId(blockX, blockY, blockZ) == webId) {
inWeb = true;
return true;
}
}
}
}
inWeb = false;
}
return inWeb;
}
/** /**
* Checks if the player is in web. * Checks if the player is on ground.
* *
* @return true, if the player is in web * @return true, if the player is on ground
*/ */
public boolean isInWeb() { public boolean isOnGround() {
final int webId = Material.WEB.getId(); if (onGround == null) {
if (inWeb == null) { final double d0 = 0.01D;
for (int blockX = Location.locToBlock(minX + 0.001D); blockX <= Location.locToBlock(maxX - 0.001D); blockX++){ onGround = BlockProperties.isOnGround(getBlockAccess(), minX - d0, minY - yOnGround, minZ - d0, maxX + d0, minY + 0.25, maxZ + d0);
for (int blockY = Location.locToBlock(minY + 0.001D); blockY <= Location.locToBlock(maxY - 0.001D); blockY++){ if (!onGround) {
for (int blockZ = Location.locToBlock(minZ + 0.001D); blockZ <= Location.locToBlock(maxZ - 0.001D); blockZ++){ // TODO: Probably check other ids too before doing this ?
if (getTypeId(blockX, blockY, blockZ) == webId){ final double d1 = 0.25D;
inWeb = true; final AxisAlignedBB box = useBox.b(minX - d1, minY - getyOnGround() - d1, minZ - d1, maxX + d1, minY + 0.25 + d1, maxZ + d1);
return true; @SuppressWarnings("rawtypes")
} final List list = worldServer.getEntities(entityPlayer, box);
} @SuppressWarnings("rawtypes")
} Iterator iterator = list.iterator();
} while (iterator.hasNext()) {
inWeb = false; final Entity entity = (Entity) iterator.next();
} final EntityType type = entity.getBukkitEntity().getType();
return inWeb; if (type != EntityType.BOAT && type != EntityType.MINECART) continue;
} final AxisAlignedBB otherBox = entity.boundingBox;
if (box.a > otherBox.d || box.d < otherBox.a || box.b > otherBox.e || box.e < otherBox.b || box.c > otherBox.f || box.f < otherBox.c) continue;
/** else {
* Checks if the player is on ground. onGround = true;
* break;
* @return true, if the player is on ground }
*/ }
public boolean isOnGround() { }
if (onGround == null) { }
final double d0 = 0.01D; return onGround;
onGround = BlockProperties.isOnGround(getBlockAccess(), minX - d0, minY - yOnGround, minZ - d0, maxX + d0, minY + 0.25, maxZ + d0); }
if (!onGround){
// TODO: Probably check other ids too before doing this ?
final double d1 = 0.25D;
final AxisAlignedBB box = useBox.b(minX - d1, minY - getyOnGround() - d1, minZ - d1, maxX + d1, minY + 0.25 + d1, maxZ + d1);
@SuppressWarnings("rawtypes")
final List list = worldServer.getEntities(entityPlayer, box);
@SuppressWarnings("rawtypes")
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
final Entity entity = (Entity) iterator.next();
final EntityType type = entity.getBukkitEntity().getType();
if (type != EntityType.BOAT && type != EntityType.MINECART) continue;
final AxisAlignedBB otherBox = entity.boundingBox;
if (box.a > otherBox.d || box.d < otherBox.a || box.b > otherBox.e || box.e < otherBox.b || box.c > otherBox.f || box.f < otherBox.c) continue;
else {
onGround = true;
break;
}
}
}
}
return onGround;
}
public double getyOnGround() { public double getyOnGround() {
return yOnGround; return yOnGround;
} }
public void setyOnGround(final double yOnGround) { public void setyOnGround(final double yOnGround) {
this.yOnGround = yOnGround; this.yOnGround = yOnGround;
this.onGround = null; this.onGround = null;
} }
/** /**
* Simple at the spot passability test, no bounding boxes. * Simple at the spot passability test, no bounding boxes.
* @return *
*/ * @return
public boolean isPassable(){ */
if (passable == null) passable = BlockProperties.isPassable(getBlockAccess(), x, y, z, getTypeId()); public boolean isPassable() {
return passable; if (passable == null) passable = BlockProperties.isPassable(getBlockAccess(), x, y, z, getTypeId());
} return passable;
}
/** /**
* Convenience method: delegate to BlockProperties.isDoppwnStream . * Convenience method: delegate to BlockProperties.isDoppwnStream .
* @param xDistance *
* @param zDistance * @param xDistance
* @return * @param zDistance
*/ * @return
public boolean isDownStream(final double xDistance, final double zDistance){ */
return BlockProperties.isDownStream(getBlockAccess(), blockX, blockY, blockZ, getData(), xDistance, zDistance); public boolean isDownStream(final double xDistance, final double zDistance)
} {
return BlockProperties.isDownStream(getBlockAccess(), blockX, blockY, blockZ, getData(), xDistance, zDistance);
}
public Integer getTypeId() { public Integer getTypeId() {
if (typeId == null) typeId = getTypeId(blockX, blockY, blockZ); if (typeId == null) typeId = getTypeId(blockX, blockY, blockZ);
return typeId; return typeId;
} }
public Integer getTypeIdBelow() { public Integer getTypeIdBelow() {
if (typeIdBelow == null) typeIdBelow = getTypeId(blockX, blockY - 1, blockZ); if (typeIdBelow == null) typeIdBelow = getTypeId(blockX, blockY - 1, blockZ);
return typeIdBelow; return typeIdBelow;
} }
public Integer getData(){ public Integer getData() {
if (data == null) data = getData(blockX, blockY, blockZ); if (data == null) data = getData(blockX, blockY, blockZ);
return data; return data;
} }
/** /**
* Uses id cache if present. * Uses id cache if present.
*
* @param x * @param x
* @param y * @param y
* @param z * @param z
* @return * @return
*/ */
public final int getTypeId(final int x, final int y, final int z){ public final int getTypeId(final int x, final int y, final int z) {
return blockCache == null ? worldServer.getTypeId(x, y, z) : blockCache.getTypeId(x, y, z); return blockCache == null ? worldServer.getTypeId(x, y, z) : blockCache.getTypeId(x, y, z);
} }
/** /**
* Uses id cache if present. * Uses id cache if present.
*
* @param x * @param x
* @param y * @param y
* @param z * @param z
* @return * @return
*/ */
public final int getData(final int x, final int y, final int z){ public final int getData(final int x, final int y, final int z) {
return blockCache == null ? worldServer.getData(x, y, z) : blockCache.getData(x, y, z); return blockCache == null ? worldServer.getData(x, y, z) : blockCache.getData(x, y, z);
} }
public WorldServer getWorldServer() { public WorldServer getWorldServer() {
return worldServer; return worldServer;
} }
/** /**
* Set the id cache for faster id getting. * Set the id cache for faster id getting.
* @param cache *
*/ * @param cache
public void setBlockCache(final BlockCache cache) { */
this.blockCache = cache; public void setBlockCache(final BlockCache cache) {
} this.blockCache = cache;
}
/** /**
* *
* @return * @return
*/ */
public final IBlockAccess getBlockAccess() { public final IBlockAccess getBlockAccess() {
return blockCache == null ? worldServer : blockCache; return blockCache == null ? worldServer : blockCache;
} }
/** /**
* Sets the player location object. * Sets the player location object.
* *
* @param location * @param location
* the location * the location
* @param player * @param player
* the player * the player
*/ */
public void set(final Location location, final Player player){ public void set(final Location location, final Player player) {
set(location, player, 0.001); set(location, player, 0.001);
} }
/** /**
* Sets the player location object. Does not set or reset blockCache. * Sets the player location object. Does not set or reset blockCache.
@ -498,19 +505,37 @@ public class PlayerLocation {
typeId = typeIdBelow = data = null; typeId = typeIdBelow = data = null;
aboveStairs = inLava = inWater = inWeb = onGround = onIce = onLadder = passable = null; aboveStairs = inLava = inWater = inWeb = onGround = onIce = onLadder = passable = null;
// TODO: Consider blockCache.setAccess? <- currently rather not, because it might be anything. // TODO: Consider blockCache.setAccess? <- currently rather not, because
// it might be anything.
this.setyOnGround(yFreedom); this.setyOnGround(yFreedom);
} }
/** /**
* Set some references to null. * Set some references to null.
*/ */
public void cleanup(){ public void cleanup() {
entityPlayer = null; entityPlayer = null;
world = null; world = null;
worldServer = null; worldServer = null;
blockCache = null; // No reset here. blockCache = null; // No reset here.
} }
/**
* Attempt to check for some exploits (!).
*
* @return
*/
public boolean isIllegal() {
if (entityPlayer.dead) return false;
if (!entityPlayer.isSleeping()){
// This can not really test stance but height of bounding box.
final double dY = Math.abs(maxY - minY);
if (dY > 1.8) return true; // dY > 1.65D ||
if (dY < 0.1D) return true;
}
if (Math.abs(minX) > 3.2E7D || Math.abs(maxX) > 3.2E7D || Math.abs(minZ) > 3.2E7D || Math.abs(maxZ) > 3.2E7D) return true;
return false;
}
} }