mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-12-29 11:57:59 +01:00
Hot fix for bounding box problems.
This commit is contained in:
parent
22f2a5c248
commit
462aeed412
@ -5,6 +5,7 @@ import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||
import fr.neatmonster.nocheatplus.utilities.LagMeasureTask;
|
||||
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.
|
||||
final PlayerLocation location = new PlayerLocation();
|
||||
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
|
||||
// and without blindness effect).
|
||||
|
@ -45,6 +45,7 @@ import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
|
||||
import fr.neatmonster.nocheatplus.permissions.Permissions;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockCache;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockProperties;
|
||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
||||
|
||||
/*
|
||||
@ -355,8 +356,30 @@ public class MovingListener implements Listener {
|
||||
|
||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||
moveInfo.set(player, from, to, cc.yOnGround);
|
||||
|
||||
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.teleported = null;
|
||||
|
||||
|
@ -863,6 +863,11 @@ public class BlockProperties {
|
||||
// return blockId != 0 && net.minecraft.server.Block.byId[blockId].//.c();// d();
|
||||
// Bit fat workaround, maybe put the object through from check listener ?
|
||||
pLoc.set(location, player, 0.3);
|
||||
if (pLoc.isIllegal()) {
|
||||
pLoc.cleanup();
|
||||
CheckUtils.onIllegalMove(player);
|
||||
return false;
|
||||
}
|
||||
final boolean onGround = pLoc.isOnGround();
|
||||
pLoc.cleanup();
|
||||
return onGround;
|
||||
|
@ -328,4 +328,9 @@ public class CheckUtils {
|
||||
return Math.max(((LivingEntity) entity).getEyeHeight(), entityHeight);
|
||||
} else return mcEntity.height;
|
||||
}
|
||||
|
||||
public static void onIllegalMove(final Player player){
|
||||
player.kickPlayer("Illegal move.");
|
||||
logWarning("[NCP] Disconnect " + player.getName() + " due to illegal move!");
|
||||
}
|
||||
}
|
||||
|
@ -37,424 +37,431 @@ import org.bukkit.util.Vector;
|
||||
* 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 {
|
||||
|
||||
|
||||
/** Box for one time use, no nesting, no extra storing this(!). */
|
||||
protected static final AxisAlignedBB useBox = AxisAlignedBB.a(0, 0, 0, 0, 0, 0);
|
||||
|
||||
/** Type id of the block at the position. */
|
||||
private Integer typeId;
|
||||
|
||||
/** Type id of the block below. */
|
||||
private Integer typeIdBelow;
|
||||
|
||||
private Integer data;
|
||||
/** Type id of the block at the position. */
|
||||
private Integer typeId;
|
||||
|
||||
/** Is the player above stairs? */
|
||||
private Boolean aboveStairs;
|
||||
/** Type id of the block below. */
|
||||
private Integer typeIdBelow;
|
||||
|
||||
/** Is the player in lava? */
|
||||
private Boolean inLava;
|
||||
private Integer data;
|
||||
|
||||
/** Is the player in water? */
|
||||
private Boolean inWater;
|
||||
/** Is the player above stairs? */
|
||||
private Boolean aboveStairs;
|
||||
|
||||
/** Is the player is web? */
|
||||
private Boolean inWeb;
|
||||
/** Is the player in lava? */
|
||||
private Boolean inLava;
|
||||
|
||||
/** Is the player on the ground? */
|
||||
private Boolean onGround;
|
||||
/** Is the player in water? */
|
||||
private Boolean inWater;
|
||||
|
||||
/** Is the player on ice? */
|
||||
private Boolean onIce;
|
||||
/** Is the player is web? */
|
||||
private Boolean inWeb;
|
||||
|
||||
/** Is the player on ladder? */
|
||||
private Boolean onLadder;
|
||||
|
||||
/** Simple test if the exact position is passable. */
|
||||
private Boolean passable;
|
||||
|
||||
/** Y parameter for growing the bounding box with the isOnGround check.*/
|
||||
private double yOnGround = 0.001;
|
||||
/** Is the player on the ground? */
|
||||
private Boolean onGround;
|
||||
|
||||
/** The block coordinates. */
|
||||
private int blockX, blockY, blockZ;
|
||||
|
||||
/** The exact coordinates. */
|
||||
private double x,y,z;
|
||||
|
||||
private float yaw, pitch;
|
||||
|
||||
// Members that need cleanup:
|
||||
|
||||
/** The entityPlayer player. */
|
||||
private EntityPlayer entityPlayer;
|
||||
|
||||
/** Bounding box of the player. */
|
||||
private double minX, maxX, minY, maxY, minZ, maxZ;
|
||||
/** Is the player on ice? */
|
||||
private Boolean onIce;
|
||||
|
||||
/** Bukkit world. */
|
||||
private World world;
|
||||
|
||||
/** The worldServer. */
|
||||
private WorldServer worldServer;
|
||||
|
||||
/** Optional block property cache. */
|
||||
private BlockCache blockCache;
|
||||
/** Is the player on ladder? */
|
||||
private Boolean onLadder;
|
||||
|
||||
/**
|
||||
* Gets the location.
|
||||
*
|
||||
* @return the location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
/** Simple test if the exact position is passable. */
|
||||
private Boolean passable;
|
||||
|
||||
/**
|
||||
* Gets the blockX.
|
||||
*
|
||||
* @return the blockX
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
/** Y parameter for growing the bounding box with the isOnGround check. */
|
||||
private double yOnGround = 0.001;
|
||||
|
||||
/**
|
||||
* Gets the boundY.
|
||||
*
|
||||
* @return the boundY
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blockZ.
|
||||
*
|
||||
* @return the blockZ
|
||||
*/
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
/** The block coordinates. */
|
||||
private int blockX, blockY, blockZ;
|
||||
|
||||
/**
|
||||
* Gets the yaw.
|
||||
*
|
||||
* @return the yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pitch.
|
||||
*
|
||||
* @return the pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public Vector getVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
public double getWidth(){
|
||||
return entityPlayer.width;
|
||||
}
|
||||
|
||||
public int getBlockX(){
|
||||
return blockX;
|
||||
}
|
||||
|
||||
public int getBlockY(){
|
||||
return blockY;
|
||||
}
|
||||
|
||||
public int getBlockZ(){
|
||||
return blockZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares block coordinates (not the world).
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public final boolean isSameBlock(final PlayerLocation other) {
|
||||
return blockX == other.getBlockX() && blockZ == other.getBlockZ() && blockY == other.getBlockY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares exact coordinates (not the world).
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean isSamePos(final PlayerLocation loc) {
|
||||
return x == loc.getX() && z == loc.getZ() && y == loc.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares exact coordinates (not the world).
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean isSamePos(final Location loc) {
|
||||
return x == loc.getX() && z == loc.getZ() && y == loc.getY();
|
||||
}
|
||||
/** The exact coordinates. */
|
||||
private double x, y, z;
|
||||
|
||||
/**
|
||||
* Checks if the player is above stairs.
|
||||
*
|
||||
* @return true, if the player above on stairs
|
||||
*/
|
||||
public boolean isAboveStairs() {
|
||||
if (aboveStairs == null){
|
||||
// aboveStairs = BlockProperties.isStairs(getTypeIdBelow().intValue());
|
||||
// TODO: maybe distinguish upside down stairs and normal 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;
|
||||
}
|
||||
private float yaw, pitch;
|
||||
|
||||
/**
|
||||
* Checks if the player is in lava.
|
||||
*
|
||||
* @return true, if the player is in lava
|
||||
*/
|
||||
public boolean isInLava() {
|
||||
if (inLava == null) {
|
||||
final double dX = -0.10000000149011612D;
|
||||
final double dY = -0.40000000596046448D;
|
||||
final double dZ = dX;
|
||||
inLava = BlockProperties.collides(getBlockAccess(), minX - dX, minY - dY, minZ - dZ, maxX + dX, maxY + dY, maxZ + dZ, BlockProperties.F_LAVA);
|
||||
}
|
||||
return inLava;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is in water.
|
||||
*
|
||||
* @return true, if the player is in water
|
||||
*/
|
||||
public boolean isInWater() {
|
||||
if (inWater == null) {
|
||||
final double dX = -0.001D;
|
||||
final double dY = -0.40000000596046448D - 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);
|
||||
}
|
||||
return inWater;
|
||||
}
|
||||
// Members that need cleanup:
|
||||
|
||||
/**
|
||||
* Checks if the player is in a liquid.
|
||||
*
|
||||
* @return true, if the player is in a liquid
|
||||
*/
|
||||
public boolean isInLiquid() {
|
||||
// TODO: optimize (check liquid first and only if liquid check further)
|
||||
return isInLava() || isInWater();
|
||||
}
|
||||
|
||||
/** The entityPlayer player. */
|
||||
private EntityPlayer entityPlayer;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
/** Bounding box of the player. */
|
||||
private double minX, maxX, minY, maxY, minZ, maxZ;
|
||||
|
||||
/**
|
||||
* Checks if the player is on a ladder or vine.
|
||||
*
|
||||
* @return If so.
|
||||
*/
|
||||
public boolean isOnLadder() {
|
||||
if (onLadder == null){
|
||||
final int typeId = getTypeId();
|
||||
onLadder = typeId == Material.LADDER.getId() || typeId == Material.VINE.getId();
|
||||
}
|
||||
return onLadder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is above a ladder or vine.<br>
|
||||
* Does not save back value to field.
|
||||
*
|
||||
* @return If so.
|
||||
*/
|
||||
public boolean isAboveLadder() {
|
||||
final int typeId = getTypeIdBelow();
|
||||
return typeId == Material.LADDER.getId() || typeId == Material.VINE.getId();
|
||||
}
|
||||
/** Bukkit world. */
|
||||
private World world;
|
||||
|
||||
/**
|
||||
* Checks if the player is in web.
|
||||
*
|
||||
* @return true, if the player is in web
|
||||
*/
|
||||
public boolean isInWeb() {
|
||||
final int webId = Material.WEB.getId();
|
||||
if (inWeb == null) {
|
||||
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;
|
||||
}
|
||||
/** The worldServer. */
|
||||
private WorldServer worldServer;
|
||||
|
||||
/**
|
||||
* Checks if the player is on ground.
|
||||
*
|
||||
* @return true, if the player is on ground
|
||||
*/
|
||||
public boolean isOnGround() {
|
||||
if (onGround == null) {
|
||||
final double d0 = 0.01D;
|
||||
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;
|
||||
}
|
||||
/** Optional block property cache. */
|
||||
private BlockCache blockCache;
|
||||
|
||||
/**
|
||||
* Gets the location.
|
||||
*
|
||||
* @return the location
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blockX.
|
||||
*
|
||||
* @return the blockX
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boundY.
|
||||
*
|
||||
* @return the boundY
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blockZ.
|
||||
*
|
||||
* @return the blockZ
|
||||
*/
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the yaw.
|
||||
*
|
||||
* @return the yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pitch.
|
||||
*
|
||||
* @return the pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public Vector getVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
public double getWidth() {
|
||||
return entityPlayer.width;
|
||||
}
|
||||
|
||||
public int getBlockX() {
|
||||
return blockX;
|
||||
}
|
||||
|
||||
public int getBlockY() {
|
||||
return blockY;
|
||||
}
|
||||
|
||||
public int getBlockZ() {
|
||||
return blockZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares block coordinates (not the world).
|
||||
*
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public final boolean isSameBlock(final PlayerLocation other) {
|
||||
return blockX == other.getBlockX() && blockZ == other.getBlockZ() && blockY == other.getBlockY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares exact coordinates (not the world).
|
||||
*
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean isSamePos(final PlayerLocation loc) {
|
||||
return x == loc.getX() && z == loc.getZ() && y == loc.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares exact coordinates (not the world).
|
||||
*
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean isSamePos(final Location loc) {
|
||||
return x == loc.getX() && z == loc.getZ() && y == loc.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is above stairs.
|
||||
*
|
||||
* @return true, if the player above on stairs
|
||||
*/
|
||||
public boolean isAboveStairs() {
|
||||
if (aboveStairs == null) {
|
||||
// aboveStairs =
|
||||
// BlockProperties.isStairs(getTypeIdBelow().intValue());
|
||||
// TODO: maybe distinguish upside down stairs and normal 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is in lava.
|
||||
*
|
||||
* @return true, if the player is in lava
|
||||
*/
|
||||
public boolean isInLava() {
|
||||
if (inLava == null) {
|
||||
final double dX = -0.10000000149011612D;
|
||||
final double dY = -0.40000000596046448D;
|
||||
final double dZ = dX;
|
||||
inLava = BlockProperties.collides(getBlockAccess(), minX - dX, minY - dY, minZ - dZ, maxX + dX, maxY + dY, maxZ + dZ, BlockProperties.F_LAVA);
|
||||
}
|
||||
return inLava;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is in water.
|
||||
*
|
||||
* @return true, if the player is in water
|
||||
*/
|
||||
public boolean isInWater() {
|
||||
if (inWater == null) {
|
||||
final double dX = -0.001D;
|
||||
final double dY = -0.40000000596046448D - 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);
|
||||
}
|
||||
return inWater;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is in a liquid.
|
||||
*
|
||||
* @return true, if the player is in a liquid
|
||||
*/
|
||||
public boolean isInLiquid() {
|
||||
// TODO: optimize (check liquid first and only if liquid check further)
|
||||
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 a ladder or vine.
|
||||
*
|
||||
* @return If so.
|
||||
*/
|
||||
public boolean isOnLadder() {
|
||||
if (onLadder == null) {
|
||||
final int typeId = getTypeId();
|
||||
onLadder = typeId == Material.LADDER.getId() || typeId == Material.VINE.getId();
|
||||
}
|
||||
return onLadder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is above a ladder or vine.<br>
|
||||
* Does not save back value to field.
|
||||
*
|
||||
* @return If so.
|
||||
*/
|
||||
public boolean isAboveLadder() {
|
||||
final int typeId = getTypeIdBelow();
|
||||
return typeId == Material.LADDER.getId() || typeId == Material.VINE.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is in web.
|
||||
*
|
||||
* @return true, if the player is in web
|
||||
*/
|
||||
public boolean isInWeb() {
|
||||
final int webId = Material.WEB.getId();
|
||||
if (inWeb == null) {
|
||||
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 on ground.
|
||||
*
|
||||
* @return true, if the player is on ground
|
||||
*/
|
||||
public boolean isOnGround() {
|
||||
if (onGround == null) {
|
||||
final double d0 = 0.01D;
|
||||
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() {
|
||||
return yOnGround;
|
||||
}
|
||||
return yOnGround;
|
||||
}
|
||||
|
||||
public void setyOnGround(final double yOnGround) {
|
||||
this.yOnGround = yOnGround;
|
||||
this.onGround = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple at the spot passability test, no bounding boxes.
|
||||
* @return
|
||||
*/
|
||||
public boolean isPassable(){
|
||||
if (passable == null) passable = BlockProperties.isPassable(getBlockAccess(), x, y, z, getTypeId());
|
||||
return passable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method: delegate to BlockProperties.isDoppwnStream .
|
||||
* @param xDistance
|
||||
* @param zDistance
|
||||
* @return
|
||||
*/
|
||||
public boolean isDownStream(final double xDistance, final double zDistance){
|
||||
return BlockProperties.isDownStream(getBlockAccess(), blockX, blockY, blockZ, getData(), xDistance, zDistance);
|
||||
}
|
||||
public void setyOnGround(final double yOnGround) {
|
||||
this.yOnGround = yOnGround;
|
||||
this.onGround = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple at the spot passability test, no bounding boxes.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isPassable() {
|
||||
if (passable == null) passable = BlockProperties.isPassable(getBlockAccess(), x, y, z, getTypeId());
|
||||
return passable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method: delegate to BlockProperties.isDoppwnStream .
|
||||
*
|
||||
* @param xDistance
|
||||
* @param zDistance
|
||||
* @return
|
||||
*/
|
||||
public boolean isDownStream(final double xDistance, final double zDistance)
|
||||
{
|
||||
return BlockProperties.isDownStream(getBlockAccess(), blockX, blockY, blockZ, getData(), xDistance, zDistance);
|
||||
}
|
||||
|
||||
public Integer getTypeId() {
|
||||
if (typeId == null) typeId = getTypeId(blockX, blockY, blockZ);
|
||||
return typeId;
|
||||
}
|
||||
|
||||
|
||||
public Integer getTypeIdBelow() {
|
||||
if (typeIdBelow == null) typeIdBelow = getTypeId(blockX, blockY - 1, blockZ);
|
||||
return typeIdBelow;
|
||||
}
|
||||
|
||||
public Integer getData(){
|
||||
if (data == null) data = getData(blockX, blockY, blockZ);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses id cache if present.
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return
|
||||
*/
|
||||
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);
|
||||
|
||||
public Integer getData() {
|
||||
if (data == null) data = getData(blockX, blockY, blockZ);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses id cache if present.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
public WorldServer getWorldServer() {
|
||||
return worldServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id cache for faster id getting.
|
||||
* @param cache
|
||||
*/
|
||||
public void setBlockCache(final BlockCache cache) {
|
||||
this.blockCache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final IBlockAccess getBlockAccess() {
|
||||
return blockCache == null ? worldServer : blockCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player location object.
|
||||
*
|
||||
* @param location
|
||||
* the location
|
||||
* @param player
|
||||
* the player
|
||||
*/
|
||||
public void set(final Location location, final Player player){
|
||||
set(location, player, 0.001);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses id cache if present.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
public WorldServer getWorldServer() {
|
||||
return worldServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id cache for faster id getting.
|
||||
*
|
||||
* @param cache
|
||||
*/
|
||||
public void setBlockCache(final BlockCache cache) {
|
||||
this.blockCache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final IBlockAccess getBlockAccess() {
|
||||
return blockCache == null ? worldServer : blockCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player location object.
|
||||
*
|
||||
* @param location
|
||||
* the location
|
||||
* @param player
|
||||
* the player
|
||||
*/
|
||||
public void set(final Location location, final Player player) {
|
||||
set(location, player, 0.001);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player location object. Does not set or reset blockCache.
|
||||
*
|
||||
@ -498,19 +505,37 @@ public class PlayerLocation {
|
||||
typeId = typeIdBelow = data = 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some references to null.
|
||||
*/
|
||||
public void cleanup(){
|
||||
entityPlayer = null;
|
||||
world = null;
|
||||
worldServer = null;
|
||||
blockCache = null; // No reset here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some references to null.
|
||||
*/
|
||||
public void cleanup() {
|
||||
entityPlayer = null;
|
||||
world = null;
|
||||
worldServer = null;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user