package codechicken.core; import codechicken.lib.asm.ObfMapping; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; public class ReflectionManager { public static HashMap<Class<?>, Class<?>> primitiveWrappers = new HashMap<Class<?>, Class<?>>(); static { primitiveWrappers.put(Integer.TYPE, Integer.class); primitiveWrappers.put(Short.TYPE, Short.class); primitiveWrappers.put(Byte.TYPE, Byte.class); primitiveWrappers.put(Long.TYPE, Long.class); primitiveWrappers.put(Double.TYPE, Double.class); primitiveWrappers.put(Float.TYPE, Float.class); primitiveWrappers.put(Boolean.TYPE, Boolean.class); primitiveWrappers.put(Character.TYPE, Character.class); } public static boolean isInstance(Class<?> class1, Object obj) { Class<?> primitive = primitiveWrappers.get(class1); if (primitive != null) { if (primitive == Long.class && Long.class.isInstance(obj)) { return true; } if ((primitive == Long.class || primitive == Integer.class) && Integer.class.isInstance(obj)) { return true; } if ((primitive == Long.class || primitive == Integer.class || primitive == Short.class) && Short.class.isInstance(obj)) { return true; } if ((primitive == Long.class || primitive == Integer.class || primitive == Short.class || primitive == Byte.class) && Integer.class.isInstance(obj)) { return true; } if (primitive == Double.class && Double.class.isInstance(obj)) { return true; } if ((primitive == Double.class || primitive == Float.class) && Float.class.isInstance(obj)) { return true; } return primitive.isInstance(obj); } return class1.isInstance(obj); } public static Class<?> findClass(String name) { return findClass(name, true); } public static boolean classExists(String name) { return findClass(name, false) != null; } public static Class<?> findClass(String name, boolean init) { try { return Class.forName(name, init, ReflectionManager.class.getClassLoader()); } catch (ClassNotFoundException cnfe) { try { return Class.forName("net.minecraft.src." + name, init, ReflectionManager.class.getClassLoader()); } catch (ClassNotFoundException cnfe2) { return null; } } } public static void setField(Class<?> class1, Object instance, String name, Object value) throws IllegalArgumentException, IllegalAccessException { setField(class1, instance, new String[] { name }, value); } public static void setField(Class<?> class1, Object instance, String[] names, Object value) throws IllegalArgumentException, IllegalAccessException { for (Field field : class1.getDeclaredFields()) { boolean match = false; for (String name : names) { if (field.getName().equals(name)) { match = true; break; } } if (!match) { continue; } field.setAccessible(true); field.set(instance, value); return; } } public static void setField(Class<?> class1, Object instance, int fieldindex, Object value) throws IllegalArgumentException, IllegalAccessException { Field field = class1.getDeclaredFields()[fieldindex]; field.setAccessible(true); field.set(instance, value); } /** * Static function * void return type * single name */ public static void callMethod(Class<?> class1, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { callMethod(class1, null, new String[] { name }, params); } /** * Static function * void return type * single name */ public static void callMethod(Class<?> class1, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { callMethod(class1, null, names, params); } /** * void return type * single name */ public static void callMethod(Class<?> class1, Object instance, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { callMethod(class1, null, instance, new String[] { name }, params); } /** * void return type */ public static void callMethod(Class<?> class1, Object instance, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { callMethod(class1, null, instance, names, params); } /** * Static method * single name */ public static <R> R callMethod(Class<?> class1, Class<R> returntype, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { return callMethod(class1, returntype, null, new String[] { name }, params); } /** * Static method */ public static <R> R callMethod(Class<?> class1, Class<R> returntype, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { return callMethod(class1, returntype, null, names, params); } /** * sinlge name */ public static <R> R callMethod(Class<?> class1, Class<R> returntype, Object instance, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { return callMethod(class1, returntype, instance, new String[] { name }, params); } public static <R> R callMethod(Class<?> class1, Class<R> returntype, Object instance, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { nextMethod: for (Method method : class1.getDeclaredMethods()) { boolean match = false; for (String name : names) { if (method.getName().equals(name)) { match = true; break; } } if (!match) { continue; } Class<?>[] paramtypes = method.getParameterTypes(); if (paramtypes.length != params.length) { continue; } for (int i = 0; i < params.length; i++) { if (!isInstance(paramtypes[i], params[i])) { continue nextMethod; } } method.setAccessible(true); return (R) method.invoke(instance, params); } return null; } public static <T> T getField(Class<?> class1, Class<T> fieldType, Object instance, int fieldIndex) throws IllegalArgumentException, IllegalAccessException { Field field = class1.getDeclaredFields()[fieldIndex]; field.setAccessible(true); return (T) field.get(instance); } public static <T> T getField(Class<?> class1, Class<T> fieldType, Object instance, String fieldName) { try { Field field = class1.getDeclaredField(fieldName); field.setAccessible(true); return (T) field.get(instance); } catch (Exception e) { throw new RuntimeException(e); } } public static <T> T newInstance(Class<T> class1, Object... params) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { nextMethod: for (Constructor<?> constructor : class1.getDeclaredConstructors()) { Class<?>[] paramtypes = constructor.getParameterTypes(); if (paramtypes.length != params.length) { continue; } for (int i = 0; i < params.length; i++) { if (!isInstance(paramtypes[i], params[i])) { continue nextMethod; } } constructor.setAccessible(true); return (T) constructor.newInstance(params); } return null; } public static boolean hasField(Class<?> class1, String fieldName) { try { class1.getDeclaredField(fieldName); return true; } catch (NoSuchFieldException nfe) { return false; } } public static <T> T get(Field field, Class<T> class1) { return get(field, class1, null); } public static <T> T get(Field field, Class<T> class1, Object instance) { try { return (T) field.get(instance); } catch (Exception e) { throw new RuntimeException(e); } } public static void set(Field field, Object value) { set(field, null, value); } public static void set(Field field, Object instance, Object value) { try { field.set(instance, value); } catch (Exception e) { throw new RuntimeException(e); } } public static Field getField(ObfMapping mapping) { mapping.toRuntime(); try { Class<?> clazz = ReflectionManager.class.getClassLoader().loadClass(mapping.javaClass()); Field field = clazz.getDeclaredField(mapping.s_name); field.setAccessible(true); return field; } catch (Exception e) { throw new RuntimeException(e); } } }