mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-06-26 06:14:42 +02:00
Re-add/repair reflection based attribute access.
This commit is contained in:
parent
e0d6585f67
commit
1e3620ac38
|
@ -0,0 +1,192 @@
|
|||
package fr.neatmonster.nocheatplus.compat.cbreflect.reflect;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.components.modifiers.IAttributeAccess;
|
||||
import fr.neatmonster.nocheatplus.utilities.AttribUtil;
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
public class ReflectAttributeAccess implements IAttributeAccess {
|
||||
|
||||
private static class ReflectGenericAttributes {
|
||||
public final Object nmsMOVEMENT_SPEED;
|
||||
|
||||
public ReflectGenericAttributes(ReflectBase base) throws ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName(base.nmsPackageName + ".GenericAttributes");
|
||||
Class<?> clazzIAttribute = Class.forName(base.nmsPackageName + ".IAttribute");
|
||||
Object nmsMOVEMENT_SPEED = null;
|
||||
nmsMOVEMENT_SPEED = get_nmsMOVEMENT_SPEED("MOVEMENT_SPEED", clazz, clazzIAttribute);
|
||||
if (nmsMOVEMENT_SPEED == null) {
|
||||
nmsMOVEMENT_SPEED = get_nmsMOVEMENT_SPEED("d", clazz, clazzIAttribute);
|
||||
}
|
||||
if (nmsMOVEMENT_SPEED == null) {
|
||||
throw new RuntimeException("Not available.");
|
||||
}
|
||||
else {
|
||||
this.nmsMOVEMENT_SPEED = nmsMOVEMENT_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
private Object get_nmsMOVEMENT_SPEED(String fieldName, Class<?> clazz, Class<?> type) {
|
||||
Field field = ReflectionUtil.getField(clazz, fieldName, type);
|
||||
if (field != null) {
|
||||
return ReflectionUtil.get(field, clazz, null);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ReflectAttributeInstance {
|
||||
/** (Custom naming.) */
|
||||
public final Method nmsGetBaseValue;
|
||||
public final Method nmsGetValue;
|
||||
|
||||
/** (Custom naming.) */
|
||||
public final Method nmsGetAttributeModifier;
|
||||
|
||||
public ReflectAttributeInstance(ReflectBase base) throws ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName(base.nmsPackageName + ".AttributeInstance");
|
||||
// Base value.
|
||||
Method method = ReflectionUtil.getMethodNoArgs(clazz, "b", double.class);
|
||||
if (method == null) {
|
||||
// TODO: Consider to search (as long as only two exist).
|
||||
method = ReflectionUtil.getMethodNoArgs(clazz, "getBaseValue", double.class);
|
||||
if (method == null) {
|
||||
method = ReflectionUtil.getMethodNoArgs(clazz, "getBase", double.class);
|
||||
}
|
||||
}
|
||||
nmsGetBaseValue = method;
|
||||
// Value (final value).
|
||||
method = ReflectionUtil.getMethodNoArgs(clazz, "getValue", double.class);
|
||||
if (method == null) {
|
||||
// TODO: Consider to search (as long as only two exist).
|
||||
method = ReflectionUtil.getMethodNoArgs(clazz, "e", double.class); // 1.6.1
|
||||
}
|
||||
nmsGetValue = method;
|
||||
// Get AttributeModifier.
|
||||
// TODO: If name changes: scan.
|
||||
method = ReflectionUtil.getMethod(clazz, "a", UUID.class);
|
||||
if (method == null) {
|
||||
method = ReflectionUtil.getMethod(clazz, "getAttributeModifier", UUID.class);
|
||||
if (method == null) {
|
||||
method = ReflectionUtil.getMethod(clazz, "getModifier", UUID.class);
|
||||
}
|
||||
}
|
||||
nmsGetAttributeModifier = method;
|
||||
if (nmsGetAttributeModifier == null || nmsGetBaseValue == null || nmsGetValue == null) {
|
||||
throw new RuntimeException("Not available.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ReflectAttributeModifier {
|
||||
/** (Custom naming.) */
|
||||
public Method nmsGetOperation;
|
||||
/** (Custom naming.) */
|
||||
public Method nmsGetValue;
|
||||
|
||||
public ReflectAttributeModifier(ReflectBase base) throws ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName(base.nmsPackageName + ".AttributeModifier");
|
||||
// TODO: Scan in a more future proof way.
|
||||
nmsGetOperation = ReflectionUtil.getMethodNoArgs(clazz, "c", int.class);
|
||||
nmsGetValue = ReflectionUtil.getMethodNoArgs(clazz, "d", double.class);
|
||||
if (nmsGetOperation == null || nmsGetValue == null) {
|
||||
throw new RuntimeException("Not available.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: Register each and every one of these as generic instances and fetch from there.
|
||||
private ReflectBase reflectBase;
|
||||
private ReflectGenericAttributes reflectGenericAttributes;
|
||||
private ReflectAttributeInstance reflectAttributeInstance;
|
||||
private ReflectAttributeModifier reflectAttributeModifier;
|
||||
private ReflectPlayer reflectPlayer;
|
||||
|
||||
public ReflectAttributeAccess() {
|
||||
try {
|
||||
this.reflectBase = new ReflectBase();
|
||||
reflectGenericAttributes = new ReflectGenericAttributes(this.reflectBase);
|
||||
reflectAttributeInstance = new ReflectAttributeInstance(this.reflectBase);
|
||||
reflectAttributeModifier = new ReflectAttributeModifier(this.reflectBase);
|
||||
reflectPlayer = new ReflectPlayer(reflectBase, new ReflectDamageSource(reflectBase));
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new RuntimeException("Not available.");
|
||||
}
|
||||
if (reflectBase.nmsPackageName == null || reflectBase.obcPackageName == null
|
||||
|| reflectPlayer.obcGetHandle == null) {
|
||||
throw new RuntimeException("Not available.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getSpeedAttributeMultiplier(Player player) {
|
||||
return getSpeedAttributeMultiplier(player, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getSprintAttributeMultiplier(Player player) {
|
||||
return nmsAttributeInstance_getSprintAttributeModifierMultiplier(getMovementSpeedAttributeInstance(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the speed attribute (MOVEMENT_SPEED) for a player.
|
||||
* @param handle EntityPlayer
|
||||
* @return AttributeInstance
|
||||
*/
|
||||
private Object getMovementSpeedAttributeInstance(Player player) {
|
||||
return ReflectionUtil.invokeMethod(this.reflectPlayer.nmsGetAttributeInstance, getHandle(player), this.reflectGenericAttributes.nmsMOVEMENT_SPEED);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
* @param removeSprint If to calculate away the sprint boost modifier.
|
||||
* @return
|
||||
*/
|
||||
private double getSpeedAttributeMultiplier(Player player, boolean removeSprint) {
|
||||
Object attributeInstance = getMovementSpeedAttributeInstance(player);
|
||||
double val = ((Double) ReflectionUtil.invokeMethodNoArgs(this.reflectAttributeInstance.nmsGetValue, attributeInstance)).doubleValue() / ((Double) ReflectionUtil.invokeMethodNoArgs(this.reflectAttributeInstance.nmsGetBaseValue, attributeInstance)).doubleValue();
|
||||
if (!removeSprint) {
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
final double sprintModifier = nmsAttributeInstance_getSprintAttributeModifierMultiplier(attributeInstance);
|
||||
if (sprintModifier == 1.0) {
|
||||
return val;
|
||||
}
|
||||
else {
|
||||
return val / sprintModifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (Not an existing method.)
|
||||
* @param attributeInstance
|
||||
*/
|
||||
private double nmsAttributeInstance_getSprintAttributeModifierMultiplier(Object attributeInstance) {
|
||||
Object mod = ReflectionUtil.invokeMethod(this.reflectAttributeInstance.nmsGetAttributeModifier, attributeInstance, AttribUtil.ID_SPRINT_BOOST);
|
||||
if (mod == null) {
|
||||
return 1.0;
|
||||
}
|
||||
else {
|
||||
return AttribUtil.getMultiplier((Integer) ReflectionUtil.invokeMethodNoArgs(this.reflectAttributeModifier.nmsGetOperation, mod), (Double) ReflectionUtil.invokeMethodNoArgs(this.reflectAttributeModifier.nmsGetValue, mod));
|
||||
}
|
||||
}
|
||||
|
||||
private Object getHandle(Player player) {
|
||||
Object handle = ReflectionUtil.invokeMethodNoArgs(this.reflectPlayer.obcGetHandle, player);
|
||||
return handle;
|
||||
}
|
||||
|
||||
}
|
|
@ -37,7 +37,7 @@ public class AttributeAccessFactory {
|
|||
"fr.neatmonster.nocheatplus.compat.cb2808.AttributeAccess",
|
||||
"fr.neatmonster.nocheatplus.compat.cb2794.AttributeAccess"
|
||||
}, fallBackDedicated, new String[] {
|
||||
// TODO: Reflection based (legacy).
|
||||
"fr.neatmonster.nocheatplus.compat.cbreflect.reflect.ReflectAttributeAccess" // Legacy
|
||||
}, fallBackReflect, IAttributeAccess.class, config);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user