diff --git a/NCPCompatCBDev/src/main/java/fr/neatmonster/nocheatplus/compat/cbdev/BlockCacheCBDev.java b/NCPCompatCBDev/src/main/java/fr/neatmonster/nocheatplus/compat/cbdev/BlockCacheCBDev.java index 0d9820d6..840adc7c 100644 --- a/NCPCompatCBDev/src/main/java/fr/neatmonster/nocheatplus/compat/cbdev/BlockCacheCBDev.java +++ b/NCPCompatCBDev/src/main/java/fr/neatmonster/nocheatplus/compat/cbdev/BlockCacheCBDev.java @@ -17,109 +17,108 @@ import org.bukkit.entity.Entity; import fr.neatmonster.nocheatplus.utilities.BlockCache; public class BlockCacheCBDev extends BlockCache implements IBlockAccess{ - - /** 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 net.minecraft.server.v1_7_R4.WorldServer world; - - public BlockCacheCBDev(World world) { - setAccess(world); - } + /** Box for one time use, no nesting, no extra storing this(!). */ + protected static final AxisAlignedBB useBox = AxisAlignedBB.a(0, 0, 0, 0, 0, 0); - @Override - public void setAccess(World world) { - if (world != null) { - this.maxBlockY = world.getMaxHeight() - 1; - this.world = ((CraftWorld) world).getHandle(); - } else { - this.world = null; - } - } + protected net.minecraft.server.v1_7_R4.WorldServer world; - @Override - public int fetchTypeId(final int x, final int y, final int z) { - return world.getTypeId(x, y, z); - } + public BlockCacheCBDev(World world) { + setAccess(world); + } - @Override - public int fetchData(final int x, final int y, final int z) { - return world.getData(x, y, z); - } + @Override + public void setAccess(World world) { + if (world != null) { + this.maxBlockY = world.getMaxHeight() - 1; + this.world = ((CraftWorld) world).getHandle(); + } else { + this.world = null; + } + } - @Override - public double[] fetchBounds(final int x, final int y, final int z){ - - // TODO: change api for this / use nodes (!) - final int id = getTypeId(x, y, z); - final net.minecraft.server.v1_7_R4.Block block = net.minecraft.server.v1_7_R4.Block.getById(id); - if (block == null) { - return null; - } - block.updateShape(this, x, y, z); // TODO: use THIS instead of world. - - // minX, minY, minZ, maxX, maxY, maxZ - return new double[]{block.x(), block.z(), block.B(), block.y(), block.A(), block.C()}; - } - - @Override - public boolean standsOnEntity(final Entity entity, final double minX, final double minY, final double minZ, final double maxX, final double maxY, final double maxZ){ - try{ - // TODO: Probably check other ids too before doing this ? - - final net.minecraft.server.v1_7_R4.Entity mcEntity = ((CraftEntity) entity).getHandle(); - - final AxisAlignedBB box = useBox.b(minX, minY, minZ, maxX, maxY, maxZ); - @SuppressWarnings("rawtypes") - final List list = world.getEntities(mcEntity, box); - @SuppressWarnings("rawtypes") - final Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - final net.minecraft.server.v1_7_R4.Entity other = (net.minecraft.server.v1_7_R4.Entity) iterator.next(); - if (!(other instanceof EntityBoat)){ // && !(other instanceof EntityMinecart)) continue; - continue; - } - if (minY >= other.locY && minY - other.locY <= 0.7){ - return true; - } - // Still check this for some reason. - final AxisAlignedBB otherBox = other.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 { - return true; - } - } - } - catch (Throwable t){ - // Ignore exceptions (Context: DisguiseCraft). - } - return false; - } - - /* (non-Javadoc) - * @see fr.neatmonster.nocheatplus.utilities.BlockCache#cleanup() - */ - @Override - public void cleanup() { - super.cleanup(); - world = null; - } + @Override + public int fetchTypeId(final int x, final int y, final int z) { + return world.getTypeId(x, y, z); + } - @Override - public TileEntity getTileEntity(final int x, final int y, final int z) { - return world.getTileEntity(x, y, z); - } + @Override + public int fetchData(final int x, final int y, final int z) { + return world.getData(x, y, z); + } - @Override - public int getBlockPower(final int arg0, final int arg1, final int arg2, final int arg3) { - return world.getBlockPower(arg0, arg1, arg2, arg3); - } + @Override + public double[] fetchBounds(final int x, final int y, final int z){ + final int id = getTypeId(x, y, z); + final net.minecraft.server.v1_7_R4.Block block = net.minecraft.server.v1_7_R4.Block.getById(id); + if (block == null) { + // TODO: Convention for null bounds -> full ? + return null; + } + block.updateShape(this, x, y, z); + + // minX, minY, minZ, maxX, maxY, maxZ + return new double[]{block.x(), block.z(), block.B(), block.y(), block.A(), block.C()}; + } + + @Override + public boolean standsOnEntity(final Entity entity, final double minX, final double minY, final double minZ, final double maxX, final double maxY, final double maxZ){ + try{ + // TODO: Find some simplification! + + final net.minecraft.server.v1_7_R4.Entity mcEntity = ((CraftEntity) entity).getHandle(); + + final AxisAlignedBB box = useBox.b(minX, minY, minZ, maxX, maxY, maxZ); + @SuppressWarnings("rawtypes") + final List list = world.getEntities(mcEntity, box); + @SuppressWarnings("rawtypes") + final Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + final net.minecraft.server.v1_7_R4.Entity other = (net.minecraft.server.v1_7_R4.Entity) iterator.next(); + if (!(other instanceof EntityBoat)){ // && !(other instanceof EntityMinecart)) continue; + continue; + } + if (minY >= other.locY && minY - other.locY <= 0.7){ + return true; + } + // Still check this for some reason. + final AxisAlignedBB otherBox = other.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 { + return true; + } + } + } + catch (Throwable t){ + // Ignore exceptions (Context: DisguiseCraft). + } + return false; + } + + /* (non-Javadoc) + * @see fr.neatmonster.nocheatplus.utilities.BlockCache#cleanup() + */ + @Override + public void cleanup() { + super.cleanup(); + world = null; + } + + @Override + public TileEntity getTileEntity(final int x, final int y, final int z) { + return world.getTileEntity(x, y, z); + } + + @Override + public int getBlockPower(final int arg0, final int arg1, final int arg2, final int arg3) { + return world.getBlockPower(arg0, arg1, arg2, arg3); + } + + @Override + public Block getType(int x, int y, int z) { + return world.getType(x, y, z); + } - @Override - public Block getType(int x, int y, int z) { - return world.getType(x, y, z); - } - } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java index d129bda8..ae1a31d2 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java @@ -13,81 +13,77 @@ import fr.neatmonster.nocheatplus.utilities.ds.CoordMap; * */ public abstract class BlockCache { - - // TODO: New concepts (Might switch to material, inspect MC+CB code for reliability and performance of block-ids during runtime). - - private static final int ID_AIR = 0; - - /** - * Convenience method to check if the bounds as returned by getBounds cover a whole block. - * @param bounds Can be null, must have 6 fields. - * @return - */ - public static final boolean isFullBounds(final double[] bounds) { - if (bounds == null) return false; - for (int i = 0; i < 3; i ++) { - if (bounds[i] > 0.0) return false; - if (bounds[i + 3] < 1.0) return false; - } - return true; - } - - /** - * Check if chunks are loaded and load all not yet loaded chunks, using normal world coordinates.
- * NOTE: Not sure where to put this. Method does not use any caching. - * @param world - * @param x - * @param z - * @param xzMargin - * @return Number of loaded chunks. - */ - public static int ensureChunksLoaded(final World world, final double x, final double z, final double xzMargin) { - int loaded = 0; - final int minX = Location.locToBlock(x - xzMargin) / 16; - final int maxX = Location.locToBlock(x + xzMargin) / 16; - final int minZ = Location.locToBlock(z - xzMargin) / 16; - final int maxZ = Location.locToBlock(z + xzMargin) / 16; - for (int cx = minX; cx <= maxX; cx ++) { - for (int cz = minZ; cz <= maxZ; cz ++) { - if (!world.isChunkLoaded(cx, cz)) { - world.loadChunk(cx, cz); - loaded ++; - } - } - } - return loaded; - } - + + // TODO: New concepts (Might switch to material, inspect MC+CB code for reliability and performance of block-ids during runtime). + + private static final int ID_AIR = 0; + + /** + * Convenience method to check if the bounds as returned by getBounds cover a whole block. + * @param bounds Can be null, must have 6 fields. + * @return + */ + public static final boolean isFullBounds(final double[] bounds) { + if (bounds == null) return false; + for (int i = 0; i < 3; i ++) { + if (bounds[i] > 0.0) return false; + if (bounds[i + 3] < 1.0) return false; + } + return true; + } + + /** + * Check if chunks are loaded and load all not yet loaded chunks, using normal world coordinates.
+ * NOTE: Not sure where to put this. Method does not use any caching. + * @param world + * @param x + * @param z + * @param xzMargin + * @return Number of loaded chunks. + */ + public static int ensureChunksLoaded(final World world, final double x, final double z, final double xzMargin) { + int loaded = 0; + final int minX = Location.locToBlock(x - xzMargin) / 16; + final int maxX = Location.locToBlock(x + xzMargin) / 16; + final int minZ = Location.locToBlock(z - xzMargin) / 16; + final int maxZ = Location.locToBlock(z + xzMargin) / 16; + for (int cx = minX; cx <= maxX; cx ++) { + for (int cz = minZ; cz <= maxZ; cz ++) { + if (!world.isChunkLoaded(cx, cz)) { + world.loadChunk(cx, cz); + loaded ++; + } + } + } + return loaded; + } + /** Cached type-ids. */ private final CoordMap idMap = new CoordMap(23); - + /** Cached data values. */ private final CoordMap dataMap = new CoordMap(23); - + /** Cached shape values. */ private final CoordMap boundsMap = new CoordMap(23); - + protected int maxBlockY = 255; - - // TODO: switch to nodes with all details on, store a working node ? - - // TODO: maybe make very fast access arrays for the ray tracing checks. -// private int[] id = null; -// private int[] data = null; - + + // TODO: Switch to nodes with all details on? + public BlockCache() { } - + public BlockCache(final World world) { setAccess(world); } - + /** * Does not do cleanup. * @param world */ public abstract void setAccess(final World world); - + /** * Fetch the type id from the underlying world. * @param x @@ -96,7 +92,7 @@ public abstract class BlockCache { * @return */ public abstract int fetchTypeId(int x, int y, int z); - + /** * Fetch the data from the underlying world. * @param x @@ -104,24 +100,31 @@ public abstract class BlockCache { * @param z * @return */ - public abstract int fetchData(int x, int y, int z); - - public abstract double[] fetchBounds(int x, int y, int z); - - /** - * This is a on-ground type check just for standing on minecarts / boats. - * @param entity - * @param minX - * @param minY - * @param minZ - * @param maxX - * @param maxY - * @param maxZ - * @return - */ - public abstract boolean standsOnEntity(Entity entity, final double minX, final double minY, final double minZ, final double maxX, final double maxY, final double maxZ); + public abstract int fetchData(int x, int y, int z); + + /** + * Find out bounds for the block, this should not return null for performance reasons. + * @param x + * @param y + * @param z + * @return + */ + public abstract double[] fetchBounds(int x, int y, int z); + + /** + * This is a on-ground type check just for standing on minecarts / boats. + * @param entity + * @param minX + * @param minY + * @param minZ + * @param maxX + * @param maxY + * @param maxZ + * @return + */ + public abstract boolean standsOnEntity(Entity entity, final double minX, final double minY, final double minZ, final double maxX, final double maxY, final double maxZ); + - /** * Remove references.
* NOTE: You must delete world references with this one. @@ -131,7 +134,7 @@ public abstract class BlockCache { dataMap.clear(); boundsMap.clear(); } - + /** * (convenience method, uses cache). * @param eX @@ -139,19 +142,19 @@ public abstract class BlockCache { * @param eZ * @return */ - public int getTypeId(double x, double y, double z) { - return getTypeId(Location.locToBlock(x), Location.locToBlock(y), Location.locToBlock(z)); - } - - /** - * (convenience method, uses cache). - * @param block - * @return - */ - public int getTypeId(final Block block) { - return getTypeId(block.getX(), block.getY(), block.getZ()); - } - + public int getTypeId(double x, double y, double z) { + return getTypeId(Location.locToBlock(x), Location.locToBlock(y), Location.locToBlock(z)); + } + + /** + * (convenience method, uses cache). + * @param block + * @return + */ + public int getTypeId(final Block block) { + return getTypeId(block.getX(), block.getY(), block.getZ()); + } + /** * Get type id with cache access. * @param x @@ -159,67 +162,68 @@ public abstract class BlockCache { * @param z * @return */ - public int getTypeId(final int x, final int y, final int z) { - final Integer pId = idMap.get(x, y, z); - if (pId != null) { - return pId; - } - final Integer nId = (y < 0 || y > maxBlockY) ? ID_AIR : fetchTypeId(x, y, z); - idMap.put(x, y, z, nId); - return nId; - } + public int getTypeId(final int x, final int y, final int z) { + final Integer pId = idMap.get(x, y, z); + if (pId != null) { + return pId; + } + final Integer nId = (y < 0 || y > maxBlockY) ? ID_AIR : fetchTypeId(x, y, z); + idMap.put(x, y, z, nId); + return nId; + } + + /** + * Get data value with cache access. + * @param x + * @param y + * @param z + * @return + */ + public int getData(final int x, final int y, final int z) { + final Integer pData = dataMap.get(x, y, z); + if (pData != null) { + return pData; + } + final Integer nData = (y < 0 || y > maxBlockY) ? 0 : fetchData(x, y, z); + dataMap.put(x, y, z, nData); + return nData; + } + + /** + * Get block bounds - Do not change these in-place, because the returned array is cached internally. + * @param x + * @param y + * @param z + * @return Array of floats (minX, minY, minZ, maxX, maxY, maxZ), may be null theoretically. Do not change these in place, because they might get cached. + */ + public double[] getBounds(final int x, final int y, final int z) { + final double[] pBounds = boundsMap.get(x, y, z); + if (pBounds != null) { + return pBounds; + } + // TODO: Convention for null bounds -> full ? + final double[] nBounds = (y < 0 || y > maxBlockY) ? null : fetchBounds(x, y, z); + boundsMap.put(x, y, z, nBounds); + return nBounds; + } + + /** + * Convenience method to check if the bounds for a block cover the full block. + * @param x + * @param y + * @param z + * @return + */ + public boolean isFullBounds(final int x, final int y, final int z) { + return isFullBounds(getBounds(x, y, z)); + } + + /** + * Get the maximal y coordinate a block can be at (non air). + * @return + */ + public int getMaxBlockY() { + return maxBlockY; + } - /** - * Get data value with cache access. - * @param x - * @param y - * @param z - * @return - */ - public int getData(final int x, final int y, final int z) { - final Integer pData = dataMap.get(x, y, z); - if (pData != null) { - return pData; - } - final Integer nData = (y < 0 || y > maxBlockY) ? 0 : fetchData(x, y, z); - dataMap.put(x, y, z, nData); - return nData; - } - - /** - * Get block bounds - Do not change these in-place, because the returned array is cached internally. - * @param x - * @param y - * @param z - * @return Array of floats (minX, minY, minZ, maxX, maxY, maxZ), may be null theoretically. Do not change these in place, because they might get cached. - */ - public double[] getBounds(final int x, final int y, final int z) { - final double[] pBounds = boundsMap.get(x, y, z); - if (pBounds != null) { - return pBounds; - } - final double[] nBounds = (y < 0 || y > maxBlockY) ? null : fetchBounds(x, y, z); - boundsMap.put(x, y, z, nBounds); - return nBounds; - } - - /** - * Convenience method to check if the bounds for a block cover the full block. - * @param x - * @param y - * @param z - * @return - */ - public boolean isFullBounds(final int x, final int y, final int z) { - return isFullBounds(getBounds(x, y, z)); - } - - /** - * Get the maximal y coordinate a block can be at (non air). - * @return - */ - public int getMaxBlockY() { - return maxBlockY; - } - }