mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-06-26 06:14:42 +02:00
[BLEEDING] Reflection module: access entity bounds/height etc.
This should fix more issues with horse type.
This commit is contained in:
parent
bb5afe0d2e
commit
12ce099eb1
|
@ -379,6 +379,24 @@ public class ReflectionUtil {
|
|||
return defaultValue;
|
||||
}
|
||||
|
||||
public static float getFloat(Field field, Object object, float defaultValue) {
|
||||
try {
|
||||
return field.getFloat(object);
|
||||
}
|
||||
catch (IllegalArgumentException e) {}
|
||||
catch (IllegalAccessException e) {}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static double getDouble(Field field, Object object, double defaultValue) {
|
||||
try {
|
||||
return field.getDouble(object);
|
||||
}
|
||||
catch (IllegalArgumentException e) {}
|
||||
catch (IllegalAccessException e) {}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static Object get(Field field, Object object, Object defaultValue) {
|
||||
try {
|
||||
return field.get(object);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
|
@ -50,7 +51,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.10") > 0) {
|
||||
else if (GenericVersion.compareVersions(mcVersion, "1.11") > 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 +69,7 @@ public class MCAccessCBReflect extends MCAccessBukkitBase {
|
|||
@Override
|
||||
public String getMCVersion() {
|
||||
// Potentially all :p.
|
||||
return "1.4.5-1.10|?";
|
||||
return "1.4.5-1.11|?";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -169,24 +170,28 @@ public class MCAccessCBReflect extends MCAccessBukkitBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHeight(Entity entity) {
|
||||
try {
|
||||
return helper.getHeight(entity);
|
||||
}
|
||||
catch (ReflectFailureException ex) {
|
||||
return super.getHeight(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWidth(Entity entity) {
|
||||
try {
|
||||
return helper.getWidth(entity);
|
||||
}
|
||||
catch (ReflectFailureException ex) {
|
||||
return super.getWidth(entity);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: ---- Missing (better to implement these) ----
|
||||
|
||||
// @Override
|
||||
// public double getHeight(final Entity entity) {
|
||||
// final net.minecraft.server.v1_8_R3.Entity mcEntity = ((CraftEntity) entity).getHandle();
|
||||
// AxisAlignedBB boundingBox = mcEntity.getBoundingBox();
|
||||
// final double entityHeight = Math.max(mcEntity.length, Math.max(mcEntity.getHeadHeight(), boundingBox.e - boundingBox.b));
|
||||
// if (entity instanceof LivingEntity) {
|
||||
// return Math.max(((LivingEntity) entity).getEyeHeight(), entityHeight);
|
||||
// } else return entityHeight;
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public double getWidth(final Entity entity) {
|
||||
// return ((CraftEntity) entity).getHandle().width;
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public AlmostBoolean isIllegalBounds(final Player player) {
|
||||
// final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MostlyHarmless {
|
||||
|
||||
}
|
|
@ -129,10 +129,15 @@ public class ReflectAttributeAccess implements IAttributeAccess {
|
|||
public ReflectAttributeAccess() {
|
||||
try {
|
||||
this.reflectBase = new ReflectBase();
|
||||
ReflectAxisAlignedBB reflectAxisAlignedBB = null;
|
||||
try {
|
||||
reflectAxisAlignedBB = new ReflectAxisAlignedBB(reflectBase);
|
||||
}
|
||||
catch (NullPointerException e) {}
|
||||
reflectGenericAttributes = new ReflectGenericAttributes(this.reflectBase);
|
||||
reflectAttributeInstance = new ReflectAttributeInstance(this.reflectBase);
|
||||
reflectAttributeModifier = new ReflectAttributeModifier(this.reflectBase);
|
||||
reflectPlayer = new ReflectPlayer(reflectBase, new ReflectDamageSource(reflectBase));
|
||||
reflectPlayer = new ReflectPlayer(reflectBase, reflectAxisAlignedBB, new ReflectDamageSource(reflectBase));
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new RuntimeException("Not available.");
|
||||
}
|
||||
|
|
|
@ -26,7 +26,14 @@ import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
|||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class ReflectEntityDamage extends ReflectGetHandleBase<Entity> {
|
||||
public class ReflectEntity extends ReflectGetHandleBase<Entity> {
|
||||
|
||||
public final Field nmsWidth;
|
||||
public final Field nmsLength; // Something like height.
|
||||
@MostlyHarmless()
|
||||
public final Field nmsHeight; // Not anymore in 1.11.
|
||||
|
||||
public final Method nmsGetBoundingBox;
|
||||
|
||||
public final Field nmsDead;
|
||||
|
||||
|
@ -34,14 +41,19 @@ public class ReflectEntityDamage extends ReflectGetHandleBase<Entity> {
|
|||
|
||||
public final boolean nmsDamageEntityInt;
|
||||
|
||||
public ReflectEntityDamage(ReflectBase base, ReflectDamageSource damageSource) throws ClassNotFoundException {
|
||||
this(base, damageSource, Class.forName(base.obcPackageName + ".entity.CraftEntity"), Class.forName(base.nmsPackageName + ".Entity"));
|
||||
public ReflectEntity(ReflectBase base, ReflectAxisAlignedBB reflectAxisAlignedBB, ReflectDamageSource damageSource) throws ClassNotFoundException {
|
||||
this(base, reflectAxisAlignedBB, damageSource, Class.forName(base.obcPackageName + ".entity.CraftEntity"), Class.forName(base.nmsPackageName + ".Entity"));
|
||||
}
|
||||
|
||||
public ReflectEntityDamage(ReflectBase base, ReflectDamageSource damageSource, Class<?> obcClass, Class<?> nmsClass) throws ClassNotFoundException {
|
||||
public ReflectEntity(ReflectBase base, ReflectAxisAlignedBB reflectAxisAlignedBB, ReflectDamageSource damageSource, Class<?> obcClass, Class<?> nmsClass) throws ClassNotFoundException {
|
||||
// base
|
||||
super(base, obcClass, nmsClass);
|
||||
|
||||
// width, length (height)
|
||||
nmsWidth = ReflectionUtil.getField(nmsClass, "width", float.class);
|
||||
nmsLength = ReflectionUtil.getField(nmsClass, "length", float.class);
|
||||
nmsHeight = ReflectionUtil.getField(nmsClass, "height", float.class); // Rather old CB around 1.6.
|
||||
|
||||
// dead
|
||||
nmsDead = ReflectionUtil.getField(nmsClass, "dead", boolean.class);
|
||||
|
||||
|
@ -53,6 +65,14 @@ public class ReflectEntityDamage extends ReflectGetHandleBase<Entity> {
|
|||
} else {
|
||||
nmsDamageEntityInt = true; // Uncertain.
|
||||
}
|
||||
|
||||
// getBoundingBox
|
||||
if (reflectAxisAlignedBB == null) {
|
||||
this.nmsGetBoundingBox = null;
|
||||
}
|
||||
else {
|
||||
this.nmsGetBoundingBox = ReflectionUtil.getMethodNoArgs(nmsClass, "getBoundingBox", reflectAxisAlignedBB.nmsClass);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
|
@ -19,6 +19,8 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
|
@ -61,19 +63,28 @@ public class ReflectHelper {
|
|||
|
||||
protected final ReflectBase reflectBase;
|
||||
|
||||
protected final ReflectAxisAlignedBB reflectAxisAlignedBB;
|
||||
protected final ReflectBlockPosition reflectBlockPosition;
|
||||
protected final IReflectBlock reflectBlock;
|
||||
protected final ReflectMaterial reflectMaterial;
|
||||
protected final ReflectWorld reflectWorld;
|
||||
|
||||
protected final ReflectDamageSource reflectDamageSource;
|
||||
protected final ReflectEntityDamage reflectEntity;
|
||||
protected final ReflectEntity reflectEntity;
|
||||
protected final ReflectEntity reflectLivingEntity;
|
||||
protected final ReflectPlayer reflectPlayer;
|
||||
|
||||
public ReflectHelper() throws ReflectFailureException {
|
||||
// TODO: Allow some to not work?
|
||||
// TODO: Store one instance of ReflectFailureException?
|
||||
// TODO: Allow some more to not work?
|
||||
try {
|
||||
this.reflectBase = new ReflectBase();
|
||||
ReflectAxisAlignedBB reflectAxisAlignedBB = null;
|
||||
try {
|
||||
reflectAxisAlignedBB = new ReflectAxisAlignedBB(reflectBase);
|
||||
}
|
||||
catch (NullPointerException ex1) {}
|
||||
this.reflectAxisAlignedBB = reflectAxisAlignedBB;
|
||||
ReflectBlockPosition reflectBlockPosition = null;
|
||||
try {
|
||||
reflectBlockPosition = new ReflectBlockPosition(this.reflectBase);
|
||||
|
@ -86,7 +97,8 @@ public class ReflectHelper {
|
|||
try {
|
||||
reflectBlockLatest = new ReflectBlock(this.reflectBase, this.reflectBlockPosition,
|
||||
reflectMaterial, reflectWorld);
|
||||
} catch (Throwable t) {}
|
||||
}
|
||||
catch (Throwable t) {}
|
||||
if (reflectBlockLatest == null) {
|
||||
// More lenient constructor.
|
||||
this.reflectBlock = new ReflectBlockSix(this.reflectBase, this.reflectBlockPosition);
|
||||
|
@ -96,8 +108,9 @@ public class ReflectHelper {
|
|||
}
|
||||
|
||||
this.reflectDamageSource = new ReflectDamageSource(this.reflectBase);
|
||||
this.reflectEntity = new ReflectEntityDamage(this.reflectBase, this.reflectDamageSource);
|
||||
this.reflectPlayer = new ReflectPlayer(this.reflectBase, this.reflectDamageSource);
|
||||
this.reflectEntity = new ReflectEntity(this.reflectBase, this.reflectAxisAlignedBB, this.reflectDamageSource);
|
||||
this.reflectLivingEntity = new ReflectLivingEntity(this.reflectBase, this.reflectAxisAlignedBB, this.reflectDamageSource);
|
||||
this.reflectPlayer = new ReflectPlayer(this.reflectBase, this.reflectAxisAlignedBB, this.reflectDamageSource);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new ReflectFailureException(ex);
|
||||
|
@ -105,6 +118,9 @@ public class ReflectHelper {
|
|||
if (ConfigManager.getConfigFile().getBoolean(ConfPaths.LOGGING_EXTENDED_STATUS)) {
|
||||
List<String> parts = new LinkedList<String>();
|
||||
for (Field rootField : this.getClass().getDeclaredFields()) {
|
||||
if (rootField.isAnnotationPresent(MostlyHarmless.class)) {
|
||||
continue;
|
||||
}
|
||||
boolean accessible = rootField.isAccessible();
|
||||
if (!accessible) {
|
||||
rootField.setAccessible(true);
|
||||
|
@ -118,6 +134,9 @@ public class ReflectHelper {
|
|||
Class<?> clazz = obj.getClass();
|
||||
// TODO: Skip attributes silently before 1.6.1 (and not unknown version).
|
||||
for (Field field : clazz.getFields()) {
|
||||
if (field.isAnnotationPresent(MostlyHarmless.class)) {
|
||||
continue;
|
||||
}
|
||||
if (ReflectionUtil.get(field, obj, null) == null) {
|
||||
parts.add(clazz.getName() + "." + field.getName());
|
||||
}
|
||||
|
@ -336,4 +355,52 @@ public class ReflectHelper {
|
|||
return reflectBlock.nms_fetchBounds(nmsWorld, nmsBlock, x, y, z);
|
||||
}
|
||||
|
||||
public double getWidth(final Entity entity) {
|
||||
float width = -16f;
|
||||
if (reflectEntity.nmsWidth != null) {
|
||||
final Object handle = reflectEntity.getHandle(entity);
|
||||
if (handle != null) {
|
||||
width = ReflectionUtil.getFloat(reflectEntity.nmsWidth, handle, width);
|
||||
}
|
||||
}
|
||||
if (width < 0f) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
return (double) width;
|
||||
}
|
||||
|
||||
public double getHeight(final Entity entity) {
|
||||
float floatHeight = -16f;
|
||||
final Object handle = reflectEntity.getHandle(entity); // TODO: Distinguish classes (living vs not)?
|
||||
if (handle != null) {
|
||||
if (reflectEntity.nmsLength != null) {
|
||||
floatHeight = Math.max(ReflectionUtil.getFloat(reflectEntity.nmsLength, handle, floatHeight), floatHeight);
|
||||
}
|
||||
if (reflectEntity.nmsHeight != null) {
|
||||
floatHeight = Math.max(ReflectionUtil.getFloat(reflectEntity.nmsHeight, handle, floatHeight), floatHeight);
|
||||
}
|
||||
}
|
||||
double height = (double) floatHeight;
|
||||
// TODO: Consider dropping the box for performance?
|
||||
if (reflectAxisAlignedBB != null && reflectEntity.nmsGetBoundingBox != null) {
|
||||
final Object box = ReflectionUtil.invokeMethodNoArgs(reflectEntity.nmsGetBoundingBox, handle);
|
||||
if (box != null) {
|
||||
// mcEntity.boundingBox.e - mcEntity.boundingBox.b
|
||||
final double y2 = ReflectionUtil.getDouble(reflectAxisAlignedBB.nms_maxY, box, Double.MAX_VALUE);
|
||||
final double y1 = ReflectionUtil.getDouble(reflectAxisAlignedBB.nms_minY, box, Double.MAX_VALUE);
|
||||
if (y1 != Double.MAX_VALUE && y2 != Double.MAX_VALUE) {
|
||||
height = Math.max(y2 - y1, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (height < 0.0) {
|
||||
throw new ReflectFailureException();
|
||||
}
|
||||
// On success only: Check eye height (MCAccessBukkit is better than just eye height.).
|
||||
if (entity instanceof LivingEntity) {
|
||||
height = Math.max(height, ((LivingEntity) entity).getEyeHeight());
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,16 +18,16 @@ import java.lang.reflect.Method;
|
|||
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
public class ReflectLivingEntity extends ReflectEntityDamage {
|
||||
public class ReflectLivingEntity extends ReflectEntity {
|
||||
|
||||
public final Method nmsGetHealth;
|
||||
|
||||
public ReflectLivingEntity(ReflectBase base, ReflectDamageSource damageSource) throws ClassNotFoundException {
|
||||
this(base, damageSource, Class.forName(base.obcPackageName + ".entity.CraftLivingEntity"), Class.forName(base.nmsPackageName + ".EntityLiving"));
|
||||
public ReflectLivingEntity(ReflectBase base, ReflectAxisAlignedBB reflectAxisAlignedBB, ReflectDamageSource damageSource) throws ClassNotFoundException {
|
||||
this(base, reflectAxisAlignedBB, damageSource, Class.forName(base.obcPackageName + ".entity.CraftLivingEntity"), Class.forName(base.nmsPackageName + ".EntityLiving"));
|
||||
}
|
||||
|
||||
public ReflectLivingEntity(ReflectBase base, ReflectDamageSource damageSource, Class<?> obcClass, Class<?> nmsClass) throws ClassNotFoundException {
|
||||
super(base, damageSource, obcClass, nmsClass);
|
||||
public ReflectLivingEntity(ReflectBase base, ReflectAxisAlignedBB reflectAxisAlignedBB, ReflectDamageSource damageSource, Class<?> obcClass, Class<?> nmsClass) throws ClassNotFoundException {
|
||||
super(base, reflectAxisAlignedBB, damageSource, obcClass, nmsClass);
|
||||
this.nmsGetHealth = ReflectionUtil.getMethodNoArgs(nmsClass, "getHealth");
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,12 @@ public class ReflectPlayer extends ReflectLivingEntity {
|
|||
|
||||
public final Method nmsGetAttributeInstance; // TODO: LivingEntity
|
||||
|
||||
public ReflectPlayer(ReflectBase base, ReflectDamageSource damageSource) throws ClassNotFoundException {
|
||||
this(base, damageSource, Class.forName(base.obcPackageName + ".entity.CraftPlayer"), Class.forName(base.nmsPackageName + ".EntityPlayer"));
|
||||
public ReflectPlayer(ReflectBase base, ReflectAxisAlignedBB reflectAxisAlignedBB, ReflectDamageSource damageSource) throws ClassNotFoundException {
|
||||
this(base, reflectAxisAlignedBB, damageSource, Class.forName(base.obcPackageName + ".entity.CraftPlayer"), Class.forName(base.nmsPackageName + ".EntityPlayer"));
|
||||
}
|
||||
|
||||
public ReflectPlayer(ReflectBase base, ReflectDamageSource damageSource, Class<?> obcClass, Class<?> nmsClass) throws ClassNotFoundException {
|
||||
super(base, damageSource, obcClass, nmsClass);
|
||||
public ReflectPlayer(ReflectBase base, ReflectAxisAlignedBB reflectAxisAlignedBB, ReflectDamageSource damageSource, Class<?> obcClass, Class<?> nmsClass) throws ClassNotFoundException {
|
||||
super(base, reflectAxisAlignedBB, damageSource, obcClass, nmsClass);
|
||||
// TODO: invulnerable etc.
|
||||
// deathTicks
|
||||
nmsDeathTicks = ReflectionUtil.getField(nmsClass, "deathTicks", int.class);
|
||||
|
|
Loading…
Reference in New Issue
Block a user