mirror of
https://github.com/2006-Scape/Parabot.git
synced 2026-07-07 08:39:12 +00:00
Updates
This commit is contained in:
@@ -9,11 +9,11 @@ import org.parabot.core.ui.ServerSelector;
|
||||
/**
|
||||
* Parabot X - A revolution in bot clients
|
||||
*
|
||||
* @author Clisprail
|
||||
* @author Matt, Dane, Parameter
|
||||
* @author Clisprail (Parnassian)
|
||||
* @author Matt, Dane
|
||||
* @version 2.0
|
||||
*/
|
||||
public class Landing {
|
||||
public final class Landing {
|
||||
|
||||
public static void main(String... args) {
|
||||
try {
|
||||
@@ -25,4 +25,6 @@ public class Landing {
|
||||
Core.enableDevMode();
|
||||
ServerSelector.getInstance().setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package org.parabot.core;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import org.parabot.core.asm.ASMClassLoader;
|
||||
import org.parabot.core.bot.loader.BotLoader;
|
||||
import org.parabot.core.classpath.ClassPath;
|
||||
import org.parabot.core.paint.PaintDebugger;
|
||||
import org.parabot.core.ui.BotUI;
|
||||
import org.parabot.core.ui.components.GamePanel;
|
||||
import org.parabot.environment.api.interfaces.Paintable;
|
||||
import org.parabot.environment.servers.ServerProvider;
|
||||
|
||||
/**
|
||||
@@ -26,7 +30,15 @@ public class Context {
|
||||
private int tab = 0;
|
||||
private Applet gameApplet = null;
|
||||
|
||||
private Object clientInstance = null;
|
||||
|
||||
private static ArrayList<Paintable> paintables = new ArrayList<Paintable>();
|
||||
|
||||
private PaintDebugger paintDebugger = new PaintDebugger();
|
||||
|
||||
public boolean added = false;
|
||||
|
||||
|
||||
|
||||
public Context(final ServerProvider serverProvider) {
|
||||
threadGroups.put(Thread.currentThread().getThreadGroup(), this);
|
||||
@@ -44,6 +56,13 @@ public class Context {
|
||||
classLoader = new BotLoader(classPath, serverEnvironment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the main client instance
|
||||
*/
|
||||
public void setClientInstance(Object object) {
|
||||
this.clientInstance = object;
|
||||
}
|
||||
|
||||
/**
|
||||
* ClassPath
|
||||
* @return classpath
|
||||
@@ -81,10 +100,13 @@ public class Context {
|
||||
*/
|
||||
public void load() {
|
||||
serverProvider.parseJar();
|
||||
for(final ClassNode node : classPath.classes.values()) {
|
||||
serverProvider.inject(node);
|
||||
}
|
||||
serverProvider.injectHooks();
|
||||
gameApplet = serverProvider.fetchApplet();
|
||||
if(getClient() == null) {
|
||||
setClientInstance(gameApplet);
|
||||
}
|
||||
serverProvider.addMenuItems(BotUI.getInstance().getBar());
|
||||
BotUI.getInstance().validate();
|
||||
final GamePanel panel = GamePanel.getInstance();
|
||||
panel.removeLoader();
|
||||
panel.setContext(this);
|
||||
@@ -114,12 +136,60 @@ public class Context {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this context
|
||||
* @return id context
|
||||
*/
|
||||
public static int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tab id of this context
|
||||
* @return tab id of this context
|
||||
*/
|
||||
public int getTab() {
|
||||
return tab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a paintable instance to the paintables
|
||||
* @param paintable
|
||||
*/
|
||||
public void addPaintable(Paintable paintable) {
|
||||
paintables.add(paintable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a paintable instance from the paintables
|
||||
* @param paintable
|
||||
*/
|
||||
public void removePaintable(Paintable paintable) {
|
||||
paintables.remove(paintable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the paintable instances
|
||||
* @return array of paintable instances
|
||||
*/
|
||||
public Paintable[] getPaintables() {
|
||||
return paintables.toArray(new Paintable[paintables.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The client debug painter
|
||||
* @return debug painter
|
||||
*/
|
||||
public PaintDebugger getPaintDebugger() {
|
||||
return paintDebugger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the main/client instance
|
||||
* @return instance of the the client
|
||||
*/
|
||||
public Object getClient() {
|
||||
return this.clientInstance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.parabot.core;
|
||||
import java.io.File;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.filechooser.FileSystemView;
|
||||
@@ -56,6 +57,14 @@ public class Directories {
|
||||
return new File(getDefaultDirectory(), "/Parabot/scripts/compiled/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get script compiled path
|
||||
* @return script compiled path
|
||||
*/
|
||||
public static File getResourcesPath() {
|
||||
return new File(getDefaultDirectory(), "/Parabot/scripts/resources/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets settings directory
|
||||
* @return settings directory
|
||||
@@ -86,6 +95,7 @@ public class Directories {
|
||||
files.add(getSettingsPath());
|
||||
files.add(getScriptSourcesPath());
|
||||
files.add(getScriptCompiledPath());
|
||||
files.add(getResourcesPath());
|
||||
while(files.size() > 0) {
|
||||
final File file = files.poll();
|
||||
if(!file.exists()) {
|
||||
@@ -93,5 +103,17 @@ public class Directories {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static File temp = null;
|
||||
public static File getTempDirectory() {
|
||||
if(temp != null) {
|
||||
return temp;
|
||||
}
|
||||
int randomNum = new Random().nextInt(999999999);
|
||||
temp = new File(getResourcesPath(), randomNum + "/");
|
||||
temp.mkdirs();
|
||||
temp.deleteOnExit();
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ public class ASMClassLoader extends ClassLoader {
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
try {
|
||||
return super.getSystemClassLoader().loadClass(name);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
String key = name.replace('.', '/');
|
||||
if (classCache.containsKey(key)) {
|
||||
return classCache.get(key);
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
|
||||
/**
|
||||
* Adds a method into a Classnode which returns a field
|
||||
@@ -14,7 +15,7 @@ import org.objectweb.asm.tree.MethodNode;
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public class AddGetterAdapter implements Opcodes {
|
||||
public class AddGetterAdapter implements Opcodes, Injectable {
|
||||
private ClassNode into = null;
|
||||
private ClassNode fieldLocation = null;
|
||||
private FieldNode fieldNode = null;
|
||||
@@ -98,9 +99,10 @@ public class AddGetterAdapter implements Opcodes {
|
||||
/**
|
||||
* Injects this the method getter
|
||||
*/
|
||||
@Override
|
||||
public void inject() {
|
||||
MethodNode method = new MethodNode(ACC_PUBLIC | (staticMethod ? ACC_STATIC : 0), methodName, "()" + returnDesc, null, null);
|
||||
if (staticField) {
|
||||
if (!staticField) {
|
||||
method.visitVarInsn(ALOAD, 0);
|
||||
}
|
||||
method.visitFieldInsn(staticField ? GETSTATIC : GETFIELD, fieldLocation.name, fieldNode.name, fieldNode.desc);
|
||||
@@ -118,7 +120,7 @@ public class AddGetterAdapter implements Opcodes {
|
||||
method.visitInsn(L2I);
|
||||
|
||||
method.visitInsn(getReturnOpcode(returnDesc));
|
||||
method.visitMaxs(0, 0);
|
||||
method.visitMaxs(1, 1);
|
||||
into.methods.add(method);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,14 @@ package org.parabot.core.asm.adapters;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.parabot.core.asm.ASMUtils;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public class AddInterfaceAdapter {
|
||||
public class AddInterfaceAdapter implements Injectable {
|
||||
|
||||
private static String accessorPackage = null;
|
||||
private ClassNode node = null;
|
||||
@@ -32,6 +33,7 @@ public class AddInterfaceAdapter {
|
||||
return accessorPackage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject() {
|
||||
addInterface(node, accessorPackage + interfaceClass);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.parabot.core.asm.adapters;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.parabot.core.asm.ASMUtils;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
|
||||
public class AddSuperAdapter implements Injectable {
|
||||
private ClassNode node = null;
|
||||
private String superClass = null;
|
||||
|
||||
public AddSuperAdapter(final ClassNode node, final String superClass) {
|
||||
this.node = node;
|
||||
this.superClass = superClass;
|
||||
}
|
||||
|
||||
public AddSuperAdapter(final String className, final String superClass) {
|
||||
this.node = ASMUtils.getClass(className);
|
||||
this.superClass = superClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject() {
|
||||
setSuper(node, superClass);
|
||||
}
|
||||
|
||||
private static final void setSuper(final ClassNode node, final String superClass) {
|
||||
ListIterator<?> mli = node.methods.listIterator();
|
||||
while (mli.hasNext()) {
|
||||
MethodNode mn = (MethodNode) mli.next();
|
||||
if (mn.name.equals("<init>")) {
|
||||
ListIterator<?> ili = mn.instructions.iterator();
|
||||
while (ili.hasNext()) {
|
||||
AbstractInsnNode ain = (AbstractInsnNode) ili.next();
|
||||
if (ain.getOpcode() == Opcodes.INVOKESPECIAL) {
|
||||
MethodInsnNode min = (MethodInsnNode) ain;
|
||||
min.owner = superClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node.superName = superClass;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.parabot.core.asm.interfaces;
|
||||
|
||||
public interface Injectable {
|
||||
|
||||
public void inject();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.parabot.core.asm.wrappers;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.parabot.core.asm.ASMUtils;
|
||||
import org.parabot.core.asm.adapters.AddGetterAdapter;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public class Getter implements Injectable {
|
||||
|
||||
private ClassNode into = null;
|
||||
private ClassNode fieldLocation = null;
|
||||
private FieldNode fieldNode = null;
|
||||
private String methodName = null;
|
||||
private String returnDesc = null;
|
||||
private boolean staticMethod = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param into - classnode to inject getter method in
|
||||
* @param fieldLocation - classnode where field is located
|
||||
* @param fieldName - field name to get
|
||||
* @param methodName - method name of getter
|
||||
* @param returnDesc - return type of method, can be null for default return
|
||||
* @param staticMethod - pass true if you want the method to be static
|
||||
*/
|
||||
public Getter(final String into, final String fieldLocation, final String fieldNode,
|
||||
final String methodName, final String returnDesc, final boolean staticMethod) {
|
||||
this.into = ASMUtils.getClass(into);
|
||||
this.fieldLocation = ASMUtils.getClass(fieldLocation);
|
||||
this.fieldNode = ASMUtils.getField(ASMUtils.getClass(fieldLocation), fieldNode);
|
||||
this.methodName = methodName;
|
||||
this.returnDesc = returnDesc == null ? this.fieldNode.desc : returnDesc;
|
||||
this.staticMethod = staticMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fieldLocation
|
||||
* @param fieldNode
|
||||
* @param methodName
|
||||
*/
|
||||
public Getter(final String fieldLocation, final String fieldNode, final String methodName) {
|
||||
this.into = ASMUtils.getClass(fieldLocation);
|
||||
this.fieldLocation = this.into;
|
||||
this.fieldNode = ASMUtils.getField(this.into, fieldNode);
|
||||
this.methodName = methodName;
|
||||
this.returnDesc = this.fieldNode.desc;
|
||||
this.staticMethod = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Short route for getAdaptar().inject();
|
||||
* @see AddGetterAdapter#inject
|
||||
*/
|
||||
@Override
|
||||
public void inject() {
|
||||
getAdapter().inject();
|
||||
}
|
||||
|
||||
public AddGetterAdapter getAdapter() {
|
||||
return new AddGetterAdapter(into, fieldLocation, fieldNode, methodName, returnDesc, staticMethod);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.parabot.core.asm.wrappers;
|
||||
|
||||
import org.parabot.core.asm.adapters.AddInterfaceAdapter;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public class Interface implements Injectable {
|
||||
private String className;
|
||||
private String interfaceClass;
|
||||
|
||||
public Interface(String className, String interfaceClass) {
|
||||
this.className = className;
|
||||
this.interfaceClass = interfaceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the interface to the class
|
||||
* Short route for getAdapter#inject();
|
||||
*/
|
||||
@Override
|
||||
public void inject() {
|
||||
getAdapter().inject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the add interface adapter
|
||||
* @return AddInterface adapter
|
||||
*/
|
||||
public AddInterfaceAdapter getAdapter() {
|
||||
return new AddInterfaceAdapter(className, interfaceClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s implements %s%s", className, AddInterfaceAdapter.getAccessorPackage().replaceAll("/", "."), interfaceClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.parabot.core.asm.wrappers;
|
||||
|
||||
import org.parabot.core.asm.adapters.AddSuperAdapter;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
/**
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public class Super implements Injectable {
|
||||
private String className = null;
|
||||
private String superClassName = null;
|
||||
|
||||
public Super(String className, String superClassName) {
|
||||
this.className = className;
|
||||
this.superClassName = superClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a superclass to a class
|
||||
* Short route for getAdapter().inject
|
||||
*/
|
||||
@Override
|
||||
public void inject() {
|
||||
getAdapter().inject();
|
||||
}
|
||||
|
||||
public AddSuperAdapter getAdapter() {
|
||||
return new AddSuperAdapter(className, superClassName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.parabot.core.bot.loader;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.parabot.core.asm.ASMClassLoader;
|
||||
import org.parabot.core.classpath.ClassPath;
|
||||
|
||||
@@ -11,32 +10,9 @@ import org.parabot.core.classpath.ClassPath;
|
||||
*
|
||||
*/
|
||||
public class BotLoader extends ASMClassLoader {
|
||||
private ASMClassLoader serverProvider = null;
|
||||
|
||||
public BotLoader(ClassPath classPath, ASMClassLoader serverProvider) {
|
||||
super(classPath);
|
||||
this.serverProvider = serverProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
return findClass(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
/*String key = name.replace('.', '/');
|
||||
if(serverProvider.classCache.containsKey(key)) {
|
||||
return serverProvider.classCache.get(key);
|
||||
}
|
||||
ClassNode node = serverProvider.classPath.classes.get(key);
|
||||
if (node != null) {
|
||||
serverProvider.classPath.classes.remove(key);
|
||||
Class<?>c = serverProvider.nodeToClass(node);
|
||||
serverProvider.classCache.put(key, c);
|
||||
return c;
|
||||
}*/
|
||||
return super.findClass(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,14 @@ public class ClassPath {
|
||||
public void addJar(final String jarLocation) {
|
||||
JarParser.parseJar(this, jarLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds jar to this classpath
|
||||
* @param jarLocation
|
||||
*/
|
||||
public void addJar(final URL jarLocation) {
|
||||
JarParser.parseJar(this, jarLocation.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and loads all classes/jar files in folder
|
||||
@@ -99,7 +107,9 @@ public class ClassPath {
|
||||
private void loadClass(InputStream in) throws IOException {
|
||||
ClassReader cr = new ClassReader(in);
|
||||
ClassNode cn = new ClassNode();
|
||||
//cr.accept(cn, 0);
|
||||
cr.accept(cn, 0);
|
||||
//cr.accept(cn, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
|
||||
classes.put(cn.name, cn);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ public class JarParser {
|
||||
ClassReader cr = new ClassReader(
|
||||
theJar.getInputStream(entry));
|
||||
ClassNode cn = new ClassNode();
|
||||
//cr.accept(cn, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
cr.accept(cn, 0);
|
||||
classPath.classes.put(cn.name, cn);
|
||||
} else if (!entry.isDirectory()
|
||||
|
||||
@@ -6,6 +6,8 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.parabot.core.Directories;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Clisprail
|
||||
@@ -22,7 +24,7 @@ public class Resources {
|
||||
*/
|
||||
public static void loadResource(final ClassPath classPath, final String name, final InputStream in)
|
||||
throws IOException {
|
||||
File f = File.createTempFile("bot", ".tmp", new File("./"));
|
||||
File f = File.createTempFile("bot", ".tmp", Directories.getTempDirectory());
|
||||
f.deleteOnExit();
|
||||
try (OutputStream out = new FileOutputStream(f)) {
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.parabot.core.paint;
|
||||
|
||||
import org.parabot.environment.api.interfaces.Paintable;
|
||||
|
||||
public abstract class AbstractDebugger implements Paintable {
|
||||
|
||||
public abstract void toggle();
|
||||
|
||||
public abstract boolean isEnabled();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.parabot.core.paint;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.parabot.core.Context;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public class PaintDebugger {
|
||||
private final HashMap<String, AbstractDebugger> debuggers = new HashMap<String, AbstractDebugger>();
|
||||
private final Queue<String> stringDebug = new LinkedList<String>();
|
||||
|
||||
public final void addDebugger(final String name, final AbstractDebugger debugger) {
|
||||
debuggers.put(name, debugger);
|
||||
}
|
||||
|
||||
public void debug(Graphics g) {
|
||||
for(final AbstractDebugger d : debuggers.values()) {
|
||||
if(d.isEnabled()) {
|
||||
d.paint(g);
|
||||
}
|
||||
}
|
||||
g.setColor(Color.green);
|
||||
int y = 20;
|
||||
while(stringDebug.size() > 0) {
|
||||
g.drawString(stringDebug.poll(), 10, y);
|
||||
y += 15;
|
||||
}
|
||||
}
|
||||
|
||||
public static final PaintDebugger getInstance() {
|
||||
return Context.resolve().getPaintDebugger();
|
||||
}
|
||||
|
||||
public final void addString(final String debugLine) {
|
||||
stringDebug.add(debugLine);
|
||||
}
|
||||
|
||||
public final void toggle(final String name) {
|
||||
debuggers.get(name).toggle();
|
||||
}
|
||||
|
||||
public final boolean isEnabled(final String name) {
|
||||
return debuggers.get(name).isEnabled();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
package org.parabot.core.parsers;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.parabot.core.asm.adapters.AddInterfaceAdapter;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
import org.parabot.core.asm.wrappers.Getter;
|
||||
import org.parabot.core.asm.wrappers.Interface;
|
||||
import org.parabot.core.asm.wrappers.Super;
|
||||
import org.parabot.environment.api.utils.WebUtil;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
*
|
||||
* Parses an XML files which injects the hooks and other bytecode manipulation methods
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public class HookParser {
|
||||
private Document doc = null;
|
||||
private boolean parsedInterfaces = false;
|
||||
private HashMap<String, String> interfaceMap = new HashMap<String, String>();
|
||||
|
||||
public HookParser(URL url) {
|
||||
try {
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
doc = dBuilder.parse(WebUtil.getInputStream(url));
|
||||
doc.getDocumentElement().normalize();
|
||||
if(!doc.getDocumentElement().getNodeName().equals("injector")) {
|
||||
throw new RuntimeException("Incorrect hook file.");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Unable to parse hooks " + t);
|
||||
}
|
||||
}
|
||||
|
||||
public final Interface[] getInterfaces() {
|
||||
parsedInterfaces = true;
|
||||
final NodeList interfaceRootList = doc.getElementsByTagName("interfaces");
|
||||
switch(interfaceRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Hook file may not contains multiple <interfaces> tags ");
|
||||
}
|
||||
final Node node = interfaceRootList.item(0);
|
||||
if(node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element interfaceRoot = (Element) node;
|
||||
final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
|
||||
if(interfaces.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Interface> interfaceList = new ArrayList<Interface>();
|
||||
for(int x = 0; x < interfaces.getLength(); x++) {
|
||||
final Node n = interfaces.item(x);
|
||||
if(n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addInterface = (Element) n;
|
||||
final String className = getValue("classname", addInterface);
|
||||
final String interfaceClass = getValue("interface", addInterface);
|
||||
interfaceMap.put(interfaceClass, className);
|
||||
final Interface inf = new Interface(className, interfaceClass);
|
||||
interfaceList.add(inf);
|
||||
}
|
||||
return interfaceList.toArray(new Interface[interfaceList.size()]);
|
||||
}
|
||||
|
||||
public final Super[] getSupers() {
|
||||
final NodeList interfaceRootList = doc.getElementsByTagName("supers");
|
||||
switch(interfaceRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Hook file may not contains multiple <supers> tags ");
|
||||
}
|
||||
final Node node = interfaceRootList.item(0);
|
||||
if(node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element superRoot = (Element) node;
|
||||
final NodeList supers = superRoot.getElementsByTagName("add");
|
||||
if(supers.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Super> superList = new ArrayList<Super>();
|
||||
for(int x = 0; x < supers.getLength(); x++) {
|
||||
final Node n = supers.item(x);
|
||||
if(n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addSuper = (Element) n;
|
||||
final String className = getValue("classname", addSuper);
|
||||
final String superClass = getValue("super", addSuper);
|
||||
final Super sup = new Super(className, superClass);
|
||||
superList.add(sup);
|
||||
}
|
||||
return superList.toArray(new Super[superList.size()]);
|
||||
}
|
||||
|
||||
public final Getter[] getGetters() {
|
||||
final NodeList getterRootList = doc.getElementsByTagName("getters");
|
||||
switch(getterRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Hook file may not contains multiple <getters> tags ");
|
||||
}
|
||||
final Node node = getterRootList.item(0);
|
||||
if(node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element getterRoot = (Element) node;
|
||||
final NodeList getters = getterRoot.getElementsByTagName("add");
|
||||
if(getters.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Getter> getterList = new ArrayList<Getter>();
|
||||
for(int x = 0; x < getters.getLength(); x++) {
|
||||
final Node n = getters.item(x);
|
||||
if(n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addGetter = (Element) n;
|
||||
if(isSet("classname", addGetter) && isSet("accessor", addGetter)) {
|
||||
throw new RuntimeException("Can't set classname and accessor tag together.");
|
||||
}
|
||||
if(isSet("accessor", addGetter) && !parsedInterfaces) {
|
||||
throw new RuntimeException("You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addGetter) ? getValue("classname", addGetter) : interfaceMap.get(getValue("accessor", addGetter));
|
||||
final String into = isSet("into", addGetter) ? getValue("into", addGetter) : className;
|
||||
final String fieldName = getValue("field", addGetter);
|
||||
final String methodName = getValue("methodname", addGetter);
|
||||
boolean staticMethod = isSet("methstatic", addGetter) ? (getValue("methstatic", addGetter).equals("true")) : false;
|
||||
String returnDesc = isSet("desc", addGetter) ? getValue("desc", addGetter) : null;
|
||||
String array = "";
|
||||
if(returnDesc != null && returnDesc.contains("%s")) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if(returnDesc.startsWith("[")) {
|
||||
for( int i=0; i<returnDesc.length(); i++ ) {
|
||||
if( returnDesc.charAt(i) == '[' ) {
|
||||
array += '[';
|
||||
}
|
||||
}
|
||||
returnDesc = returnDesc.replaceAll("\\[", "");
|
||||
}
|
||||
str.append(array).append('L').append(String.format(returnDesc, AddInterfaceAdapter.getAccessorPackage())).append(";");
|
||||
returnDesc = str.toString();
|
||||
}
|
||||
final Getter get = new Getter(into, className, fieldName, methodName, returnDesc, staticMethod);
|
||||
getterList.add(get);
|
||||
}
|
||||
return getterList.toArray(new Getter[getterList.size()]);
|
||||
}
|
||||
|
||||
public Injectable[] getInjectables() {
|
||||
ArrayList<Injectable> injectables = new ArrayList<Injectable>();
|
||||
Interface[] interfaces = getInterfaces();
|
||||
if(interfaces != null) {
|
||||
for(Interface inf : interfaces) {
|
||||
injectables.add(inf);
|
||||
}
|
||||
}
|
||||
Getter[] getters = getGetters();
|
||||
if(getters != null) {
|
||||
for(Getter get : getters) {
|
||||
injectables.add(get);
|
||||
}
|
||||
}
|
||||
Super[] supers = getSupers();
|
||||
if(supers != null) {
|
||||
for(Super sup : supers) {
|
||||
injectables.add(sup);
|
||||
}
|
||||
}
|
||||
return injectables.toArray(new Injectable[injectables.size()]);
|
||||
}
|
||||
|
||||
private static final boolean isSet(String tag, Element element) {
|
||||
return element.getElementsByTagName(tag).getLength() > 0;
|
||||
}
|
||||
|
||||
private static final String getValue(String tag, Element element) {
|
||||
NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();
|
||||
Node node = (Node) nodes.item(0);
|
||||
return node.getNodeValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import javax.swing.JScrollPane;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
import org.parabot.core.Context;
|
||||
import org.parabot.core.ui.components.BotToolbar;
|
||||
import org.parabot.core.ui.components.GamePanel;
|
||||
import org.parabot.core.ui.components.LogArea;
|
||||
@@ -30,13 +29,16 @@ public class BotUI extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static BotUI instance = null;
|
||||
private JMenuBar bar = null;
|
||||
|
||||
public static BotUI getInstance() {
|
||||
return instance == null ? instance = new BotUI() : instance;
|
||||
}
|
||||
|
||||
public BotUI() {
|
||||
JMenuBar bar = new JMenuBar();
|
||||
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
|
||||
setDefaultLookAndFeelDecorated(false);
|
||||
bar = new JMenuBar();
|
||||
JMenu file = new JMenu("File");
|
||||
JMenuItem screenshot = new JMenuItem("Screenshot");
|
||||
screenshot.addActionListener(new ActionListener() {
|
||||
@@ -45,14 +47,7 @@ public class BotUI extends JFrame {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Context c = GamePanel.getInstance().context;
|
||||
GamePanel.getInstance().setContext(null);
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
GamePanel.getInstance().setContext(c);
|
||||
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
@@ -65,10 +60,8 @@ public class BotUI extends JFrame {
|
||||
JToolBar tool = BotToolbar.getInstance();
|
||||
GamePanel pane = GamePanel.getInstance();
|
||||
pane.addLoader();
|
||||
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
|
||||
getContentPane().setLayout(layout);
|
||||
setJMenuBar(bar);
|
||||
setDefaultLookAndFeelDecorated(true);
|
||||
setTitle("parabot v2");
|
||||
setIconImage(Images.getResource("/org/parabot/core/ui/images/icon.png"));
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
@@ -94,5 +87,9 @@ public class BotUI extends JFrame {
|
||||
.addContainerGap(58, Short.MAX_VALUE)));
|
||||
LogArea.log("Welcome to Parabot v2");
|
||||
}
|
||||
|
||||
public JMenuBar getBar() {
|
||||
return bar;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.parabot.environment.api.interfaces;
|
||||
|
||||
import java.awt.Graphics;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*/
|
||||
public interface Paintable {
|
||||
|
||||
public void paint(Graphics g);
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.parabot.environment.api.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
@@ -69,15 +71,28 @@ public class WebUtil {
|
||||
*/
|
||||
public static BufferedReader getReader(final URL url) {
|
||||
try {
|
||||
final URLConnection con = getConnection(url);
|
||||
return new BufferedReader(new InputStreamReader(
|
||||
con.getInputStream()));
|
||||
return new BufferedReader(new InputStreamReader(getInputStream(url)));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets inputstream from url
|
||||
* @param url
|
||||
* @return inputstream from url
|
||||
*/
|
||||
public static InputStream getInputStream(final URL url) {
|
||||
final URLConnection con = getConnection(url);
|
||||
try {
|
||||
return con.getInputStream();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection
|
||||
* @param url
|
||||
|
||||
@@ -5,51 +5,74 @@ import java.applet.AppletStub;
|
||||
import java.net.URL;
|
||||
import javax.swing.JMenuBar;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.parabot.core.Context;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
import org.parabot.core.parsers.HookParser;
|
||||
|
||||
/**
|
||||
* Provides a server to the bot
|
||||
*
|
||||
*
|
||||
* @author Clisprail
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class ServerProvider {
|
||||
|
||||
public abstract class ServerProvider implements Opcodes {
|
||||
|
||||
/**
|
||||
* Hooks to parse
|
||||
*
|
||||
* @return URL to hooks file
|
||||
*/
|
||||
public URL getHooks() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Jar to parse
|
||||
*
|
||||
* @return URL to client jar
|
||||
*/
|
||||
public abstract String getJar();
|
||||
|
||||
public abstract URL getJar();
|
||||
|
||||
public abstract Applet fetchApplet();
|
||||
|
||||
|
||||
public String getAccessorsPackage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void inject(ClassNode node) {
|
||||
|
||||
|
||||
public void injectHooks() {
|
||||
URL hooksFile = getHooks();
|
||||
if (hooksFile == null) {
|
||||
System.out.println("null");
|
||||
return;
|
||||
}
|
||||
HookParser parser = new HookParser(hooksFile);
|
||||
Injectable[] injectables = parser.getInjectables();
|
||||
if (injectables == null) {
|
||||
return;
|
||||
}
|
||||
for (Injectable inj : injectables) {
|
||||
inj.inject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add custom items to the bot menu bar
|
||||
* @param menu bar to add items on
|
||||
*
|
||||
* @param menu
|
||||
* bar to add items on
|
||||
*/
|
||||
public void addMenuItems(JMenuBar bar) {
|
||||
}
|
||||
|
||||
|
||||
public AppletStub getStub() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setClientInstance(Object client) {
|
||||
Context.resolve().setClientInstance(client);
|
||||
}
|
||||
|
||||
public void parseJar() {
|
||||
Context.resolve().getClassPath().addJar(getJar());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user