mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-06-26 06:14:42 +02:00
CompatCBReflect: block shape fetching for MC 1.9 and 1.10.
Worked on the first run :p, still took too long.
This commit is contained in:
parent
ea4108b22a
commit
db945a7559
|
@ -50,7 +50,7 @@ public class MCAccessCBReflect extends MCAccessBukkitBase {
|
|||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.INIT, "The Minecraft version seems to be older than what Compat-CB-Reflect can support.");
|
||||
this.knownSupportedVersion = false;
|
||||
}
|
||||
else if (GenericVersion.compareVersions(mcVersion, "1.9") >= 0) {
|
||||
else if (GenericVersion.compareVersions(mcVersion, "1.10") > 0) {
|
||||
this.knownSupportedVersion = false;
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.INIT, "The Minecraft version seems to be more recent than the one Compat-CB-Reflect has been built with - this might work, but there could be incompatibilities.");
|
||||
} else {
|
||||
|
@ -68,7 +68,7 @@ public class MCAccessCBReflect extends MCAccessBukkitBase {
|
|||
@Override
|
||||
public String getMCVersion() {
|
||||
// Potentially all :p.
|
||||
return "1.4.5-1.8.8|?";
|
||||
return "1.4.5-1.10|?";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
/**
|
||||
* Reflection based block bounds fetching.
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public interface IReflectBlock {
|
||||
|
||||
/**
|
||||
* Static method: Get the block by id.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public Object nms_getById(int id);
|
||||
|
||||
/**
|
||||
* Get the material for a Block instance.
|
||||
*
|
||||
* @param block
|
||||
* @return
|
||||
*/
|
||||
public Object nms_getMaterial(Object block);
|
||||
|
||||
/**
|
||||
* Fetch bounds for a block instance (minX, minY, minZ, maxX, maxY, maxZ).
|
||||
*
|
||||
* @param nmsWorld
|
||||
* @param nmsBlock
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return
|
||||
*/
|
||||
public double[] nms_fetchBounds(final Object nmsWorld, final Object nmsBlock,
|
||||
final int x, final int y, final int z);
|
||||
|
||||
/**
|
||||
* Indicate if nms_fetchBounds could work.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFetchBoundsAvailable();
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import fr.neatmonster.nocheatplus.compat.cbreflect.reflect.ReflectHelper.ReflectFailureException;
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
import fr.neatmonster.nocheatplus.utilities.Validate;
|
||||
|
||||
/**
|
||||
* AxisAlignedBB (nms).
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class ReflectAxisAlignedBB {
|
||||
|
||||
public final Class<?> nmsClass;
|
||||
|
||||
|
||||
public final Field nms_minX;
|
||||
public final Field nms_minY;
|
||||
public final Field nms_minZ;
|
||||
public final Field nms_maxX;
|
||||
public final Field nms_maxY;
|
||||
public final Field nms_maxZ;
|
||||
|
||||
/**
|
||||
* @param base
|
||||
* @throws ClassNotFoundException
|
||||
* @throws NullPointerException
|
||||
* if not available.
|
||||
*/
|
||||
public ReflectAxisAlignedBB(ReflectBase base) throws ClassNotFoundException {
|
||||
nmsClass = Class.forName(base.nmsPackageName + ".AxisAlignedBB");
|
||||
nms_minX = ReflectionUtil.getField(nmsClass, "a", double.class);
|
||||
nms_minY = ReflectionUtil.getField(nmsClass, "b", double.class);
|
||||
nms_minZ = ReflectionUtil.getField(nmsClass, "c", double.class);
|
||||
nms_maxX = ReflectionUtil.getField(nmsClass, "d", double.class);
|
||||
nms_maxY = ReflectionUtil.getField(nmsClass, "e", double.class);
|
||||
nms_maxZ = ReflectionUtil.getField(nmsClass, "f", double.class);
|
||||
Validate.validateNotNull(nms_minX, nms_minY, nms_minZ, nms_maxX, nms_maxY, nms_maxZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in all six values into the given array (order: minY, minY, minZ,
|
||||
* maxX, maxY, maxZ).
|
||||
*
|
||||
* @param aabb
|
||||
* @param arr
|
||||
* @return The given array.
|
||||
*/
|
||||
public double[] fillInValues(final Object aabb, final double[] arr) {
|
||||
try {
|
||||
arr[0] = nms_minX.getDouble(aabb);
|
||||
arr[1] = nms_minY.getDouble(aabb);
|
||||
arr[2] = nms_minZ.getDouble(aabb);
|
||||
arr[3] = nms_maxX.getDouble(aabb);
|
||||
arr[4] = nms_maxY.getDouble(aabb);
|
||||
arr[5] = nms_maxZ.getDouble(aabb);
|
||||
return arr;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import fr.neatmonster.nocheatplus.compat.cbreflect.reflect.ReflectHelper.ReflectFailureException;
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* Reflection for block shape getting (latest).
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class ReflectBlock implements IReflectBlock {
|
||||
|
||||
/** Block class. */
|
||||
public final Class<?> nmsClass;
|
||||
|
||||
// Reference.
|
||||
private final ReflectBlockPosition reflectBlockPosition;
|
||||
private final ReflectAxisAlignedBB reflectAxisAlignedBB;
|
||||
private final ReflectIBlockData reflectIBlockData;
|
||||
private final ReflectWorld reflectWorld;
|
||||
|
||||
// Static.
|
||||
public final Method nmsGetById;
|
||||
|
||||
// Instance.
|
||||
public final Method nmsGetBlockData;
|
||||
/** Not the original name. */
|
||||
public final Method nmsFetchAABB;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param base
|
||||
* @param reflectBlockPosition
|
||||
* @throws ClassNotFoundException
|
||||
* @throws ReflectFailureException If not available.
|
||||
*/
|
||||
public ReflectBlock(ReflectBase base, ReflectBlockPosition reflectBlockPosition,
|
||||
ReflectMaterial reflectMaterial, ReflectWorld reflectWorld) throws ClassNotFoundException {
|
||||
// Reference.
|
||||
this.reflectBlockPosition = reflectBlockPosition;
|
||||
if (reflectBlockPosition.new_nmsBlockPosition == null) {
|
||||
fail();
|
||||
}
|
||||
this.reflectAxisAlignedBB = new ReflectAxisAlignedBB(base); // Fails if not available.
|
||||
this.reflectIBlockData = new ReflectIBlockData(base, reflectMaterial); // Fails if not available.
|
||||
this.reflectWorld = reflectWorld;
|
||||
if (reflectWorld.nmsClass == null || reflectWorld.nmsGetType == null) {
|
||||
fail();
|
||||
}
|
||||
ReflectIBlockAccess reflectIBlockAccess = new ReflectIBlockAccess(base);
|
||||
// Block.
|
||||
nmsClass = Class.forName(base.nmsPackageName + ".Block");
|
||||
// byID (static)
|
||||
nmsGetById = ReflectionUtil.getMethod(nmsClass, "getById", int.class);
|
||||
if (nmsGetById == null) {
|
||||
fail();
|
||||
}
|
||||
// Instance.
|
||||
this.nmsGetBlockData = ReflectionUtil.getMethodNoArgs(nmsClass, "getBlockData", reflectIBlockData.nmsClass);
|
||||
if (this.nmsGetBlockData == null) {
|
||||
fail();
|
||||
}
|
||||
// TODO: a(IBlockData, IBlockAccess, BlockPosition) is deprecated (why / what else?).
|
||||
this.nmsFetchAABB = ReflectionUtil.getMethod(nmsClass, "a",
|
||||
reflectIBlockData.nmsClass, reflectIBlockAccess.nmsClass, reflectBlockPosition.nmsClass);
|
||||
if (nmsFetchAABB == null || nmsFetchAABB.getReturnType() != reflectAxisAlignedBB.nmsClass) {
|
||||
fail();
|
||||
}
|
||||
if (!nmsFetchAABB.isAnnotationPresent(Deprecated.class)) {
|
||||
// The final frontier.
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick fail with exception.
|
||||
*/
|
||||
private void fail() {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
|
||||
private Object nmsBlockPosition(final int x, final int y, final int z) {
|
||||
final Object blockPos = ReflectionUtil.newInstance(this.reflectBlockPosition.new_nmsBlockPosition, x, y, z);
|
||||
if (blockPos == null) {
|
||||
fail();
|
||||
}
|
||||
return blockPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nms_getById(final int id) {
|
||||
if (this.nmsGetById == null) {
|
||||
fail();
|
||||
}
|
||||
return ReflectionUtil.invokeMethod(this.nmsGetById, null, id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param block
|
||||
* Instance of Block.
|
||||
* @return
|
||||
*/
|
||||
private Object nms_getBlockData(final Object block) {
|
||||
try {
|
||||
return nmsGetBlockData.invoke(block);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nms_getMaterial(final Object block) {
|
||||
return reflectIBlockData.nms_getMaterial(nms_getBlockData(block));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] nms_fetchBounds(final Object nmsWorld, final Object nmsBlock,
|
||||
final int x, final int y, final int z) {
|
||||
final Object pos = nmsBlockPosition(x, y, z);
|
||||
final Object blockData = reflectWorld.nms_getType(nmsWorld, pos);
|
||||
// TODO: a(IBlockData, IBlockAccess, BlockPosition) is deprecated (why / what else?).
|
||||
final Object bb = nms_fetchAABB(nmsBlock, blockData, nmsWorld, pos);
|
||||
if (bb == null) {
|
||||
return new double[] {0.0, 0.0, 0.0, 1.0, 1.0, 1.0}; // Special case.
|
||||
//return null;
|
||||
}
|
||||
return reflectAxisAlignedBB.fillInValues(bb, new double[6]);
|
||||
}
|
||||
|
||||
private Object nms_fetchAABB(final Object nmsBlock, final Object iBlockData, final Object iBlockAccess, final Object blockPosition) {
|
||||
try {
|
||||
return nmsFetchAABB.invoke(nmsBlock, iBlockData, iBlockAccess, blockPosition);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFetchBoundsAvailable() {
|
||||
// Available, if initialized at all.
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ import java.util.Comparator;
|
|||
import java.util.List;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
import fr.neatmonster.nocheatplus.compat.cbreflect.reflect.ReflectHelper.ReflectFailureException;
|
||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||
import fr.neatmonster.nocheatplus.logging.Streams;
|
||||
|
@ -35,11 +36,11 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
|||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class ReflectBlockSix {
|
||||
|
||||
public class ReflectBlockSix implements IReflectBlock {
|
||||
|
||||
/** Obfuscated nms names, allowing to find the order in the source code under certain circumstances. */
|
||||
private static final List<String> possibleNames = new ArrayList<String>();
|
||||
|
||||
|
||||
static {
|
||||
// These might suffice for a while.
|
||||
for (char c : "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) {
|
||||
|
@ -47,11 +48,16 @@ public class ReflectBlockSix {
|
|||
}
|
||||
}
|
||||
|
||||
// Reference.
|
||||
private final ReflectBlockPosition reflectBlockPosition;
|
||||
|
||||
/** (static) */
|
||||
public final Method nmsGetById;
|
||||
|
||||
public final Method nmsGetMaterial;
|
||||
public final boolean useBlockPosition;
|
||||
|
||||
|
||||
public final Method nmsUpdateShape;
|
||||
// Block bounds in the order the methods (used to) appear in the nms class.
|
||||
/** If this is null, all other nmsGetMin/Max... methods are null too. */
|
||||
|
@ -62,7 +68,8 @@ public class ReflectBlockSix {
|
|||
public final Method nmsGetMinZ;
|
||||
public final Method nmsGetMaxZ;
|
||||
|
||||
public ReflectBlockSix(ReflectBase base, ReflectBlockPosition blockPosition) throws ClassNotFoundException {
|
||||
public ReflectBlockSix(ReflectBase base, ReflectBlockPosition reflectBlockPosition) throws ClassNotFoundException {
|
||||
this.reflectBlockPosition = reflectBlockPosition;
|
||||
final Class<?> clazz = Class.forName(base.nmsPackageName + ".Block");
|
||||
// byID (static)
|
||||
nmsGetById = ReflectionUtil.getMethod(clazz, "getById", int.class);
|
||||
|
@ -71,8 +78,8 @@ public class ReflectBlockSix {
|
|||
// updateShape
|
||||
Method method = null;
|
||||
Class<?> clazzIBlockAccess = Class.forName(base.nmsPackageName + ".IBlockAccess");
|
||||
if (blockPosition != null) {
|
||||
method = ReflectionUtil.getMethod(clazz, "updateShape", clazzIBlockAccess, blockPosition.nmsClass);
|
||||
if (reflectBlockPosition != null) {
|
||||
method = ReflectionUtil.getMethod(clazz, "updateShape", clazzIBlockAccess, reflectBlockPosition.nmsClass);
|
||||
}
|
||||
if (method == null) {
|
||||
method = ReflectionUtil.getMethod(clazz, "updateShape", clazzIBlockAccess, int.class, int.class, int.class);
|
||||
|
@ -185,4 +192,70 @@ public class ReflectBlockSix {
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick fail with exception.
|
||||
*/
|
||||
private void fail() {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
|
||||
private Object nmsBlockPosition(final int x, final int y, final int z) {
|
||||
if (!this.useBlockPosition || this.reflectBlockPosition.new_nmsBlockPosition == null) {
|
||||
fail();
|
||||
}
|
||||
Object blockPos = ReflectionUtil.newInstance(this.reflectBlockPosition.new_nmsBlockPosition, x, y, z);
|
||||
if (blockPos == null) {
|
||||
fail();
|
||||
}
|
||||
return blockPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nms_getById(final int id) {
|
||||
if (this.nmsGetById == null) {
|
||||
fail();
|
||||
}
|
||||
return ReflectionUtil.invokeMethod(this.nmsGetById, null, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nms_getMaterial(final Object block) {
|
||||
if (this.nmsGetMaterial == null) {
|
||||
fail();
|
||||
}
|
||||
return ReflectionUtil.invokeMethodNoArgs(this.nmsGetMaterial, block);
|
||||
}
|
||||
|
||||
public void nms_updateShape(final Object block, final Object iBlockAccess,
|
||||
final int x, final int y, final int z) {
|
||||
if (this.nmsUpdateShape == null) {
|
||||
fail();
|
||||
}
|
||||
if (this.useBlockPosition) {
|
||||
ReflectionUtil.invokeMethod(this.nmsUpdateShape, block, iBlockAccess, nmsBlockPosition(x, y, z));
|
||||
} else {
|
||||
ReflectionUtil.invokeMethod(this.nmsUpdateShape, block, iBlockAccess, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] nms_fetchBounds(final Object nmsWorld, final Object nmsBlock,
|
||||
final int x, final int y, final int z) {
|
||||
nms_updateShape(nmsBlock, nmsWorld, x, y, z);
|
||||
// TODO: The methods could return null [better try-catch here].
|
||||
return new double[] {
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.nmsGetMinX, nmsBlock)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.nmsGetMinY, nmsBlock)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.nmsGetMinZ, nmsBlock)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.nmsGetMaxX, nmsBlock)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.nmsGetMaxY, nmsBlock)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.nmsGetMaxZ, nmsBlock)).doubleValue(),
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFetchBoundsAvailable() {
|
||||
return nmsGetById != null && nmsUpdateShape != null && nmsGetMinX != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class ReflectHelper {
|
|||
protected final ReflectBase reflectBase;
|
||||
|
||||
protected final ReflectBlockPosition reflectBlockPosition;
|
||||
protected final ReflectBlockSix reflectBlock;
|
||||
protected final IReflectBlock reflectBlock;
|
||||
protected final ReflectMaterial reflectMaterial;
|
||||
protected final ReflectWorld reflectWorld;
|
||||
|
||||
|
@ -80,9 +80,20 @@ public class ReflectHelper {
|
|||
}
|
||||
catch (ClassNotFoundException ex) {}
|
||||
this.reflectBlockPosition = reflectBlockPosition;
|
||||
this.reflectBlock = new ReflectBlockSix(this.reflectBase, this.reflectBlockPosition);
|
||||
this.reflectMaterial = new ReflectMaterial(this.reflectBase);
|
||||
this.reflectWorld = new ReflectWorld(this.reflectBase);
|
||||
this.reflectWorld = new ReflectWorld(reflectBase, reflectMaterial, reflectBlockPosition);
|
||||
ReflectBlock reflectBlockLatest = null;
|
||||
try {
|
||||
reflectBlockLatest = new ReflectBlock(this.reflectBase, this.reflectBlockPosition,
|
||||
reflectMaterial, reflectWorld);
|
||||
} catch (Throwable t) {}
|
||||
if (reflectBlockLatest == null) {
|
||||
// More lenient constructor.
|
||||
this.reflectBlock = new ReflectBlockSix(this.reflectBase, this.reflectBlockPosition);
|
||||
}
|
||||
else {
|
||||
this.reflectBlock = reflectBlockLatest;
|
||||
}
|
||||
|
||||
this.reflectDamageSource = new ReflectDamageSource(this.reflectBase);
|
||||
this.reflectEntity = new ReflectEntityDamage(this.reflectBase, this.reflectDamageSource);
|
||||
|
@ -116,6 +127,9 @@ public class ReflectHelper {
|
|||
rootField.setAccessible(false);
|
||||
}
|
||||
}
|
||||
if (!reflectBlock.isFetchBoundsAvailable()) {
|
||||
parts.add("fetch-block-shape");
|
||||
}
|
||||
if (!parts.isEmpty()) {
|
||||
parts.add(0, "CompatCBReflect: The following properties could not be set:");
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.INIT, StringUtil.join(parts, "\n"));
|
||||
|
@ -231,7 +245,7 @@ public class ReflectHelper {
|
|||
}
|
||||
|
||||
public Object nmsBlockPosition(int x, int y, int z) {
|
||||
if (!this.reflectBlock.useBlockPosition || this.reflectBlockPosition.new_nmsBlockPosition == null) {
|
||||
if (this.reflectBlockPosition.new_nmsBlockPosition == null) {
|
||||
fail();
|
||||
}
|
||||
Object blockPos = ReflectionUtil.newInstance(this.reflectBlockPosition.new_nmsBlockPosition, x, y, z);
|
||||
|
@ -247,28 +261,17 @@ public class ReflectHelper {
|
|||
* @return Block instance (could be null).
|
||||
*/
|
||||
public Object nmsBlock_getById(int id) {
|
||||
if (this.reflectBlock.nmsGetById == null) {
|
||||
if (reflectBlock == null) {
|
||||
fail();
|
||||
}
|
||||
return ReflectionUtil.invokeMethod(this.reflectBlock.nmsGetById, null, id);
|
||||
return this.reflectBlock.nms_getById(id);
|
||||
}
|
||||
|
||||
public Object nmsBlock_getMaterial(Object block) {
|
||||
if (this.reflectBlock.nmsGetMaterial == null) {
|
||||
if (reflectBlock == null) {
|
||||
fail();
|
||||
}
|
||||
return ReflectionUtil.invokeMethodNoArgs(this.reflectBlock.nmsGetMaterial, block);
|
||||
}
|
||||
|
||||
public void nmsBlock_updateShape(Object block, Object iBlockAccess, int x, int y, int z) {
|
||||
if (this.reflectBlock.nmsUpdateShape == null) {
|
||||
fail();
|
||||
}
|
||||
if (this.reflectBlock.useBlockPosition) {
|
||||
ReflectionUtil.invokeMethod(this.reflectBlock.nmsUpdateShape, block, iBlockAccess, nmsBlockPosition(x, y, z));
|
||||
} else {
|
||||
ReflectionUtil.invokeMethod(this.reflectBlock.nmsUpdateShape, block, iBlockAccess, x, y, z);
|
||||
}
|
||||
return this.reflectBlock.nms_getMaterial(block);
|
||||
}
|
||||
|
||||
public boolean nmsMaterial_isSolid(Object material) {
|
||||
|
@ -310,32 +313,27 @@ public class ReflectHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* (Not a method in world types.)
|
||||
* Fetch the block shape for the given position in the given nms-world. (Not
|
||||
* a method in world types.)
|
||||
*
|
||||
* @param nmsWorld
|
||||
* @param typeId
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return double[6] minX, minY, minZ, maxX, maxY, maxZ. Returns null for cases like air/unspecified.
|
||||
* @return double[6] minX, minY, minZ, maxX, maxY, maxZ. Returns null for
|
||||
* cases like air/unspecified.
|
||||
*/
|
||||
public double[] nmsWorld_fetchBlockShape(Object nmsWorld, int id, int x, int y, int z) {
|
||||
if (this.reflectBlock.nmsGetMinX == null) { // Use nmsGetMinX as reference for all six methods (!).
|
||||
public double[] nmsWorld_fetchBlockShape(final Object nmsWorld,
|
||||
final int id, final int x, final int y, final int z) {
|
||||
if (reflectBlock == null) {
|
||||
fail();
|
||||
}
|
||||
Object block = nmsBlock_getById(id);
|
||||
if (block == null) {
|
||||
final Object nmsBlock = nmsBlock_getById(id);
|
||||
if (nmsBlock == null) {
|
||||
return null;
|
||||
}
|
||||
nmsBlock_updateShape(block, nmsWorld, x, y, z);
|
||||
// TODO: The methods could return null [better try-catch here].
|
||||
return new double[] {
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.reflectBlock.nmsGetMinX, block)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.reflectBlock.nmsGetMinY, block)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.reflectBlock.nmsGetMinZ, block)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.reflectBlock.nmsGetMaxX, block)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.reflectBlock.nmsGetMaxY, block)).doubleValue(),
|
||||
((Number) ReflectionUtil.invokeMethodNoArgs(this.reflectBlock.nmsGetMaxZ, block)).doubleValue(),
|
||||
};
|
||||
return reflectBlock.nms_fetchBounds(nmsWorld, nmsBlock, x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
public class ReflectIBlockAccess {
|
||||
|
||||
public final Class<?> nmsClass;
|
||||
|
||||
public ReflectIBlockAccess(ReflectBase base) throws ClassNotFoundException {
|
||||
nmsClass = Class.forName(base.nmsPackageName + ".IBlockAccess");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import fr.neatmonster.nocheatplus.compat.cbreflect.reflect.ReflectHelper.ReflectFailureException;
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* IBlockData (nms).
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class ReflectIBlockData {
|
||||
|
||||
public final Class<?> nmsClass;
|
||||
|
||||
public final Method nmsGetMaterial;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param base
|
||||
* @param reflectMaterial
|
||||
* @throws ClassNotFoundException
|
||||
* @throws ReflectFailureException
|
||||
* If not available.
|
||||
*/
|
||||
public ReflectIBlockData(ReflectBase base, ReflectMaterial reflectMaterial) throws ClassNotFoundException {
|
||||
nmsClass = Class.forName(base.nmsPackageName + ".IBlockData");
|
||||
nmsGetMaterial = ReflectionUtil.getMethodNoArgs(nmsClass, "getMaterial", reflectMaterial.nmsClass);
|
||||
if (nmsGetMaterial == null) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param iBlockData
|
||||
* IBlockData instance.
|
||||
* @return
|
||||
* @throws ReflectFailureException
|
||||
* On failures.
|
||||
*/
|
||||
public Object nms_getMaterial(final Object iBlockData) {
|
||||
try {
|
||||
return nmsGetMaterial.invoke(iBlockData);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -19,12 +19,14 @@ import java.lang.reflect.Method;
|
|||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
public class ReflectMaterial {
|
||||
|
||||
|
||||
public final Class<?> nmsClass;
|
||||
|
||||
public final Method nmsIsLiquid;
|
||||
public final Method nmsIsSolid;
|
||||
|
||||
public ReflectMaterial(ReflectBase base) throws ClassNotFoundException {
|
||||
Class<?> nmsClass = Class.forName(base.nmsPackageName + ".Material");
|
||||
nmsClass = Class.forName(base.nmsPackageName + ".Material");
|
||||
nmsIsLiquid = ReflectionUtil.getMethodNoArgs(nmsClass, "isLiquid", boolean.class);
|
||||
nmsIsSolid = ReflectionUtil.getMethodNoArgs(nmsClass, "isSolid", boolean.class);
|
||||
}
|
||||
|
|
|
@ -14,19 +14,71 @@
|
|||
*/
|
||||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import fr.neatmonster.nocheatplus.compat.cbreflect.reflect.ReflectHelper.ReflectFailureException;
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
public class ReflectWorld {
|
||||
|
||||
|
||||
/** World (nms) */
|
||||
public final Class<?> nmsClass;
|
||||
|
||||
public final Method obcGetHandle;
|
||||
|
||||
|
||||
public final Method nmsGetType;
|
||||
|
||||
// nms - WorldServer: Used as IBlockAccess as well.
|
||||
|
||||
public ReflectWorld(ReflectBase base) throws ClassNotFoundException {
|
||||
public ReflectWorld(ReflectBase base, ReflectMaterial reflectMaterial,
|
||||
ReflectBlockPosition reflectBlockPosition) throws ClassNotFoundException {
|
||||
Class<?> obcClass = Class.forName(base.obcPackageName + ".CraftWorld");
|
||||
obcGetHandle = ReflectionUtil.getMethodNoArgs(obcClass, "getHandle");
|
||||
|
||||
// IBlockData getType(BlockPosition): fail-safe.
|
||||
ReflectIBlockData reflectIBlockData = null;
|
||||
Class<?> nmsClass = null;
|
||||
try {
|
||||
reflectIBlockData = new ReflectIBlockData(base, reflectMaterial);
|
||||
nmsClass = Class.forName(base.nmsPackageName + ".World");
|
||||
}
|
||||
catch (Throwable t) {};
|
||||
this.nmsClass = nmsClass;
|
||||
if (reflectIBlockData == null || nmsClass == null) {
|
||||
nmsGetType = null;
|
||||
}
|
||||
else {
|
||||
Method method = ReflectionUtil.getMethod(nmsClass, "getType", reflectBlockPosition.nmsClass);
|
||||
if (method.getReturnType() == reflectIBlockData.nmsClass) {
|
||||
this.nmsGetType = method;
|
||||
}
|
||||
else {
|
||||
this.nmsGetType = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nmsWorld
|
||||
* @param blockPosition
|
||||
* @return
|
||||
* @throws ReflectFailureException
|
||||
*/
|
||||
public Object nms_getType(final Object nmsWorld, final Object blockPosition) {
|
||||
if (nmsGetType == null) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
try {
|
||||
return nmsGetType.invoke(nmsWorld, blockPosition);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ReflectFailureException();
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user