[TEST] Fix reflection for health changes.

This commit is contained in:
asofold 2013-07-06 18:53:21 +02:00
parent fb4614d101
commit a7581d509d
2 changed files with 38 additions and 9 deletions

View File

@ -75,20 +75,48 @@ public class ReflectionUtil {
} }
} }
public static Object invokeMethodVoid(final Object obj, final String methodName){ /**
// TODO: ? provide a variation with boolean for general first or specialized first *
// TODO: copy and paste: bad! * @param obj
* @param methodName
* @param returnTypePreference This is comparison with ==, no isAssignableForm. TODO: really ?
* @return
*/
public static Object invokeMethodVoid(final Object obj, final String methodName, final Class<?> ... returnTypePreference){
// TODO: Isn't there a one-line-call for this ?? // TODO: Isn't there a one-line-call for this ??
final Class<?> objClass = obj.getClass(); final Class<?> objClass = obj.getClass();
// Collect methods that might work. // Collect methods that might work.
Method methodFound = null; Method methodFound = null;
int returnTypeIndex = returnTypePreference.length; // This can be 0 for no preferences given.
for (final Method method : objClass.getDeclaredMethods()){ for (final Method method : objClass.getDeclaredMethods()){
if (method.getName().equals(methodName)){ if (method.getName().equals(methodName)){
final Class<?>[] parameterTypes = method.getParameterTypes(); final Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1 ){ if (parameterTypes.length == 0){
// Override the found method if none found yet and assignment is possible, or if it has a specialized argument of an already found one. // Override the found method if none found yet or if the return type matches the preferred policy.
if (methodFound != null && methodFound.getParameterTypes()[0].isAssignableFrom(parameterTypes[0])){ final Class<?> returnType = method.getReturnType();
if (methodFound == null){
methodFound = method; methodFound = method;
for (int i = 0; i < returnTypeIndex; i++){
if (returnTypePreference[i] == returnType){
returnTypeIndex = i;
break;
}
}
}
else{
// Check if the return type is preferred over previously found ones.
for (int i = 0; i < returnTypeIndex; i++){
if (returnTypePreference[i] == returnType){
methodFound = method;
returnTypeIndex = i;
break;
}
}
}
if (returnTypeIndex == 0){
// "Quick" return.
break;
} }
} }
} }

View File

@ -425,6 +425,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// Set god-mode health to maximum. // Set god-mode health to maximum.
// TODO: Mind that health regain might half the ndt. // TODO: Mind that health regain might half the ndt.
double health = 0.0; double health = 0.0;
// TODO: Put workarounds to some HealthAPI utility class with proper arguments and return type.
try{ try{
// Changed order. // Changed order.
health = event.getAmount() + player.getHealth(); health = event.getAmount() + player.getHealth();
@ -435,11 +436,11 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
LogUtil.logWarning("[NoCheatPlus] Health API incompatibility detected."); LogUtil.logWarning("[NoCheatPlus] Health API incompatibility detected.");
} }
// Reflection fall-back (might fall back to int methods, at present). // Reflection fall-back (might fall back to int methods, at present).
final Object o1 = ReflectionUtil.invokeMethodVoid(event, "getAmount"); final Object o1 = ReflectionUtil.invokeMethodVoid(event, "getAmount", double.class, int.class);
if (o1 instanceof Number){ if (o1 instanceof Number){
health += ((Number) o1).doubleValue(); health += ((Number) o1).doubleValue();
} }
final Object o2 = ReflectionUtil.invokeMethodVoid(player, "getHealth"); final Object o2 = ReflectionUtil.invokeMethodVoid(player, "getHealth", double.class, int.class);
if (o2 instanceof Number){ if (o2 instanceof Number){
health += ((Number) o2).doubleValue(); health += ((Number) o2).doubleValue();
} }
@ -453,7 +454,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
LogUtil.logWarning("[NoCheatPlus] Health API incompatibility detected."); LogUtil.logWarning("[NoCheatPlus] Health API incompatibility detected.");
} }
// Reflection fall-back (might fall back to int methods, at present). // Reflection fall-back (might fall back to int methods, at present).
final Object o1 = ReflectionUtil.invokeMethodVoid(player, "getMaxHealth"); final Object o1 = ReflectionUtil.invokeMethodVoid(player, "getMaxHealth", double.class, int.class);
if (o1 instanceof Number){ if (o1 instanceof Number){
health = Math.min(health, ((Number) o1).doubleValue()); health = Math.min(health, ((Number) o1).doubleValue());
} }