diff --git a/parabotv2/src/org/parabot/core/parsers/servers/LocalServers.java b/parabotv2/src/org/parabot/core/parsers/servers/LocalServers.java new file mode 100644 index 0000000..fb82095 --- /dev/null +++ b/parabotv2/src/org/parabot/core/parsers/servers/LocalServers.java @@ -0,0 +1,69 @@ +package org.parabot.core.parsers.servers; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; + +import org.parabot.core.Directories; +import org.parabot.core.classpath.ClassPath; +import org.parabot.core.desc.ServerDescription; +import org.parabot.environment.servers.ServerManifest; +import org.parabot.environment.servers.executers.LocalServerExecuter; +import org.parabot.environment.servers.loader.ServerLoader; + +/** + * Parses local server providers located in the servers directory + * + * @author Everel + */ +public class LocalServers extends ServerParser { + + @Override + public void execute() { + // parse classes in server directories + final ClassPath basePath = new ClassPath(); + basePath.parseJarFiles(false); + basePath.addClasses(Directories.getServerPath()); + + final ArrayList classPaths = new ArrayList(); + classPaths.add(basePath); + for (final ClassPath classPath : basePath.getJarFiles()) { + classPaths.add(classPath); + } + + for (final ClassPath path : classPaths) { + // init the server loader + final ServerLoader loader = new ServerLoader(path); + + // loop through all classes which extends the 'ServerProvider' class + for (final String className : loader.getServerClassNames()) { + try { + // get class + final Class serverProviderClass = loader + .loadClass(className); + // get annotation + final Object annotation = serverProviderClass + .getAnnotation(ServerManifest.class); + if (annotation == null) { + throw new RuntimeException("Missing manifest at " + + className); + } + // cast object annotation to server manifest annotation + final ServerManifest manifest = (ServerManifest) annotation; + // get constructor + final Constructor con = serverProviderClass + .getConstructor(); + + SERVER_CACHE.put( + new ServerDescription(manifest.name(), manifest + .author(), manifest.version()), + new LocalServerExecuter(con, path, + manifest.name())); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + + } + +} diff --git a/parabotv2/src/org/parabot/core/parsers/servers/PublicServers.java b/parabotv2/src/org/parabot/core/parsers/servers/PublicServers.java new file mode 100644 index 0000000..ead4bdc --- /dev/null +++ b/parabotv2/src/org/parabot/core/parsers/servers/PublicServers.java @@ -0,0 +1,62 @@ +package org.parabot.core.parsers.servers; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.parabot.core.Configuration; +import org.parabot.core.desc.ServerDescription; +import org.parabot.core.forum.AccountManager; +import org.parabot.core.forum.AccountManagerAccess; +import org.parabot.core.ui.utils.UILog; +import org.parabot.environment.api.utils.WebUtil; +import org.parabot.environment.servers.executers.PublicServerExecuter; + +import javax.swing.*; +import java.io.BufferedReader; +import java.net.URL; + +/** + * Parses servers hosted on Parabot + * + * @author Paradox, Everel + */ +public class PublicServers extends ServerParser { + + private static AccountManager manager; + + public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() { + + @Override + public final void setManager(AccountManager manager) { + PublicServers.manager = manager; + } + + }; + + @Override + public void execute() { + try { + BufferedReader br = WebUtil.getReader(new URL( + Configuration.GET_SERVER_PROVIDERS), manager.getAccount().getURLUsername(), manager.getAccount().getURLPassword()); + String line; + + JSONParser parser = new JSONParser(); + while ((line = br.readLine()) != null) { + + JSONObject jsonObject = (JSONObject) parser.parse(line); + String name = String.valueOf(jsonObject.get("name")); + String author = String.valueOf(jsonObject.get("author")); + double version = Double.parseDouble(String.valueOf(jsonObject.get("version"))); + + ServerDescription desc = new ServerDescription(name, + author, version); + SERVER_CACHE.put(desc, new PublicServerExecuter(name)); + } + + br.close(); + + } catch (Exception e) { + UILog.log("Error", "Failed to load public servers. Either disable your anti-virus or request support on the forums.", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + } + } +} diff --git a/parabotv2/src/org/parabot/core/parsers/servers/ServerParser.java b/parabotv2/src/org/parabot/core/parsers/servers/ServerParser.java new file mode 100644 index 0000000..91d5b24 --- /dev/null +++ b/parabotv2/src/org/parabot/core/parsers/servers/ServerParser.java @@ -0,0 +1,51 @@ +package org.parabot.core.parsers.servers; + +import org.parabot.core.Core; +import org.parabot.core.desc.ServerDescription; +import org.parabot.environment.servers.executers.ServerExecuter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +/** + * Abstract class for parsing server providers + * + * @author Everel + */ +public abstract class ServerParser { + public static final Map SERVER_CACHE = new HashMap(); + + public abstract void execute(); + + public static final ServerDescription[] getDescriptions() { + SERVER_CACHE.clear(); + final ArrayList parsers = new ArrayList<>(); + if (Core.inLoadLocal()) { + parsers.add(new LocalServers()); + parsers.add(new PublicServers()); + } else if (Core.inDebugMode()) { + parsers.add(new LocalServers()); + } else { + parsers.add(new PublicServers()); + } + + Core.verbose("Parsing server providers..."); + for (final ServerParser parser : parsers) { + parser.execute(); + } + + if (Core.inVerboseMode()) { + for (final ServerDescription desc : SERVER_CACHE.keySet()) { + Core.verbose(desc.toString()); + } + Core.verbose("Server providers parsed."); + } + + Map SORTED_SERVER_CACHE = new TreeMap( SERVER_CACHE ); + + return SORTED_SERVER_CACHE.keySet().toArray(new ServerDescription[SORTED_SERVER_CACHE.size()]); + } + +} \ No newline at end of file diff --git a/parabotv2/src/org/parabot/environment/servers/LocalServerExecuter.java b/parabotv2/src/org/parabot/environment/servers/LocalServerExecuter.java new file mode 100755 index 0000000..61a9f4c --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/LocalServerExecuter.java @@ -0,0 +1,50 @@ +package org.parabot.environment.servers; + +import org.parabot.core.Core; +import org.parabot.core.Directories; +import org.parabot.core.build.BuildPath; +import org.parabot.core.classpath.ClassPath; +import org.parabot.environment.servers.executers.ServerExecuter; + +import java.net.MalformedURLException; + +/** + * + * Loads locally stored server providers + * + * @author Everel + * + */ +public class LocalServerExecuter extends ServerExecuter { + private final ServerProvider serverProvider; + private ClassPath classPath; + private String serverName; + + public LocalServerExecuter(ServerProvider serverProvider, + ClassPath classPath, final String serverName) { + this.serverProvider = serverProvider; + this.classPath = classPath; + this.serverName = serverName; + } + + @Override + public void run() { + // add jar or directory to buildpath. + if (this.classPath.isJar()) { + Core.verbose("Adding server provider jar to buildpath: " + + this.classPath.lastParsed.toString()); + this.classPath.addToBuildPath(); + } else { + Core.verbose("Adding server providers directory to buildpath: " + + Directories.getServerPath().getPath()); + try { + BuildPath.add(Directories.getServerPath().toURI().toURL()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + // finalize + super.finalize(this.serverProvider, this.serverName); + } + +} diff --git a/parabotv2/src/org/parabot/environment/servers/ServerManifest.java b/parabotv2/src/org/parabot/environment/servers/ServerManifest.java new file mode 100644 index 0000000..19efd55 --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/ServerManifest.java @@ -0,0 +1,22 @@ +package org.parabot.environment.servers; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A server manifest + * @author Everel + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface ServerManifest { + + String author(); + + String name(); + + double version(); + + Type type(); + +} diff --git a/parabotv2/src/org/parabot/environment/servers/ServerProvider.java b/parabotv2/src/org/parabot/environment/servers/ServerProvider.java new file mode 100644 index 0000000..c201ce8 --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/ServerProvider.java @@ -0,0 +1,150 @@ +package org.parabot.environment.servers; + +import org.objectweb.asm.Opcodes; +import org.parabot.core.Context; +import org.parabot.core.asm.hooks.HookFile; +import org.parabot.core.asm.interfaces.Injectable; +import org.parabot.core.parsers.hooks.HookParser; +import org.parabot.environment.input.Keyboard; +import org.parabot.environment.input.Mouse; +import org.parabot.environment.scripts.Script; + +import javax.swing.*; + +import java.applet.Applet; +import java.applet.AppletStub; +import java.awt.Dimension; +import java.net.URL; + +/** + * Provides a server to the bot + * + * @author Everel + * + */ +public abstract class ServerProvider implements Opcodes { + + /** + * Get the game/applet dimensions + * @return game/applet dimensions + */ + public Dimension getGameDimensions() { + return new Dimension(765, 503); + } + + /** + * Hooks to parse + * + * @deprecated use getHookFile() now + * @return URL to hooks file + */ + @Deprecated + public URL getHooks() { + return null; + } + + /** + * Get hook file to parse + * @return hook file + */ + public HookFile getHookFile() { + return null; + } + + /** + * Jar to parse + * + * @return URL to client jar + */ + public abstract URL getJar(); + + public abstract Applet fetchApplet(); + + public String getAccessorsPackage() { + return null; + } + + public void injectHooks() { + HookFile hookFile = fetchHookFile(); + + if(hookFile == null) { + return; + } + + HookParser parser = hookFile.getParser(); + Injectable[] injectables = parser.getInjectables(); + if (injectables == null) { + return; + } + for (Injectable inj : injectables) { + inj.inject(); + } + Context.getInstance().setHookParser(parser); + } + + private HookFile fetchHookFile() { + HookFile hookFile = getHookFile(); + if(hookFile != null) { + return hookFile; + } + + URL hookLocation = getHooks(); + if(hookLocation == null) { + return null; + } + + return new HookFile(hookLocation, HookFile.TYPE_XML); + } + + /** + * Add custom items to the bot menu bar + * + * @param bar + * menu bar to add items on + */ + public void addMenuItems(JMenuBar bar) { + } + + public AppletStub getStub() { + return null; + } + + public void setClientInstance(Object client) { + Context.getInstance().setClientInstance(client); + } + + public void parseJar() { + Context.getInstance().getClassPath().addJar(getJar()); + } + + public void initScript(Script script) { + + } + + public void init() { + + } + + public void initMouse() { + final Context context = Context.getInstance(); + final Applet applet = context.getApplet(); + final Mouse mouse = new Mouse(applet); + applet.addMouseListener(mouse); + applet.addMouseMotionListener(mouse); + context.setMouse(mouse); + } + + public void initKeyboard() { + final Context context = Context.getInstance(); + final Applet applet = context.getApplet(); + final Keyboard keyboard = new Keyboard(applet); + applet.addKeyListener(keyboard); + context.setKeyboard(keyboard); + } + + public void unloadScript(Script script) { + + } + + +} diff --git a/parabotv2/src/org/parabot/environment/servers/Type.java b/parabotv2/src/org/parabot/environment/servers/Type.java new file mode 100644 index 0000000..91f3f4b --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/Type.java @@ -0,0 +1,14 @@ +package org.parabot.environment.servers; + +/** + * + * Server provider type + * + * @author Everel + * + */ +public enum Type { + + INJECTION, REFLECTION, COLOR, LOADER, OTHER + +} diff --git a/parabotv2/src/org/parabot/environment/servers/executers/LocalServerExecuter.java b/parabotv2/src/org/parabot/environment/servers/executers/LocalServerExecuter.java new file mode 100644 index 0000000..135ae02 --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/executers/LocalServerExecuter.java @@ -0,0 +1,55 @@ +package org.parabot.environment.servers.executers; + +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; + +import org.parabot.core.Core; +import org.parabot.core.Directories; +import org.parabot.core.build.BuildPath; +import org.parabot.core.classpath.ClassPath; +import org.parabot.environment.servers.ServerProvider; + +/** + * + * Loads locally stored server providers + * + * @author Everel + * + */ +public class LocalServerExecuter extends ServerExecuter { + private final Constructor serverProviderConstructor; + private ClassPath classPath; + private String serverName; + + public LocalServerExecuter(Constructor serverProviderConstructor, + ClassPath classPath, final String serverName) { + this.serverProviderConstructor = serverProviderConstructor; + this.classPath = classPath; + this.serverName = serverName; + } + + @Override + public void run() { + // add jar or directory to buildpath. + if (this.classPath.isJar()) { + Core.verbose("Adding server provider jar to buildpath: " + + this.classPath.lastParsed.toString()); + this.classPath.addToBuildPath(); + } else { + Core.verbose("Adding server providers directory to buildpath: " + + Directories.getServerPath().getPath()); + try { + BuildPath.add(Directories.getServerPath().toURI().toURL()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + // finalize + try { + super.finalize((ServerProvider) serverProviderConstructor.newInstance(), this.serverName); + } catch (Throwable t) { + t.printStackTrace(); + } + } + +} diff --git a/parabotv2/src/org/parabot/environment/servers/executers/PublicServerExecuter.java b/parabotv2/src/org/parabot/environment/servers/executers/PublicServerExecuter.java new file mode 100644 index 0000000..21846a7 --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/executers/PublicServerExecuter.java @@ -0,0 +1,123 @@ +package org.parabot.environment.servers.executers; + +import org.parabot.core.Configuration; +import org.parabot.core.Context; +import org.parabot.core.Core; +import org.parabot.core.Directories; +import org.parabot.core.build.BuildPath; +import org.parabot.core.classpath.ClassPath; +import org.parabot.core.desc.ServerProviderInfo; +import org.parabot.core.forum.AccountManager; +import org.parabot.core.forum.AccountManagerAccess; +import org.parabot.core.ui.components.VerboseLoader; +import org.parabot.core.ui.utils.UILog; +import org.parabot.environment.api.utils.WebUtil; +import org.parabot.environment.servers.ServerProvider; +import org.parabot.environment.servers.loader.ServerLoader; + +import javax.swing.*; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.net.URL; + +/** + * + * Fetches a server provider from the Parabot BDN + * + * @author Everel + * + */ +public class PublicServerExecuter extends ServerExecuter { + private String serverName; + + private static AccountManager manager; + + public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() { + + @Override + public final void setManager(AccountManager manager) { + PublicServerExecuter.manager = manager; + } + + }; + + public PublicServerExecuter(final String serverName) { + this.serverName = serverName; + } + + @Override + public void run() { + try { + ServerProviderInfo serverProviderInfo = new ServerProviderInfo(new URL(Configuration.GET_SERVER_PROVIDER_INFO + + this.serverName), manager.getAccount().getURLUsername(), manager.getAccount().getURLPassword()); + + final File destination = new File(Directories.getCachePath(), + serverProviderInfo.getCRC32() + ".jar"); + final String jarUrl = Configuration.GET_SERVER_PROVIDER + + this.serverName; + + Core.verbose("Downloading: " + jarUrl + " ..."); + + + if(destination.exists()) { + Core.verbose("Found cached server provider [CRC32: " + serverProviderInfo.getCRC32() + "]"); + } else { + WebUtil.downloadFile(new URL(jarUrl), destination, + VerboseLoader.get(), manager.getAccount().getURLUsername(), manager.getAccount().getURLPassword()); + Core.verbose("Server provider downloaded..."); + } + + + final ClassPath classPath = new ClassPath(); + classPath.addJar(destination); + + BuildPath.add(destination.toURI().toURL()); + + ServerLoader serverLoader = new ServerLoader(classPath); + final String[] classNames = serverLoader.getServerClassNames(); + if (classNames == null || classNames.length == 0) { + UILog.log( + "Error", + "Failed to load server provider, error: [No provider found in jar file.]", + JOptionPane.ERROR_MESSAGE); + return; + } else if (classNames.length > 1) { + UILog.log( + "Error", + "Failed to load server provider, error: [Multiple providers found in jar file.]"); + return; + } + + final String className = classNames[0]; + try { + final Class providerClass = serverLoader + .loadClass(className); + final Constructor con = providerClass.getConstructor(); + final ServerProvider serverProvider = (ServerProvider) con + .newInstance(); + Context.getInstance(serverProvider).setProviderInfo(serverProviderInfo); + super.finalize(serverProvider, this.serverName); + } catch (NoClassDefFoundError | ClassNotFoundException ignored) { + UILog.log( + "Error", + "Failed to load server provider, error: [This server provider is not compitable with this version of parabot]", + JOptionPane.ERROR_MESSAGE); + } catch (Throwable t) { + t.printStackTrace(); + UILog.log( + "Error", + "Failed to load server provider, post the stacktrace/error on the parabot forums.", + JOptionPane.ERROR_MESSAGE); + } + + } catch (Exception e) { + e.printStackTrace(); + UILog.log( + "Error", + "Failed to load server provider, post the stacktrace/error on the parabot forums.", + JOptionPane.ERROR_MESSAGE); + } + + } +} diff --git a/parabotv2/src/org/parabot/environment/servers/executers/ServerExecuter.java b/parabotv2/src/org/parabot/environment/servers/executers/ServerExecuter.java new file mode 100644 index 0000000..0d257bb --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/executers/ServerExecuter.java @@ -0,0 +1,33 @@ +package org.parabot.environment.servers.executers; + +import org.parabot.core.Context; +import org.parabot.core.ui.components.PaintComponent; +import org.parabot.environment.servers.ServerProvider; + +/** + * + * Executes a server provider + * + * @author Everel + * + */ +public abstract class ServerExecuter { + + public abstract void run(); + + public void finalize(final ServerProvider provider, final String serverName) { + new Thread(new Runnable() { + @Override + public void run() { + try { + Context context = Context.getInstance(provider); + context.load(); + PaintComponent.getInstance().startPainting(context); + } catch (Throwable t) { + t.printStackTrace(); + } + } + }).start(); + } + +} diff --git a/parabotv2/src/org/parabot/environment/servers/loader/ServerLoader.java b/parabotv2/src/org/parabot/environment/servers/loader/ServerLoader.java new file mode 100644 index 0000000..f76cb42 --- /dev/null +++ b/parabotv2/src/org/parabot/environment/servers/loader/ServerLoader.java @@ -0,0 +1,46 @@ +package org.parabot.environment.servers.loader; + +import java.util.ArrayList; +import java.util.List; + +import org.objectweb.asm.tree.ClassNode; +import org.parabot.core.asm.ASMClassLoader; +import org.parabot.core.classpath.ClassPath; +import org.parabot.environment.servers.ServerProvider; + +/** + * + * An environment to load a server + * + * @author Everel + * + * + */ +public class ServerLoader extends ASMClassLoader { + private ClassPath classPath; + + public ServerLoader(ClassPath classPath) { + super(classPath); + this.classPath = classPath; + } + + + /** + * Gets all classes that extends ServerProvider + * @return string array of class names that extends ServerProvider + */ + public final String[] getServerClassNames() { + final List classNames = new ArrayList(); + for (ClassNode c : classPath.classes.values()) + if (c.superName.replace('/', '.').equals( + ServerProvider.class.getName())) { + classNames.add(c.name.replace('/', '.')); + } + return classNames.toArray(new String[classNames.size()]); + } + + public ClassPath getClassPath() { + return classPath; + } + +}