Skip to content

Commit

Permalink
Re-add/repair reflection based attribute access.
Browse files Browse the repository at this point in the history
  • Loading branch information
asofold committed Jun 11, 2016
1 parent e0d6585 commit 1e3620a
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 1 deletion.
@@ -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;
}

}
Expand Up @@ -37,7 +37,7 @@ public void setupAttributeAccess(final MCAccess mcAccess, final MCAccessConfig c
"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);
}

Expand Down

0 comments on commit 1e3620a

Please sign in to comment.