public Object call(Object[] params) throws Exception { if (useDirectMethod) { return method.invoke(object, params); } int size = stack.size(); ArrayList<Object> oParams = new ArrayList<Object>(Arrays.asList(params)); oParams.ensureCapacity(oParams.size() + defaults.size()); for (Integer i : defaults.keySet()) { oParams.add(i, defaults.get(i)); } debug("oParams:" + oParams.toString()); debug("Stack:" + stack); Object lastResult = null; for (int i = 0; i < size; i++) { Object v = stack.get(i); debug("v:" + v.getClass().getCanonicalName()); if (v instanceof Server || v instanceof APIWrapperMethods || (i == 0 && v instanceof Plugin)) { lastResult = v; } else if (v instanceof SubField) { SubField obj = (SubField) v; debug("Requesting field: " + obj.getName()); if (obj.getName().equals("length") && lastResult.getClass().isArray()) { lastResult = Array.getLength(lastResult); } else { java.lang.reflect.Field field; try { field = lastResult.getClass().getField(obj.getName()); } catch (NoSuchFieldException e) { field = lastResult.getClass().getDeclaredField(obj.getName()); } catch (NoClassDefFoundError e) { lastResult = null; return lastResult; } field.setAccessible(true); lastResult = field.get(lastResult); } } else if (v instanceof SubCall) { SubCall obj = (SubCall) v; debug( "Calling method: '" + obj.getName() + "' with signature: '" + obj.requiresArgs() + "' '" + Arrays.asList(sigForIndices(obj.requiresArgs())) + "'."); debug("Last result:" + (lastResult == null ? null : lastResult.toString())); debug( "Invoking method: '" + obj.getName() + "' with args: '" + Arrays.asList(indicies(oParams, obj.requiresArgs())) + "'."); Object[] args = indicies(oParams, obj.requiresArgs()); Class<?>[] sig = sigForIndices(obj.requiresArgs()); for (int x = 0; x < args.length; x++) { Object val = args[x]; if ((val.getClass().equals(Long.class) || val.getClass().equals(Double.class) || val.getClass().equals(String.class) || val.getClass().equals(long.class) || val.getClass().equals(double.class)) && (sig[x].equals(Integer.class) || sig[x].equals(int.class))) { args[x] = Integer.valueOf(val.toString()); val = args[x]; } else if ((val.getClass().equals(Integer.class) || val.getClass().equals(Long.class) || val.getClass().equals(String.class) || val.getClass().equals(long.class) || val.getClass().equals(int.class)) && (sig[x].equals(Double.class) || sig[x].equals(double.class))) { args[x] = Double.valueOf(val.toString()); val = args[x]; } else if ((val.getClass().equals(Integer.class) || val.getClass().equals(Double.class) || val.getClass().equals(String.class) || val.getClass().equals(int.class) || val.getClass().equals(double.class)) && (sig[x].equals(Long.class) || sig[x].equals(long.class))) { args[x] = Long.valueOf(val.toString()); val = args[x]; } else if (val instanceof List) { sig[x] = List.class; } debug("Arg " + x + ": '" + val + "', type: " + val.getClass().getName()); debug("Sig type: " + sig[x].getName()); } if (flags.contains("NO_EXCEPTIONS") || flags.contains("FALSE_ON_EXCEPTION")) { try { java.lang.reflect.Method thisMethod; try { thisMethod = lastResult.getClass().getMethod(obj.getName(), sig); } catch (NoSuchMethodException e) { thisMethod = lastResult.getClass().getDeclaredMethod(obj.getName(), sig); } thisMethod.setAccessible(true); lastResult = thisMethod.invoke(lastResult, args); } catch (Exception e) { if (flags.contains("FALSE_ON_EXCEPTION")) { return false; } return null; } } else { java.lang.reflect.Method thisMethod = null; try { thisMethod = lastResult.getClass().getMethod(obj.getName(), sig); } catch (NoSuchMethodException e) { thisMethod = lastResult.getClass().getDeclaredMethod(obj.getName(), sig); } catch (NullPointerException e) { return null; // Logger.getLogger("Minecraft").severe("this returned null: " // + stack.get(i - 1)); } thisMethod.setAccessible(true); lastResult = thisMethod.invoke(lastResult, args); } debug("New value:" + lastResult); } } return lastResult; }