mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-02 13:57:49 +01:00
Add ability to use a cache for block id and data for PlayerLocation.
This commit is contained in:
parent
a5c37a884b
commit
5bf347ca88
@ -86,6 +86,8 @@ public class PlayerLocation {
|
||||
|
||||
/** The worldServer. */
|
||||
private WorldServer worldServer;
|
||||
|
||||
private TypeIdCache idCache;
|
||||
|
||||
/**
|
||||
* Gets the location.
|
||||
@ -215,7 +217,7 @@ public class PlayerLocation {
|
||||
.floor(boundingBox.e - 0.001D); blockY++)
|
||||
for (int blockZ = (int) Math.floor(boundingBox.c + 0.001D); blockZ <= (int) Math
|
||||
.floor(boundingBox.f - 0.001D); blockZ++)
|
||||
if (worldServer.getTypeId(blockX, blockY, blockZ) == Material.WEB.getId())
|
||||
if (getTypeId(blockX, blockY, blockZ) == Material.WEB.getId())
|
||||
inWeb = true;
|
||||
if (inWeb == null)
|
||||
inWeb = false;
|
||||
@ -254,7 +256,7 @@ public class PlayerLocation {
|
||||
public boolean isOnIce() {
|
||||
if (onIce == null)
|
||||
if (entity.getBukkitEntity().isSneaking() || entity.getBukkitEntity().isBlocking())
|
||||
onIce = worldServer.getTypeId(blockX, (int) Math.floor(boundingBox.b - 0.1D), blockZ) == Material.ICE.getId();
|
||||
onIce = getTypeId(blockX, (int) Math.floor(boundingBox.b - 0.1D), blockZ) == Material.ICE.getId();
|
||||
else
|
||||
onIce = getTypeIdBelow() == Material.ICE.getId();
|
||||
return onIce;
|
||||
@ -336,18 +338,18 @@ public class PlayerLocation {
|
||||
}
|
||||
|
||||
public Integer getTypeId() {
|
||||
if (typeId == null) typeId = worldServer.getTypeId(blockX, blockY, blockZ);
|
||||
if (typeId == null) typeId = getTypeId(blockX, blockY, blockZ);
|
||||
return typeId;
|
||||
}
|
||||
|
||||
|
||||
public Integer getTypeIdBelow() {
|
||||
if (typeIdBelow == null) typeIdBelow = worldServer.getTypeId(blockX, blockY - 1, blockZ);
|
||||
if (typeIdBelow == null) typeIdBelow = getTypeId(blockX, blockY - 1, blockZ);
|
||||
return typeIdBelow;
|
||||
}
|
||||
|
||||
public Integer getData(){
|
||||
if (data == null) data = worldServer.getData(blockX, blockY, blockZ);
|
||||
if (data == null) data = getData(blockX, blockY, blockZ);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -358,36 +360,36 @@ public class PlayerLocation {
|
||||
if ((fromData & 0x8) == 0){
|
||||
// not falling.
|
||||
if ((xDistance > 0)){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(worldServer.getTypeId(blockX + 1, blockY, blockZ)) && worldServer.getData(blockX + 1, blockY, blockZ) > fromData){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(getTypeId(blockX + 1, blockY, blockZ)) && getData(blockX + 1, blockY, blockZ) > fromData){
|
||||
return true;
|
||||
}
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(worldServer.getTypeId(blockX - 1, blockY, blockZ)) && worldServer.getData(blockX - 1, blockY, blockZ) < fromData){
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(getTypeId(blockX - 1, blockY, blockZ)) && getData(blockX - 1, blockY, blockZ) < fromData){
|
||||
// reverse direction.
|
||||
return true;
|
||||
}
|
||||
} else if (xDistance < 0){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(worldServer.getTypeId(blockX - 1, blockY, blockZ)) && worldServer.getData(blockX - 1, blockY, blockZ) > fromData){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(getTypeId(blockX - 1, blockY, blockZ)) && getData(blockX - 1, blockY, blockZ) > fromData){
|
||||
return true;
|
||||
}
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(worldServer.getTypeId(blockX + 1, blockY, blockZ)) && worldServer.getData(blockX + 1, blockY, blockZ) < fromData){
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(getTypeId(blockX + 1, blockY, blockZ)) && getData(blockX + 1, blockY, blockZ) < fromData){
|
||||
// reverse direction.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (zDistance > 0){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(worldServer.getTypeId(blockX, blockY, blockZ + 1)) && worldServer.getData(blockX, blockY, blockZ + 1) > fromData){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(getTypeId(blockX, blockY, blockZ + 1)) && getData(blockX, blockY, blockZ + 1) > fromData){
|
||||
return true;
|
||||
}
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(worldServer.getTypeId(blockX , blockY, blockZ - 1)) && worldServer.getData(blockX, blockY, blockZ - 1) < fromData){
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(getTypeId(blockX , blockY, blockZ - 1)) && getData(blockX, blockY, blockZ - 1) < fromData){
|
||||
// reverse direction.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (zDistance < 0 ){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(worldServer.getTypeId(blockX, blockY, blockZ - 1)) && worldServer.getData(blockX, blockY, blockZ - 1) > fromData){
|
||||
if (fromData < 7 && BlockProperties.isLiquid(getTypeId(blockX, blockY, blockZ - 1)) && getData(blockX, blockY, blockZ - 1) > fromData){
|
||||
return true;
|
||||
}
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(worldServer.getTypeId(blockX , blockY, blockZ + 1)) && worldServer.getData(blockX, blockY, blockZ + 1) < fromData){
|
||||
else if (fromData > 0 && BlockProperties.isLiquid(getTypeId(blockX , blockY, blockZ + 1)) && getData(blockX, blockY, blockZ + 1) < fromData){
|
||||
// reverse direction.
|
||||
return true;
|
||||
}
|
||||
@ -400,7 +402,29 @@ public class PlayerLocation {
|
||||
// Maybe make block coordinate fields later.
|
||||
return blockX == other.getBlockX() && blockZ == other.getBlockZ() && blockY == other.getBlockY();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 idCache == null ? worldServer.getTypeId(x, y, z) : idCache.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 idCache == null ? worldServer.getData(x, y, z) : idCache.getData(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: temp maybe
|
||||
* @return
|
||||
@ -409,6 +433,14 @@ public class PlayerLocation {
|
||||
return worldServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id cache for faster id getting.
|
||||
* @param cache
|
||||
*/
|
||||
public void setIdCache(final TypeIdCache cache) {
|
||||
this.idCache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some references to null.
|
||||
*/
|
||||
|
136
src/fr/neatmonster/nocheatplus/utilities/TypeIdCache.java
Normal file
136
src/fr/neatmonster/nocheatplus/utilities/TypeIdCache.java
Normal file
@ -0,0 +1,136 @@
|
||||
package fr.neatmonster.nocheatplus.utilities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.server.IBlockAccess;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
/**
|
||||
* Access to type-ids using caching techniques.
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public class TypeIdCache {
|
||||
/**
|
||||
* TODO: Make a map for faster queries (without object creation).
|
||||
* TODO: Not sure the prime numbers are too big for normal use.
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
private static class Pos3D{
|
||||
private static final int p1 = 73856093;
|
||||
private static final int p2 = 19349663;
|
||||
private static final int p3 = 83492791;
|
||||
// Cube coordinates:
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final int hash;
|
||||
/**
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param size
|
||||
*/
|
||||
public Pos3D (final int x, final int y, final int z){
|
||||
// Cube related coordinates:
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
// Hash
|
||||
hash = getHash(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(final Object obj) {
|
||||
if (obj instanceof Pos3D){
|
||||
final Pos3D other = (Pos3D) obj;
|
||||
return other.x == x && other.y == y && other.z == z;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static final int getHash(final int x, final int y, final int z) {
|
||||
return p1 * x ^ p2 * y ^ p3 * z;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For getting ids.
|
||||
*/
|
||||
private IBlockAccess access = null;
|
||||
/** Cached type-ids. */
|
||||
private final Map<Pos3D, Integer> idMap = new HashMap<Pos3D, Integer>();
|
||||
/** Cahced data values. */
|
||||
private final Map<Pos3D, Integer> dataMap = new HashMap<Pos3D, Integer>();
|
||||
|
||||
// TODO: maybe make very fast access arrays for the ray tracing checks.
|
||||
// private int[] id = null;
|
||||
// private int[] data = null;
|
||||
|
||||
public TypeIdCache(){
|
||||
}
|
||||
|
||||
public TypeIdCache(final World world){
|
||||
setAccess(world);
|
||||
}
|
||||
|
||||
public TypeIdCache(final IBlockAccess access){
|
||||
setAccess(access);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not do cleanup.
|
||||
* @param world
|
||||
*/
|
||||
public void setAccess(final World world){
|
||||
setAccess(((CraftWorld) world).getHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Does not do cleanup.
|
||||
* @param access
|
||||
*/
|
||||
public void setAccess(final IBlockAccess access){
|
||||
this.access = access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove references.
|
||||
*/
|
||||
public void cleanup(){
|
||||
access = null;
|
||||
idMap.clear();
|
||||
dataMap.clear();
|
||||
}
|
||||
|
||||
|
||||
public Integer getTypeId(final int x, final int y, final int z){
|
||||
final Pos3D pos = new Pos3D(x, y, z);
|
||||
final Integer pId = idMap.get(pos);
|
||||
if (pId != null) return pId;
|
||||
final Integer nId = access.getTypeId(x, y, z);
|
||||
idMap.put(pos, nId);
|
||||
return nId;
|
||||
}
|
||||
|
||||
public Integer getData(final int x, final int y, final int z){
|
||||
final Pos3D pos = new Pos3D(x, y, z);
|
||||
final Integer pData = dataMap.get(pos);
|
||||
if (pData != null) return pData;
|
||||
final Integer nData = access.getData(x, y, z);
|
||||
dataMap.put(pos, nData);
|
||||
return nData;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user