package jas.common.helper;
import jas.common.JASLog;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ObfuscationHelper {
/**
* Helper used to See if we are unObfuscated by checking for a known non-Obfuscated name return true if unObfuscated
* (eclipse), false if obfuscated (Minecraft)
*
* @param list
*/
public static boolean isUnObfuscated(Field[] fieldList, String desired) {
for (int i = 0; i < fieldList.length; i++) {
if (fieldList[i].getName().equals(desired)) {
return true;
}
}
return false;
}
public static boolean isUnObfuscated(Class<?> regularClass, String regularClassName) {
return regularClass.getSimpleName().equals(regularClassName);
}
public static Object invokeMethod(String eclipseName, String seargeName, Class<?> containingClass,
Object containterInstance, Object... args) {
try {
Method method;
method = getIntanceOfMethod(eclipseName, seargeName, containterInstance);
if (method == null) {
throw new NoSuchMethodException();
}
method.setAccessible(true);
return method.invoke(containterInstance, args);
} catch (NoSuchMethodException e) {
JASLog.log().severe("Obfuscation needs updating to access method %s. Notify modmaker.", eclipseName);
e.printStackTrace();
} catch (SecurityException e) {
JASLog.log().severe("Obfuscation needs updating to access method %s. Notify modmaker.", eclipseName);
e.printStackTrace();
} catch (IllegalAccessException e) {
JASLog.log().severe("Obfuscation needs updating to access method %s. Notify modmaker.", eclipseName);
e.printStackTrace();
} catch (IllegalArgumentException e) {
JASLog.log().severe("Obfuscation needs updating to access method %s. Notify modmaker.", eclipseName);
e.printStackTrace();
} catch (InvocationTargetException e) {
JASLog.log().severe("Obfuscation needs updating to access method %s. Notify modmaker.", eclipseName);
e.printStackTrace();
}
return null;
}
private static Method getIntanceOfMethod(String eclipseName, String seargeName, Object containterInstance,
Class<?>... topClassToLook) {
Class<?> classToSearch = containterInstance.getClass();
while (classToSearch.getSuperclass() != null) {
for (Method method : classToSearch.getDeclaredMethods()) {
if (eclipseName.equalsIgnoreCase(method.getName()) || seargeName.equalsIgnoreCase(method.getName())) {
return method;
}
}
classToSearch = classToSearch.getSuperclass();
}
return null;
}
/**
* Helper method to Perform Reflection to Get Static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param type
* @return
*/
public static <T> T getFieldFromReflection(String fieldName, Class<?> containingClass, Class<T> type) {
try {
Field desiredField = containingClass.getDeclaredField(fieldName);
desiredField.setAccessible(true);
return type.cast(desiredField.get(null));
} catch (NoSuchFieldException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s %s. Please notify modmaker Immediately.",
fieldName, type.getSimpleName());
e.printStackTrace();
} catch (IllegalArgumentException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s %s. Please notify modmaker Immediately.",
fieldName, type.getSimpleName());
e.printStackTrace();
} catch (IllegalAccessException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s %s. Please notify modmaker Immediately.",
fieldName, type.getSimpleName());
e.printStackTrace();
} catch (SecurityException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s %s. Please notify modmaker Immediately.",
fieldName, type.getSimpleName());
e.printStackTrace();
}
return null;
}
/**
* Helper method to Perform Reflection to Get non-static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param type
* @return
*/
public static <T> T getFieldFromReflection(String fieldName, Object containterInstance, Class<T> type) {
return getFieldFromReflection(fieldName, containterInstance.getClass(), containterInstance, type);
}
public static <T> T getFieldFromReflection(String fieldName, Class<?> containingClass, Object containterInstance,
Class<T> type) {
try {
return getCatchableFieldFromReflection(fieldName, containingClass, containterInstance, type);
} catch (NoSuchFieldException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s %s. Please notify modmaker Immediately.",
fieldName, type.getSimpleName());
e.printStackTrace();
}
return null;
}
/**
* Helper method to Perform Reflection to Get non-static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param type
* @return
*/
public static <T> T getCatchableFieldFromReflection(String fieldName, Object containterInstance, Class<T> type)
throws NoSuchFieldException {
return getCatchableFieldFromReflection(fieldName, containterInstance.getClass(), containterInstance, type);
}
/**
* Helper method to Perform Reflection to Get non-static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param type
* @return
*/
public static <T> T getCatchableFieldFromReflection(String fieldName, Class<?> containingClass,
Object containterInstance, Class<T> type) throws NoSuchFieldException {
try {
Field desiredField = containingClass.getDeclaredField(fieldName);
desiredField.setAccessible(true);
return type.cast(desiredField.get(containterInstance));
} catch (IllegalArgumentException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (IllegalAccessException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (SecurityException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
}
return null;
}
/**
* Helper method to Perform Reflection to Set non-static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param containingClass Class that contains desired field containerInstance should be castable to it. Required to
* get fields from parent classes
* @param containterInstance Instance of the Object to get the non-static Field
* @param isPrivate Whether the field is private and requires setAccessible(true)
* @param type
* @param value
* @return
* @throws NoSuchFieldException
*/
public static <T> void setCatchableFieldUsingReflection(String fieldName, Class<?> containingClass,
Object containterInstance, boolean isPrivate, T value) throws NoSuchFieldException {
try {
Field desiredField = containingClass.getDeclaredField(fieldName);
if (isPrivate) {
desiredField.setAccessible(true);
}
desiredField.set(containterInstance, value);
} catch (IllegalArgumentException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (IllegalAccessException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (SecurityException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
}
}
/**
* Helper method to Perform Reflection to Set non-static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param containingClass Class that contains desired field containerInstance should be castable to it. Required to
* get fields from parent classes
* @param containterInstance Instance of the Object to get the non-static Field
* @param isPrivate Whether the field is private and requires setAccessible(true)
* @param type
* @param value
* @return
*/
public static <T> void setFieldUsingReflection(String fieldName, Class<?> containingClass,
Object containterInstance, boolean isPrivate, T value) {
try {
Field desiredField = containingClass.getDeclaredField(fieldName);
if (isPrivate) {
desiredField.setAccessible(true);
}
desiredField.set(containterInstance, value);
} catch (NoSuchFieldException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (IllegalArgumentException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (IllegalAccessException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (SecurityException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
}
}
/**
* Helper method to Perform Reflection to Set non-static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param containingClass Class that contains desired field containerInstance should be castable to it. Required to
* get fields from parent classes
* @param containterInstance Instance of the Object to get the non-static Field
* @param isPrivate Whether the field is private and requires setAccessible(true)
* @param type
* @param value
* @return
*/
public static <T> void setFieldUsingReflection(String fieldName, Class<?> containingClass,
Object containterInstance, boolean isPrivate, boolean isFinal, T value) {
try {
Field desiredField = containingClass.getDeclaredField(fieldName);
if (isPrivate) {
desiredField.setAccessible(true);
}
if (isFinal || isPrivate) {
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.set(desiredField, desiredField.getModifiers() & ~Modifier.FINAL);
}
desiredField.set(containterInstance, value);
} catch (NoSuchFieldException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (IllegalArgumentException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (IllegalAccessException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (SecurityException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
}
}
/**
* Helper method to Perform Reflection to Set non-static Field of Provided Type. Field is assumed Private.
*
* @param fieldName
* @param containingClass Class that contains desired field containerInstance should be castable to it. Required to
* get fields from parent classes
* @param containterInstance Instance of the Object to get the non-static Field
* @param isPrivate Whether the field is private and requires setAccessible(true)
* @param type
* @param value
* @return
* @throws NoSuchFieldException
*/
public static <T> void setCatchableFieldUsingReflection(String fieldName, Class<?> containingClass,
Object containterInstance, boolean isPrivate, boolean isFinal, T value) throws NoSuchFieldException {
try {
Field desiredField = containingClass.getDeclaredField(fieldName);
if (isPrivate) {
desiredField.setAccessible(true);
}
if (isFinal || isPrivate) {
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.set(desiredField, desiredField.getModifiers() & ~Modifier.FINAL);
}
desiredField.set(containterInstance, value);
} catch (IllegalArgumentException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (IllegalAccessException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
} catch (SecurityException e) {
JASLog.log().severe(
"Obfuscation needs to be updated to access the %s. Please notify modmaker Immediately.", fieldName);
e.printStackTrace();
}
}
public static Class<?> getDeclaredClass(String className, Class<?> containingClass) {
for (Class<?> declaredClass : containingClass.getDeclaredClasses()) {
if (declaredClass.getSimpleName().equals(className)) {
return declaredClass;
}
}
return null;
}
}