package codechicken.core; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import codechicken.lib.asm.ObfMapping; public class ReflectionManager { public static HashMap, Class> primitiveWrappers = new HashMap, 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 callMethod(Class class1, Class returntype, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { return callMethod(class1, returntype, null, new String[]{name}, params); } /** * Static method */ public static R callMethod(Class class1, Class returntype, String[] names, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { return callMethod(class1, returntype, null, names, params); } /** * sinlge name */ public static R callMethod(Class class1, Class returntype, Object instance, String name, Object... params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { return callMethod(class1, returntype, instance, new String[]{name}, params); } public static R callMethod(Class class1, Class 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 getField(Class class1, Class fieldType, Object instance, int fieldIndex) throws IllegalArgumentException, IllegalAccessException { Field field = class1.getDeclaredFields()[fieldIndex]; field.setAccessible(true); return (T) field.get(instance); } public static T getField(Class class1, Class 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 newInstance(Class 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 get(Field field, Class class1) { return get(field, class1, null); } public static T get(Field field, Class 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); } } }