public static void loadLocal(final List<ScriptInfo> scripts, final File directory) throws ClassNotFoundException, InstantiationException, IllegalAccessException, FileNotFoundException, IOException { final List<File> classes = new ArrayList<File>(); for (final File file : directory.listFiles()) { if (file.isDirectory()) { putClasses(classes, file); } else if (file.toString().endsWith(".class")) { classes.add(file); } } for (final File file : classes) { final ClassGen cg = new ClassGen(new ClassParser(file.toURI().toURL().openStream(), file.getName()).parse()); final String className = cg.getClassName(); String fileDir; if (className.indexOf('.') != -1) { final String classDir = className.substring(0, className.indexOf('.')); fileDir = getDirectory(file).toString(); fileDir = fileDir.substring(0, fileDir.indexOf(classDir + '/')); } else { fileDir = directory.toURI().toURL().toString(); } final URLClassLoader loader = new URLClassLoader(new URL[] {new URL(fileDir)}) { public Class loadClass(String name, final boolean resolve) throws ClassNotFoundException { name = name.replace('/', '.').replace('\\', '.'); return super.loadClass(name, resolve); } }; Class<?> clazz; try { clazz = loader.loadClass(className); } catch (Exception e) { e.printStackTrace(); clazz = null; } if (clazz != null) { if (clazz.isAnnotationPresent(ScriptManifest.class)) { final ScriptManifest manifest = clazz.getAnnotation(ScriptManifest.class); scripts.add( new ScriptInfo( manifest.name(), manifest.description(), clazz, manifest.authors(), manifest.version(), manifest.type())); } } loader.close(); } }
public void run() { ClassGen nodeCG = hookHandler.getClassByNick("Node"); for (ClassGen cG : classes) { ConstantPoolGen cpg = cG.getConstantPool(); int nonstatic = 0; int nodeFields = 0; for (Field field : cG.getFields()) { if (field.isStatic()) continue; nonstatic++; if (field.getSignature().equals("L" + nodeCG.getClassName() + ";")) nodeFields++; } if (nonstatic != 2 || nodeFields != 2) continue; String fieldHeadName = ""; for (Method m : cG.getMethods()) { if (m.getName().equals("<init>")) { InstructionFinder instructionFinder = new InstructionFinder(new InstructionList(m.getCode().getCode())); Iterator<InstructionHandle[]> iterator = instructionFinder.search("putfield"); if (iterator.hasNext()) { fieldHeadName = ((FieldInstruction) iterator.next()[0].getInstruction()).getFieldName(cpg); } } } hookHandler.addClassNick("NodeList", cG); for (Field field : cG.getFields()) { if (field.isStatic()) continue; if (field.getName().equals(fieldHeadName)) { hookHandler.addFieldHook( "NodeList", cG, field, "headNode", TypeBuilder.createHookType("Node")); } else { hookHandler.addFieldHook( "NodeList", cG, field, "currentNode", TypeBuilder.createHookType("Node")); } } } }
@Override public void run() { ClassGen nodeCG = hookHandler.getClassByNick("Node"); ClassGen npcCG = hookHandler.getClassByNick("NPC"); for (ClassGen cG : classes) { ConstantPoolGen cpg = cG.getConstantPool(); if (!cG.getSuperclassName().equals(nodeCG.getClassName())) { continue; } int nonStaticFieldCount = 0; int npcFieldCount = 0; for (Field field : cG.getFields()) { if (field.isStatic()) { continue; } nonStaticFieldCount++; if (field.getType().toString().equals(npcCG.getClassName())) { npcFieldCount++; } } if (nonStaticFieldCount != 1 || npcFieldCount != 1) { continue; } hookHandler.addClassNick("NPCNode", cG); for (Field field : cG.getFields()) { if (field.isStatic()) { continue; } if (field.getType().toString().equals(npcCG.getClassName())) { hookHandler.addFieldHook("NPCNode", cG, field, "NPC", TypeBuilder.createHookType("NPC")); } } } ClassGen npcNodeCG = hookHandler.getClassByNick("NPCNode"); for (ClassGen cG : classes) { for (Field field : cG.getFields()) { if (!field.isStatic()) { continue; } if (field.getType().getSignature().equals("[L" + npcNodeCG.getClassName() + ";")) { hookHandler.addClientHook( cG, field, "NPCNodes", TypeBuilder.createHookArrayType("NPCNode", 1)); } } } ClassGen nodeCacheCG = hookHandler.getClassByNick("NodeCache"); FieldHook fieldHook = hookHandler.getFieldHook("NPCNode", "NPC"); for (ClassGen cG : classes) { ConstantPoolGen cpg = cG.getConstantPool(); if (cpg.lookupClass(nodeCacheCG.getClassName()) == -1) { continue; } if (cpg.lookupFieldref( fieldHook.getClassName(), fieldHook.getFieldName(), fieldHook.getFieldType().getSignature()) == -1) { continue; } for (Method method : cG.getMethods()) { if (!method.isStatic()) { continue; } if (!method.getReturnType().equals(Type.VOID)) { continue; } Type[] args = method.getArgumentTypes(); if (args.length < 13 || args.length > 14) { continue; } if (TypeCounter.getObjectCount(args) != 0) { continue; } InstructionList iList = new InstructionList(method.getCode().getCode()); InstructionFinder instructionFinder = new InstructionFinder(iList); for (Iterator<InstructionHandle[]> iterator = instructionFinder.search("getstatic"); iterator.hasNext(); ) { InstructionHandle[] ih = iterator.next(); FieldInstruction fieldInstruction = (FieldInstruction) ih[0].getInstruction(); if (fieldInstruction.getFieldType(cpg).toString().equals(nodeCacheCG.getClassName())) { hookHandler.addClientHook( fieldInstruction, cpg, "NPCNodeCache", TypeBuilder.createHookType("NodeCache")); } } } } }