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:
asofold 2016-06-13 17:49:28 +02:00
parent ea4108b22a
commit db945a7559
10 changed files with 514 additions and 48 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}

View File

@ -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();
}
}
}