mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-04 23:07:44 +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. */
|
/** The worldServer. */
|
||||||
private WorldServer worldServer;
|
private WorldServer worldServer;
|
||||||
|
|
||||||
|
private TypeIdCache idCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the location.
|
* Gets the location.
|
||||||
@ -215,7 +217,7 @@ public class PlayerLocation {
|
|||||||
.floor(boundingBox.e - 0.001D); blockY++)
|
.floor(boundingBox.e - 0.001D); blockY++)
|
||||||
for (int blockZ = (int) Math.floor(boundingBox.c + 0.001D); blockZ <= (int) Math
|
for (int blockZ = (int) Math.floor(boundingBox.c + 0.001D); blockZ <= (int) Math
|
||||||
.floor(boundingBox.f - 0.001D); blockZ++)
|
.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;
|
inWeb = true;
|
||||||
if (inWeb == null)
|
if (inWeb == null)
|
||||||
inWeb = false;
|
inWeb = false;
|
||||||
@ -254,7 +256,7 @@ public class PlayerLocation {
|
|||||||
public boolean isOnIce() {
|
public boolean isOnIce() {
|
||||||
if (onIce == null)
|
if (onIce == null)
|
||||||
if (entity.getBukkitEntity().isSneaking() || entity.getBukkitEntity().isBlocking())
|
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
|
else
|
||||||
onIce = getTypeIdBelow() == Material.ICE.getId();
|
onIce = getTypeIdBelow() == Material.ICE.getId();
|
||||||
return onIce;
|
return onIce;
|
||||||
@ -336,18 +338,18 @@ public class PlayerLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Integer getTypeId() {
|
public Integer getTypeId() {
|
||||||
if (typeId == null) typeId = worldServer.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 = worldServer.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 = worldServer.getData(blockX, blockY, blockZ);
|
if (data == null) data = getData(blockX, blockY, blockZ);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,36 +360,36 @@ public class PlayerLocation {
|
|||||||
if ((fromData & 0x8) == 0){
|
if ((fromData & 0x8) == 0){
|
||||||
// not falling.
|
// not falling.
|
||||||
if ((xDistance > 0)){
|
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;
|
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.
|
// reverse direction.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (xDistance < 0){
|
} 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;
|
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.
|
// reverse direction.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (zDistance > 0){
|
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;
|
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.
|
// reverse direction.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (zDistance < 0 ){
|
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;
|
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.
|
// reverse direction.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -400,7 +402,29 @@ public class PlayerLocation {
|
|||||||
// Maybe make block coordinate fields later.
|
// Maybe make block coordinate fields later.
|
||||||
return blockX == other.getBlockX() && blockZ == other.getBlockZ() && blockY == other.getBlockY();
|
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
|
* TODO: temp maybe
|
||||||
* @return
|
* @return
|
||||||
@ -409,6 +433,14 @@ public class PlayerLocation {
|
|||||||
return worldServer;
|
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.
|
* 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