v2.01 update

This commit is contained in:
Clisprail
2013-09-04 14:45:23 +02:00
parent 36f7e0407e
commit edb17e188b
89 changed files with 2866 additions and 847 deletions
+46 -10
View File
@@ -5,48 +5,84 @@ import javax.swing.UIManager;
import org.parabot.core.Core; import org.parabot.core.Core;
import org.parabot.core.Directories; import org.parabot.core.Directories;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.ui.LoginUI;
import org.parabot.core.ui.ServerSelector; import org.parabot.core.ui.ServerSelector;
import org.parabot.core.ui.utils.UILog; import org.parabot.core.ui.utils.UILog;
/** /**
* Parabot v2 * Parabot v2
* *
* @author Clisprail (Parnassian) * @author Everel/Parnassian
* @author Matt, Dane * @author Matt, Dane
* @version 2.0 * @version 2.01
*/ */
public final class Landing { public final class Landing {
// forum account
private static String username = null;
private static String password = null;
public static void main(String... args) { public static void main(String... args) {
parseArgs(args); parseArgs(args);
Core.verbose("Debug mode: " + Core.inDebugMode());
try { try {
Core.verbose("Setting look and feel: "
+ UIManager.getSystemLookAndFeelClassName());
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
Directories.validate();
if(!Core.inDebugMode()) { if (!Core.inDebugMode() && !Core.isValid()) {
UILog.log("Error", "You can only run parabot in debug mode.", JOptionPane.ERROR_MESSAGE); UILog.log(
"Updates",
"Please download the newest version of parabot at http://www.parabot.org/",
JOptionPane.INFORMATION_MESSAGE);
return; return;
} }
ServerSelector.getInstance();
Core.verbose("Validating directories...");
Directories.validate();
Core.verbose("Validating account manager...");
AccountManager.validate();
if (username != null && password != null) {
new LoginUI(username, password);
username = null;
password = null;
return;
}
Core.verbose("Starting login gui...");
new LoginUI().setVisible(true);
} }
private static void parseArgs(String... args) { private static void parseArgs(String... args) {
for(int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
final String arg = args[i]; final String arg = args[i].toLowerCase();
switch(arg) { switch (arg) {
case "-createdirs": case "-createdirs":
Directories.validate(); Directories.validate();
System.out.println("Directories created, you can now run parabot."); System.out
.println("Directories created, you can now run parabot.");
System.exit(0); System.exit(0);
break; break;
case "-debug": case "-debug":
Core.setDebug(true); Core.setDebug(true);
break; break;
case "-v":
case "-verbose":
Core.setVerbose(true);
break;
case "-server": case "-server":
ServerSelector.initServer = args[++i]; ServerSelector.initServer = args[++i];
break; break;
case "-login":
username = args[++i];
password = args[++i];
break;
} }
} }
@@ -0,0 +1,18 @@
package org.parabot.core;
/**
*
* @author Everel
*
*/
public class Configuration {
public static final String LOGIN_SERVER = "http://www.parabot.org/community/api/login.php?username=%s&password=%s";
public static final String SDN_SCRIPTS = "http://sdn.parabot.org/scripts.php?user=%s";
public static final String GET_SDN_SCRIPT = "http://sdn.parabot.org/getscript.php?user=%s&pass=%s&scriptid=%d";
public static final String GET_SERVER_PROVIDERS = "http://sdn.parabot.org/list/providers.php";
public static final String GET_SERVER_PROVIDER = "http://sdn.parabot.org/providers/%s";
public static final String GET_BOT_VERSION = "http://bot.parabot.org/version.txt";
public static final double BOT_VERSION = 2.01;
}
+15 -10
View File
@@ -6,7 +6,6 @@ import java.util.HashMap;
import java.util.TimerTask; import java.util.TimerTask;
import org.parabot.core.asm.ASMClassLoader; import org.parabot.core.asm.ASMClassLoader;
import org.parabot.core.bot.loader.BotLoader;
import org.parabot.core.classpath.ClassPath; import org.parabot.core.classpath.ClassPath;
import org.parabot.core.paint.PaintDebugger; import org.parabot.core.paint.PaintDebugger;
import org.parabot.core.parsers.HookParser; import org.parabot.core.parsers.HookParser;
@@ -21,7 +20,7 @@ import org.parabot.environment.servers.ServerProvider;
/** /**
* Game context * Game context
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Context { public class Context {
@@ -53,6 +52,7 @@ public class Context {
this.serverProvider = serverProvider; this.serverProvider = serverProvider;
id++; id++;
this.classPath = new ClassPath(); this.classPath = new ClassPath();
classLoader = new ASMClassLoader(classPath);
} }
/** /**
@@ -69,13 +69,8 @@ public class Context {
return threadGroups.values().iterator().next(); return threadGroups.values().iterator().next();
} }
/** public void setEnvironment() {
* Sets the ServerProvider class loader classLoader = new ASMClassLoader(classPath);
*
* @param serverEnvironment
*/
public void setEnvironment(ASMClassLoader serverEnvironment) {
classLoader = new BotLoader(classPath, serverEnvironment);
} }
/** /**
@@ -157,12 +152,18 @@ public class Context {
* Loads the game * Loads the game
*/ */
public void load() { public void load() {
Core.verbose("Parsing server jar...");
serverProvider.parseJar(); serverProvider.parseJar();
Core.verbose("Done.");
Core.verbose("Injecting hooks...");
serverProvider.injectHooks(); serverProvider.injectHooks();
Core.verbose("Done.");
Core.verbose("Fetching game applet...");;
gameApplet = serverProvider.fetchApplet(); gameApplet = serverProvider.fetchApplet();
if (getClient() == null) { if (getClient() == null) {
setClientInstance(gameApplet); setClientInstance(gameApplet);
} }
Core.verbose("Applet fetched.");
serverProvider.addMenuItems(BotUI.getInstance().getJMenuBar()); serverProvider.addMenuItems(BotUI.getInstance().getJMenuBar());
BotUI.getInstance().validate(); BotUI.getInstance().validate();
final GamePanel panel = GamePanel.getInstance(); final GamePanel panel = GamePanel.getInstance();
@@ -176,8 +177,12 @@ public class Context {
gameApplet.setBounds(0, 0, 765, 503); gameApplet.setBounds(0, 0, 765, 503);
} }
}, 1000); }, 1000);
Core.verbose("Initializing mouse...");
serverProvider.initMouse(); serverProvider.initMouse();
Core.verbose("Done.");
Core.verbose("Initializing keyboard...");
serverProvider.initKeyboard(); serverProvider.initKeyboard();
Core.verbose("Done.");
} }
/** /**
@@ -190,7 +195,7 @@ public class Context {
} }
/** /**
* Gets class loader from this context * Gets class loader of server from this context
* *
* @return class loader * @return class loader
*/ */
+66 -3
View File
@@ -1,23 +1,86 @@
package org.parabot.core; package org.parabot.core;
import java.io.BufferedReader;
import java.io.IOException;
import org.parabot.environment.api.utils.WebUtil;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Core { public class Core {
private static boolean debug = false; private static boolean debug = false;
private static boolean verbose = false;
public static void setDebug(boolean debug) { /**
* Enabled debug mode
*
* @param debug
*/
public static void setDebug(final boolean debug) {
Core.debug = debug; Core.debug = debug;
} }
/** /**
* @return if the botclient is in debug mode. * @return if the client is in debug mode.
*/ */
public static boolean inDebugMode() { public static boolean inDebugMode() {
return debug; return debug;
} }
/**
* @return if the client is in verbose mode.
*/
public static boolean inVerboseMode() {
return verbose;
}
/**
* Sets verbose mode
*
* @param verbose
* - enabled
*/
public static void setVerbose(final boolean verbose) {
Core.verbose = verbose;
}
public static void verbose(final String line) {
if (verbose) {
System.out.println(line);
}
}
/**
* Checks for updates.
*
* @return <b>true</b> if no update is required, otherwise <b>false</b>.
*/
public static boolean isValid() {
Core.verbose("Checking for updates...");
BufferedReader br = WebUtil.getReader(Configuration.GET_BOT_VERSION);
try {
double version = Double.parseDouble(br.readLine());
if (Configuration.BOT_VERSION == version) {
Core.verbose("No updates available.");
return true;
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Core.verbose("Updates available...");
return false;
}
} }
@@ -13,7 +13,7 @@ import org.parabot.environment.OperatingSystem;
/** /**
* *
* @author Clisprail * @author Everel
* @author Matt * @author Matt
* *
*/ */
@@ -31,6 +31,7 @@ public class Directories {
cached.put("Root", new File(System.getProperty("user.home"))); cached.put("Root", new File(System.getProperty("user.home")));
} }
Core.verbose("Caching directories...");
cached.put("Root", getDefaultDirectory()); cached.put("Root", getDefaultDirectory());
cached.put("Workspace", new File(cached.get("Root"), "/Parabot/")); cached.put("Workspace", new File(cached.get("Root"), "/Parabot/"));
cached.put("Sources", new File(cached.get("Root"), "/Parabot/scripts/sources/")); cached.put("Sources", new File(cached.get("Root"), "/Parabot/scripts/sources/"));
@@ -38,6 +39,8 @@ public class Directories {
cached.put("Resources", new File(cached.get("Root"), "/Parabot/scripts/resources/")); cached.put("Resources", new File(cached.get("Root"), "/Parabot/scripts/resources/"));
cached.put("Settings", new File(cached.get("Root"), "/Parabot/settings/")); cached.put("Settings", new File(cached.get("Root"), "/Parabot/settings/"));
cached.put("Servers", new File(cached.get("Root"), "/Parabot/servers/")); cached.put("Servers", new File(cached.get("Root"), "/Parabot/servers/"));
cached.put("Cache", new File(cached.get("Root"), "/Parabot/cache/"));
Core.verbose("Directories cached.");
} }
/** /**
@@ -103,6 +106,15 @@ public class Directories {
return cached.get("Servers"); return cached.get("Servers");
} }
/**
* Returns the Parabot cache folder.
*
* @return
*/
public static File getCachePath() {
return cached.get("Cache");
}
/** /**
* Validates all directories and makes them if necessary * Validates all directories and makes them if necessary
*/ */
@@ -118,10 +130,15 @@ public class Directories {
files.add(getScriptSourcesPath()); files.add(getScriptSourcesPath());
files.add(getScriptCompiledPath()); files.add(getScriptCompiledPath());
files.add(getResourcesPath()); files.add(getResourcesPath());
files.add(getCachePath());
while (files.size() > 0) { while (files.size() > 0) {
final File file = files.poll(); final File file = files.poll();
if (!file.exists()) { if (!file.exists()) {
Core.verbose("Generating directory: " + file.getAbsolutePath());
file.mkdirs(); file.mkdirs();
if(!file.exists()) {
System.err.println("Failed to make directory: " + file.getAbsolutePath());
}
} }
} }
} }
@@ -1,7 +0,0 @@
package org.parabot.core;
public class WebConstants {
public static final String HOME = "http://parnassian.host56.com/";
public static final String SERVER_MANIFEST = HOME + "servers/manifest.dat";
}
@@ -14,6 +14,12 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.parabot.core.classpath.ClassPath; import org.parabot.core.classpath.ClassPath;
/**
*
* @author Everel
* @author Matt
*
*/
public class ASMClassLoader extends ClassLoader { public class ASMClassLoader extends ClassLoader {
private Map<String, Class<?>> classCache = new HashMap<String, Class<?>>(); private Map<String, Class<?>> classCache = new HashMap<String, Class<?>>();
@@ -1,19 +1,21 @@
package org.parabot.core.asm; package org.parabot.core.asm;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Context; import org.parabot.core.Context;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class ASMUtils { public class ASMUtils implements Opcodes {
public static FieldNode getField(ClassNode node, String fieldName) { public static FieldNode getField(ClassNode node, String fieldName) {
for(final FieldNode fieldNode : node.fields) { for (final FieldNode fieldNode : node.fields) {
if(fieldNode.name.equals(fieldName)) { if (fieldNode.name.equals(fieldName)) {
return fieldNode; return fieldNode;
} }
} }
@@ -22,12 +24,81 @@ public class ASMUtils {
public static ClassNode getClass(String className) { public static ClassNode getClass(String className) {
Context context = Context.resolve(); Context context = Context.resolve();
for(ClassNode node : context.getClassPath().classes.values()) { for (ClassNode node : context.getClassPath().classes.values()) {
if(node.name.equals(className)) { if (node.name.equals(className)) {
return node; return node;
} }
} }
return null; return null;
} }
public static MethodNode getMethod(final String className,
final String methodName, final String methodDesc) {
return getMethod(getClass(className), methodName, methodDesc);
}
public static MethodNode getMethod(final ClassNode location,
final String methodName, final String methodDesc) {
for (MethodNode mn : location.methods) {
if (mn.name.equals(methodName) && mn.desc.equals(methodDesc)) {
return mn;
}
}
return null;
}
/**
* Return right opcode for desc
*
* @param desc
* @return return opcode
*/
public static int getReturnOpcode(String desc) {
desc = desc.substring(desc.indexOf("L") + 1);
if (desc.length() > 1) {
return ARETURN;
}
final char c = desc.charAt(0);
switch (c) {
case 'I':
case 'Z':
case 'B':
case 'S':
case 'C':
return IRETURN;
case 'J':
return LRETURN;
case 'F':
return FRETURN;
case 'D':
return DRETURN;
case 'V': // void, method desc
return RETURN;
}
throw new RuntimeException("Wrong desc type: " + c);
}
public static int getLoadOpcode(String desc) {
desc = desc.substring(desc.indexOf("L") + 1);
if (desc.length() > 1) {
return ALOAD;
}
final char c = desc.charAt(0);
switch (c) {
case 'I':
case 'Z':
case 'B':
case 'S':
case 'C':
return ILOAD;
case 'J':
return LLOAD;
case 'F':
return FLOAD;
case 'D':
return DLOAD;
}
throw new RuntimeException("eek " + c);
}
} }
@@ -1,5 +0,0 @@
package org.parabot.core.asm;
public class Injector {
}
@@ -0,0 +1,54 @@
package org.parabot.core.asm.adapters;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* Injects a callback, invokes a given static method
*
* @author Everel
*
*/
public class AddCallbackAdapter implements Injectable, Opcodes {
private MethodNode method;
private String invokeClass;
private String invokeMethod;
private String desc;
private int[] args;
public AddCallbackAdapter(final MethodNode method,
final String invokeClass, final String invokeMethod,
final String desc, final int[] args) {
this.method = method;
this.invokeClass = invokeClass;
this.invokeMethod = invokeMethod;
this.desc = desc;
this.args = args;
}
@Override
public void inject() {
final Type[] types = Type.getArgumentTypes(this.method.desc);
InsnList inject = new InsnList();
Label l0 = new Label();
inject.add(new LabelNode(l0));
for (int arg : args) {
inject.add(new VarInsnNode(ASMUtils.getLoadOpcode(types[arg - 1]
.getDescriptor()), arg));
}
inject.add(new MethodInsnNode(INVOKESTATIC,
this.invokeClass, this.invokeMethod,
this.desc));
this.method.instructions.insert(inject);
}
}
@@ -7,12 +7,14 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Core;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
/** /**
* Adds a method into a Classnode which returns a field * Adds a method into a Classnode which returns a field
* *
* @author Clisprail * @author Everel
* *
*/ */
public class AddGetterAdapter implements Opcodes, Injectable { public class AddGetterAdapter implements Opcodes, Injectable {
@@ -26,15 +28,23 @@ public class AddGetterAdapter implements Opcodes, Injectable {
/** /**
* *
* @param into - classnode to inject getter method in * @param into
* @param fieldLocation - classnode where field is located * - classnode to inject getter method in
* @param fieldName - field name to get * @param fieldLocation
* @param methodName - method name of getter * - classnode where field is located
* @param returnDesc - return type of method, can be null for default return * @param fieldName
* @param staticMethod - pass true if you want the method to be static * - 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 AddGetterAdapter(final ClassNode into, final ClassNode fieldLocation, final FieldNode fieldNode, public AddGetterAdapter(final ClassNode into,
final String methodName, final String returnDesc, final boolean staticMethod) { final ClassNode fieldLocation, final FieldNode fieldNode,
final String methodName, final String returnDesc,
final boolean staticMethod) {
this.into = into; this.into = into;
this.fieldLocation = fieldLocation; this.fieldLocation = fieldLocation;
this.fieldNode = fieldNode; this.fieldNode = fieldNode;
@@ -50,7 +60,8 @@ public class AddGetterAdapter implements Opcodes, Injectable {
* @param fieldNode * @param fieldNode
* @param methodName * @param methodName
*/ */
public AddGetterAdapter(final ClassNode fieldLocation, final FieldNode fieldNode, final String methodName) { public AddGetterAdapter(final ClassNode fieldLocation,
final FieldNode fieldNode, final String methodName) {
this.into = fieldLocation; this.into = fieldLocation;
this.fieldLocation = fieldLocation; this.fieldLocation = fieldLocation;
this.fieldNode = fieldNode; this.fieldNode = fieldNode;
@@ -60,37 +71,41 @@ public class AddGetterAdapter implements Opcodes, Injectable {
this.staticMethod = false; this.staticMethod = false;
} }
/** /**
* Validates if this getter can be injected, if not a runtime exception is thrown * Validates if this getter can be injected, if not a runtime exception is
* thrown
*/ */
public void validate() { public void validate() {
if(methodName == null) { if (methodName == null) {
throw new RuntimeException("Null method name"); throw new RuntimeException("Null method name");
} }
if(into == null) { if (into == null) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("Into ClassNode is null, at : ").append(methodName).append("()"); sb.append("Into ClassNode is null, at : ").append(methodName)
.append("()");
throw new RuntimeException(sb.toString()); throw new RuntimeException(sb.toString());
} }
if(fieldNode == null) { if (fieldNode == null) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("FieldLocation ClassNode is null, at : ").append(methodName).append("()"); sb.append("FieldLocation ClassNode is null, at : ")
.append(methodName).append("()");
throw new RuntimeException(sb.toString()); throw new RuntimeException(sb.toString());
} }
if(fieldNode == null) { if (fieldNode == null) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("FieldNode is null, at : ").append(methodName).append("()"); sb.append("FieldNode is null, at : ").append(methodName)
.append("()");
throw new RuntimeException(sb.toString()); throw new RuntimeException(sb.toString());
} }
for(final MethodNode methodNode : into.methods) { for (final MethodNode methodNode : into.methods) {
if(methodNode.name.equals(methodName)) { if (methodNode.name.equals(methodName)) {
final Type[] args = Type.getArgumentTypes(methodNode.desc); final Type[] args = Type.getArgumentTypes(methodNode.desc);
if(args != null && args.length != 0) { if (args != null && args.length != 0) {
continue; continue;
} }
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("Duplicated method detected. ").append(methodName).append("() in ").append(into.name); sb.append("Duplicated method detected. ").append(methodName)
.append("() in ").append(into.name);
throw new RuntimeException(sb.toString()); throw new RuntimeException(sb.toString());
} }
} }
@@ -101,15 +116,22 @@ public class AddGetterAdapter implements Opcodes, Injectable {
*/ */
@Override @Override
public void inject() { public void inject() {
MethodNode method = new MethodNode(ACC_PUBLIC | (staticMethod ? ACC_STATIC : 0), methodName, "()" + returnDesc, null, null); Core.verbose("Injecting: " + this.toString());
MethodNode method = new MethodNode(ACC_PUBLIC
| (staticMethod ? ACC_STATIC : 0), methodName, "()"
+ returnDesc, null, null);
if (!staticField) { if (!staticField) {
method.visitVarInsn(ALOAD, 0); method.visitVarInsn(ALOAD, 0);
} }
method.visitFieldInsn(staticField ? GETSTATIC : GETFIELD, fieldLocation.name, fieldNode.name, fieldNode.desc); method.visitFieldInsn(staticField ? GETSTATIC : GETFIELD,
fieldLocation.name, fieldNode.name, fieldNode.desc);
if (!fieldNode.desc.equals(returnDesc)) { if (!fieldNode.desc.equals(returnDesc)) {
if (returnDesc.contains("L")) { if (returnDesc.contains("L")) {
if (!returnDesc.contains("[")) { if (!returnDesc.contains("[")) {
method.visitTypeInsn(CHECKCAST,returnDesc.replaceFirst("L", "").replaceAll(";", "")); method.visitTypeInsn(CHECKCAST,
returnDesc.replaceFirst("L", "")
.replaceAll(";", ""));
} else { } else {
method.visitTypeInsn(CHECKCAST, returnDesc); method.visitTypeInsn(CHECKCAST, returnDesc);
} }
@@ -119,38 +141,21 @@ public class AddGetterAdapter implements Opcodes, Injectable {
if (fieldNode.desc.equals("J") && returnDesc.equals("I")) if (fieldNode.desc.equals("J") && returnDesc.equals("I"))
method.visitInsn(L2I); method.visitInsn(L2I);
method.visitInsn(getReturnOpcode(returnDesc)); method.visitInsn(ASMUtils.getReturnOpcode(returnDesc));
method.visitMaxs(1, 1); method.visitMaxs(1, 1);
into.methods.add(method); into.methods.add(method);
} }
/** @Override
* Return right opcode for desc public String toString() {
* @param desc return new StringBuilder("[Injectable: getter, into classname: ")
* @return return opcode .append(into.name).append(", field classname: ")
*/ .append(fieldLocation.name).append(", field name: ")
private static int getReturnOpcode(String desc) { .append(fieldNode.name).append(", field desc: ")
desc = desc.substring(desc.indexOf("L") + 1); .append(fieldNode.desc).append(", method name: ")
if (desc.length() > 1) { .append(methodName).append(", return desc: ")
return ARETURN; .append(returnDesc).append(", static method: ")
} .append(staticMethod).append(", static field: ")
final char c = desc.charAt(0); .append(staticField).append("]").toString();
switch (c)
{
case 'I':
case 'Z':
case 'B':
case 'S':
case 'C':
return IRETURN;
case 'J':
return LRETURN;
case 'F':
return FRETURN;
case 'D':
return DRETURN;
}
throw new RuntimeException("Wrong desc type: " + c);
} }
} }
@@ -1,12 +1,13 @@
package org.parabot.core.asm.adapters; package org.parabot.core.asm.adapters;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.parabot.core.Core;
import org.parabot.core.asm.ASMUtils; import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class AddInterfaceAdapter implements Injectable { public class AddInterfaceAdapter implements Injectable {
@@ -35,11 +36,16 @@ public class AddInterfaceAdapter implements Injectable {
@Override @Override
public void inject() { public void inject() {
Core.verbose("Injecting: " + this.toString());
addInterface(node, accessorPackage + interfaceClass); addInterface(node, accessorPackage + interfaceClass);
} }
protected static void addInterface(ClassNode cg, String i) { protected static void addInterface(ClassNode cg, String i) {
System.out.println(" ^ " + cg.name + " implements " + i);
cg.interfaces.add(i); cg.interfaces.add(i);
} }
@Override
public String toString() {
return new StringBuilder("[Injectable: interface, into classname: ").append(node.name).append(", interface: ").append(accessorPackage).append(interfaceClass).append("]").toString();
}
} }
@@ -0,0 +1,66 @@
package org.parabot.core.asm.adapters;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* Injects a method which invokes an other method
*
* @author Everel
*
*/
public class AddInvokerAdapter implements Opcodes, Injectable {
private ClassNode into = null;
private ClassNode methodLocation = null;
private MethodNode mn = null;
private String argsDesc = null;
private String returnDesc = null;
private String methodName = null;
public AddInvokerAdapter(final ClassNode methodLocation,
final ClassNode into, final MethodNode mn, final String argsDesc,
final String returnDesc, final String methodName) {
this.into = into;
this.methodLocation = methodLocation;
this.mn = mn;
this.argsDesc = argsDesc;
this.returnDesc = returnDesc;
this.methodName = methodName;
}
@Override
public void inject() {
MethodNode m = new MethodNode(ACC_PUBLIC, this.methodName,
this.argsDesc + this.returnDesc, null, null);
boolean isStatic = (this.mn.access & ACC_STATIC) != 0;
if (!isStatic)
m.visitVarInsn(ALOAD, 0);
if (!this.argsDesc.equals("()"))
for (int i = 1; i < this.argsDesc.length() - 1; i++)
m.visitVarInsn(ASMUtils.getLoadOpcode(this.argsDesc.substring(
i, i + 1)), i);
m.visitMethodInsn(isStatic ? INVOKESTATIC : INVOKEVIRTUAL,
methodLocation.name, mn.name, mn.desc);
if (this.returnDesc.contains("L")) {
if (!this.returnDesc.contains("[")) {
m.visitTypeInsn(CHECKCAST, this.returnDesc
.replaceFirst("L", "").replaceAll(";", ""));
} else {
m.visitTypeInsn(CHECKCAST, this.returnDesc);
}
}
m.visitInsn(ASMUtils.getReturnOpcode(this.returnDesc));
m.visitMaxs(0, 0);
this.into.methods.add(m);
}
}
@@ -4,12 +4,13 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Core;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
/** /**
* Injects methods which sets a field * Injects methods which sets a field
* *
* @author Clisprail * @author Everel
* *
*/ */
public class AddSetterAdapter implements Opcodes, Injectable { public class AddSetterAdapter implements Opcodes, Injectable {
@@ -20,7 +21,8 @@ public class AddSetterAdapter implements Opcodes, Injectable {
private String desc = null; private String desc = null;
private boolean methodStatic = false; private boolean methodStatic = false;
public AddSetterAdapter(ClassNode fieldLocation, ClassNode into, FieldNode field, String name, String desc, boolean methodStatic) { public AddSetterAdapter(ClassNode fieldLocation, ClassNode into,
FieldNode field, String name, String desc, boolean methodStatic) {
this.fieldLocation = fieldLocation; this.fieldLocation = fieldLocation;
this.into = into; this.into = into;
this.field = field; this.field = field;
@@ -29,23 +31,31 @@ public class AddSetterAdapter implements Opcodes, Injectable {
this.methodStatic = methodStatic; this.methodStatic = methodStatic;
} }
public AddSetterAdapter(ClassNode fieldLocation, ClassNode into, FieldNode field, String name, String desc) { public AddSetterAdapter(ClassNode fieldLocation, ClassNode into,
FieldNode field, String name, String desc) {
this(fieldLocation, into, field, name, desc, false); this(fieldLocation, into, field, name, desc, false);
} }
private static void addSetter(ClassNode fieldLocation, ClassNode into, FieldNode field, String name, String desc, boolean methodStatic) { private static void addSetter(ClassNode fieldLocation, ClassNode into,
FieldNode field, String name, String desc, boolean methodStatic) {
if (desc.contains("L") && !desc.endsWith("Ljava/lang/String;")) if (desc.contains("L") && !desc.endsWith("Ljava/lang/String;"))
desc = "Ljava/lang/Object;"; desc = "Ljava/lang/Object;";
MethodNode method = new MethodNode(ACC_PUBLIC | (methodStatic ? ACC_STATIC : 0), name, "(" + desc + ")V", null, null); MethodNode method = new MethodNode(ACC_PUBLIC
| (methodStatic ? ACC_STATIC : 0), name, "(" + desc + ")V",
null, null);
boolean isStatic = (field.access & ACC_STATIC) > 0; boolean isStatic = (field.access & ACC_STATIC) > 0;
if (!isStatic) { if (!isStatic) {
method.visitVarInsn(ALOAD, 0); method.visitVarInsn(ALOAD, 0);
} }
if (desc.equals("I")) if (desc.equals("I")) {
method.visitVarInsn(ILOAD, 1); method.visitVarInsn(ILOAD, 1);
else } else if (desc.equals("J")) {
method.visitVarInsn(Opcodes.LLOAD, 1);
} else {
method.visitVarInsn(ALOAD, 1); method.visitVarInsn(ALOAD, 1);
method.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD, fieldLocation.name, field.name, field.desc); }
method.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD,
fieldLocation.name, field.name, field.desc);
method.visitInsn(RETURN); method.visitInsn(RETURN);
method.visitMaxs(2, 2); method.visitMaxs(2, 2);
into.methods.add(method); into.methods.add(method);
@@ -56,8 +66,20 @@ public class AddSetterAdapter implements Opcodes, Injectable {
*/ */
@Override @Override
public void inject() { public void inject() {
Core.verbose("Injecting: " + this.toString());
addSetter(fieldLocation, into, field, name, desc, methodStatic); addSetter(fieldLocation, into, field, name, desc, methodStatic);
}
@Override
public String toString() {
return new StringBuilder("[Injectable: setter, into classname: ")
.append(into.name).append(", field classname: ")
.append(fieldLocation.name).append(", field name: ")
.append(field.name).append(", field desc: ").append(field.desc)
.append(", method name: ").append(name)
.append(", method desc: ").append(desc)
.append(", static method: ").append(methodStatic).append("]")
.toString();
} }
} }
@@ -7,9 +7,15 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Core;
import org.parabot.core.asm.ASMUtils; import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
/**
*
* @author Everel
*
*/
public class AddSuperAdapter implements Injectable { public class AddSuperAdapter implements Injectable {
private ClassNode node = null; private ClassNode node = null;
private String superClass = null; private String superClass = null;
@@ -26,10 +32,12 @@ public class AddSuperAdapter implements Injectable {
@Override @Override
public void inject() { public void inject() {
Core.verbose("Injecting: " + this.toString());
setSuper(node, superClass); setSuper(node, superClass);
} }
private static final void setSuper(final ClassNode node, final String superClass) { private static final void setSuper(final ClassNode node,
final String superClass) {
ListIterator<?> mli = node.methods.listIterator(); ListIterator<?> mli = node.methods.listIterator();
while (mli.hasNext()) { while (mli.hasNext()) {
MethodNode mn = (MethodNode) mli.next(); MethodNode mn = (MethodNode) mli.next();
@@ -48,4 +56,11 @@ public class AddSuperAdapter implements Injectable {
node.superName = superClass; node.superName = superClass;
} }
@Override
public String toString() {
return new StringBuilder("[Injectable: super, class name: ")
.append(node.name).append(", super: ").append(superClass)
.append("]").toString();
}
} }
@@ -0,0 +1,48 @@
package org.parabot.core.asm.wrappers;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.adapters.AddCallbackAdapter;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* @author Everel
*
*/
public class Callback implements Injectable {
private MethodNode method;
private String invokeClass;
private String invokeMethod;
private String desc;
private int[] args;
public Callback(final String className, final String methodName,
final String methodDesc, final String callbackClass,
final String callbackMethod, final String callbackDesc, String args) {
this.method = ASMUtils.getMethod(className, methodName, methodDesc);
this.invokeClass = callbackClass;
this.invokeMethod = callbackMethod;
this.desc = callbackDesc;
if (args.contains(",")) {
final String[] strArgs = args.split(",");
this.args = new int[strArgs.length];
for (int i = 0; i < this.args.length; i++) {
this.args[i] = Integer.parseInt(strArgs[i]);
}
} else {
this.args = new int[] { Integer.parseInt(args) };
}
}
@Override
public void inject() {
getAdapter().inject();
}
public AddCallbackAdapter getAdapter() {
return new AddCallbackAdapter(this.method, this.invokeClass,
this.invokeMethod, this.desc, this.args);
}
}
@@ -8,7 +8,7 @@ import org.parabot.core.asm.interfaces.Injectable;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Getter implements Injectable { public class Getter implements Injectable {
@@ -35,7 +35,6 @@ public class Getter implements Injectable {
this.fieldLocation = ASMUtils.getClass(fieldLocation); this.fieldLocation = ASMUtils.getClass(fieldLocation);
this.fieldNode = ASMUtils.getField(ASMUtils.getClass(fieldLocation), fieldNode); this.fieldNode = ASMUtils.getField(ASMUtils.getClass(fieldLocation), fieldNode);
this.methodName = methodName; this.methodName = methodName;
System.out.println(fieldNode);
this.returnDesc = returnDesc == null ? this.fieldNode.desc : returnDesc; this.returnDesc = returnDesc == null ? this.fieldNode.desc : returnDesc;
this.staticMethod = staticMethod; this.staticMethod = staticMethod;
} }
@@ -5,7 +5,7 @@ import org.parabot.core.asm.interfaces.Injectable;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Interface implements Injectable { public class Interface implements Injectable {
@@ -0,0 +1,68 @@
package org.parabot.core.asm.wrappers;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.adapters.AddInvokerAdapter;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* @author Everel
*
*/
public class Invoker implements Injectable {
private ClassNode into = null;
private ClassNode methodLocation = null;
private MethodNode mn = null;
private String argsDesc = null;
private String returnDesc = null;
private String methodName = null;
public Invoker(String methodLoc, String invMethName, String argsDesc,
String returnDesc, String methodName) {
this(methodLoc, methodLoc, invMethName, argsDesc, returnDesc,
methodName);
}
public Invoker(String into, String methodLoc, String invMethName,
String argsDesc, String returnDesc, String methodName) {
this.into = ASMUtils.getClass(into);
this.methodLocation = ASMUtils.getClass(methodLoc);
this.mn = getMethod(this.methodLocation, invMethName, argsDesc);
this.returnDesc = returnDesc;
this.methodName = methodName;
this.argsDesc = argsDesc;
}
private static MethodNode getMethod(ClassNode into, String name, String desc) {
for (MethodNode m : into.methods) {
String s = m.desc.substring(0, m.desc.indexOf(')') + 1);
if (m.name.equals(name) && s.equals(desc)) {
return m;
}
}
return null;
}
/**
* Short route for getAdaptar().inject();
*
* @see AddInvokerAdapter#inject
*/
@Override
public void inject() {
getAdapter().inject();
}
/**
* Gets the AddInvokerAdapter
*
* @return AddInvokerAdapter
*/
public AddInvokerAdapter getAdapter() {
return new AddInvokerAdapter(this.methodLocation, this.into, this.mn,
this.argsDesc, this.returnDesc, this.methodName);
}
}
@@ -8,7 +8,7 @@ import org.parabot.core.asm.interfaces.Injectable;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Setter implements Injectable { public class Setter implements Injectable {
@@ -4,7 +4,7 @@ import org.parabot.core.asm.adapters.AddSuperAdapter;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Super implements Injectable { public class Super implements Injectable {
@@ -1,18 +0,0 @@
package org.parabot.core.bot.loader;
import org.parabot.core.asm.ASMClassLoader;
import org.parabot.core.classpath.ClassPath;
/**
* Handles client class calls
*
* @author Clisprail
*
*/
public class BotLoader extends ASMClassLoader {
public BotLoader(ClassPath classPath, ASMClassLoader serverProvider) {
super(classPath);
}
}
@@ -6,7 +6,7 @@ import java.net.URLClassLoader;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class BuildPath { public class BuildPath {
@@ -2,22 +2,33 @@ package org.parabot.core.classpath;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.parabot.core.Directories;
import org.parabot.core.build.BuildPath; import org.parabot.core.build.BuildPath;
import org.parabot.core.io.SizeInputStream;
import org.parabot.core.ui.components.VerboseLoader;
/** /**
* *
* @author Clisprail * @author Everel
* @author Matt * @author Matt
*/ */
public class ClassPath { public class ClassPath {
@@ -38,33 +49,96 @@ public class ClassPath {
this.isJar = isJar; this.isJar = isJar;
} }
/** public void addJar(final File file) {
* Adds jar to this classpath try {
* @param jarLocation addJar(file.toURI().toURL());
*/ } catch (MalformedURLException e) {
public void addJar(final String jarLocation) { e.printStackTrace();
JarParser.parseJar(this, jarLocation); }
}
public void addJar(final URL url) {
this.lastParsed = url;
try {
addJar(url.openConnection());
} catch (IOException e) {
e.printStackTrace();
}
} }
/** /**
* Adds jar to this classpath * Adds a jar to this classpath
* @param jarLocation *
* @param url
*/ */
public void addJar(final URL jarLocation) { public void addJar(final URLConnection connection) {
JarParser.parseJar(this, jarLocation.toString()); try {
final int size = connection.getContentLength();
final SizeInputStream sizeInputStream = new SizeInputStream(
connection.getInputStream(), size, VerboseLoader.get());
final ZipInputStream zin = new ZipInputStream(sizeInputStream);
ZipEntry e;
while ((e = zin.getNextEntry()) != null) {
if (e.isDirectory())
continue;
if (e.getName().endsWith(".class")) {
loadClass(zin);
} else {
loadResource(e.getName(), zin);
}
VerboseLoader.setState("Downloading: " + e.getName());
}
zin.close();
} catch (IOException e) {
e.printStackTrace();
}
VerboseLoader.get().onProgressUpdate(100);
} }
/**
* Adds a jar to this classpath
*
* @param url
* - in string format
*/
public void addJar(final String url) {
try {
addJar(new URL(url));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
/**
* Whether jar files should be parsed or ignored
*
* @param enabled
*/
public void parseJarFiles(final boolean enabled) { public void parseJarFiles(final boolean enabled) {
this.parseJar = enabled; this.parseJar = enabled;
} }
/**
* Finds and loads all classes/jar files in folder
* @param directory
*/
public void addClasses(final File directory) {
if(directory == null || !directory.isDirectory()) {
throw new IllegalArgumentException("Not a valid directory.");
}
addClasses(directory, null);
}
/** /**
* Finds and loads all classes/jar files in folder * Finds and loads all classes/jar files in folder
* *
* @param file to find class / jar files * @param file
* to find class / jar files
* @param root * @param root
*/ */
public void loadClasses(final File f, File root) { public void addClasses(final File f, File root) {
if (f == null) if (f == null)
return; return;
if (!f.exists()) { if (!f.exists()) {
@@ -77,21 +151,22 @@ public class ClassPath {
if (f1 == null) { if (f1 == null) {
continue; continue;
} else if (f1.isDirectory()) { } else if (f1.isDirectory()) {
loadClasses(f1, root); addClasses(f1, root);
} else { } else {
try (FileInputStream fin = new FileInputStream(f1)) { try (FileInputStream fin = new FileInputStream(f1)) {
if (f1.getName().endsWith(".class")) if (f1.getName().endsWith(".class"))
loadClass(fin); loadClass(fin);
else if (f.equals(root) && f1.getName().endsWith(".jar")) { else if (f.equals(root) && f1.getName().endsWith(".jar")) {
jarFiles.add(f1.toURI().toURL()); jarFiles.add(f1.toURI().toURL());
if(this.parseJar) { if (this.parseJar) {
// if enabled, there may be problem with duplicate class names....... // if enabled, there may be problem with duplicate
loadClasses(f1.toURI().toURL()); // class names.......
addJar(f1.toURI().toURL());
} }
} else { } else {
String path = f1.toURI().relativize(root.toURI()) String path = f1.toURI().relativize(root.toURI())
.getPath(); .getPath();
Resources.loadResource(this, path, fin); loadResource(path, fin);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -100,71 +175,114 @@ public class ClassPath {
} }
} }
/**
* Loads classes from zip/jar files
*
* @param url to file
*/
public void loadClasses(URL u) {
this.lastParsed = u;
try (ZipInputStream zin = new ZipInputStream(u.openStream())) {
ZipEntry e;
while ((e = zin.getNextEntry()) != null) {
if (e.isDirectory())
continue;
if (e.getName().endsWith(".class")) {
loadClass(zin);
} else {
Resources.loadResource(this, e.getName(), zin);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/** /**
* Loads class from input stream * Loads class from input stream
* *
* @param inputstream * @param inputstream
* @throws IOException * @throws IOException
*/ */
private void loadClass(InputStream in) throws IOException { protected void loadClass(InputStream in) throws IOException {
ClassReader cr = new ClassReader(in); ClassReader cr = new ClassReader(in);
ClassNode cn = new ClassNode(); ClassNode cn = new ClassNode();
//cr.accept(cn, 0);
cr.accept(cn, 0); cr.accept(cn, 0);
//cr.accept(cn, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
classes.put(cn.name, cn); classes.put(cn.name, cn);
} }
/** /**
* Dumps the classnodes into a jar * Determines if this classpath represents a jar file
* *
* @param jarName * @return if this classpath represents a jar file
*/ */
public void dump(final String jarName) {
JarDumper.dump(this, jarName);
}
public boolean isJar() { public boolean isJar() {
return isJar; return isJar;
} }
/**
* Gets all jar files in this classpath
*
* @return array of classpath
*/
public ClassPath[] getJarFiles() { public ClassPath[] getJarFiles() {
final ClassPath[] jars = new ClassPath[jarFiles.size()]; final ClassPath[] jars = new ClassPath[jarFiles.size()];
for(int i = 0; i < jarFiles.size(); i++) { for (int i = 0; i < jarFiles.size(); i++) {
final ClassPath classPath = new ClassPath(true); final ClassPath classPath = new ClassPath(true);
classPath.loadClasses(jarFiles.get(i)); classPath.addJar(jarFiles.get(i));
jars[i] = classPath; jars[i] = classPath;
} }
return jars; return jars;
} }
/**
* Dumps a resource from a input stream
*
* @param classPath
* @param name
* @param inputstream
* @throws IOException
*/
private void loadResource(final String name, final InputStream in)
throws IOException {
final File f = File.createTempFile("bot", ".tmp",
Directories.getTempDirectory());
f.deleteOnExit();
try (OutputStream out = new FileOutputStream(f)) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1)
out.write(buffer, 0, len);
} catch (IOException e) {
}
this.resources.put(name, f.toURI().toURL());
}
/**
* Adds this jar to buildpath
*/
public void addToBuildPath() { public void addToBuildPath() {
BuildPath.add(lastParsed); BuildPath.add(lastParsed);
} }
/**
* Dump this classPath classes to a jar file
*
* @param fileName
*/
public void dump(final String fileName) {
dump(new File(fileName));
}
/**
* Dump this classPath classes to a jar file
*
* @param file
*/
public void dump(final File file) {
try {
dump(new FileOutputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
* Dumps this classPath classes to a jar file
* @param stream
*/
public void dump(final FileOutputStream stream) {
try {
JarOutputStream out = new JarOutputStream(stream);
for (ClassNode cn : this.classes.values()) {
JarEntry je = new JarEntry(cn.name + ".class");
out.putNextEntry(je);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cn.accept(cw);
out.write(cw.toByteArray());
}
out.close();
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} }
@@ -1,41 +0,0 @@
package org.parabot.core.classpath;
import java.io.File;
import java.io.FileOutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
/**
*
* @author Clisprail
*
*/
public class JarDumper {
/**
* Dumps classnodes to a jar file
* @param classPath
* @param fileName
*/
public static void dump(final ClassPath classPath, final String fileName) {
try {
FileOutputStream stream = new FileOutputStream(new File(fileName));
JarOutputStream out = new JarOutputStream(stream);
for (ClassNode cn : classPath.classes.values()) {
JarEntry je = new JarEntry(cn.name + ".class");
out.putNextEntry(je);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cn.accept(cw);
out.write(cw.toByteArray());
}
out.close();
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,51 +0,0 @@
package org.parabot.core.classpath;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
/**
*
* A class for parsing a jar file
*
* @author Clisprail
*
*/
public class JarParser {
/**
* Parses a jar from an URL
* @param classPath
* @param jarLocation
*/
public static void parseJar(final ClassPath classPath, final String jarLocation) {
try {
URL jarURL = new URL("jar:" + jarLocation + "!/");
JarURLConnection jarConnection = (JarURLConnection) jarURL
.openConnection();
JarFile theJar = jarConnection.getJarFile();
Enumeration<?> en = theJar.entries();
while (en.hasMoreElements()) {
JarEntry entry = (JarEntry) en.nextElement();
if (entry.getName().endsWith(".class")) {
ClassReader cr = new ClassReader(
theJar.getInputStream(entry));
ClassNode cn = new ClassNode();
cr.accept(cn, 0);
classPath.classes.put(cn.name, cn);
} else if (!entry.isDirectory()
&& !entry.getName().startsWith("META-INF")) {
Resources.loadResource(classPath, entry.getName(), theJar.getInputStream(entry));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,39 +0,0 @@
package org.parabot.core.classpath;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.parabot.core.Directories;
/**
*
* @author Clisprail
* @author Matt
*/
public class Resources {
/**
* Dumps a resource from a input stream
* @param classPath
* @param name
* @param inputstream
* @throws IOException
*/
public static void loadResource(final ClassPath classPath, final String name, final InputStream in)
throws IOException {
File f = File.createTempFile("bot", ".tmp", Directories.getTempDirectory());
f.deleteOnExit();
try (OutputStream out = new FileOutputStream(f)) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1)
out.write(buffer, 0, len);
} catch (IOException e) {
}
classPath.resources.put(name, f.toURI().toURL());
}
}
@@ -1,5 +1,11 @@
package org.parabot.core.desc; package org.parabot.core.desc;
/**
* Holds information about a script
*
* @author Everel
*
*/
public class ScriptDescription { public class ScriptDescription {
public String scriptName = null; public String scriptName = null;
public String author = null; public String author = null;
@@ -7,19 +13,122 @@ public class ScriptDescription {
public double version = 0; public double version = 0;
public String description = null; public String description = null;
public String[] servers = null; public String[] servers = null;
public int scriptIndex = -1; public String isVip = null;
public String isPremium = null;
public int sdnId = -1;
public String jarName = null;
/**
* The ScriptManifest
*
* @param scriptName
* @param author
* @param category
* @param version
* @param description
* @param servers
*/
public ScriptDescription(final String scriptName, final String author, public ScriptDescription(final String scriptName, final String author,
final String category, final double version, final String category, final double version,
final String description, final String[] servers, final String description, final String[] servers) {
final int scriptIndex) { this(scriptName, author, category, version, description, servers, null,
null, -1, null);
}
/**
* Used for SDN script (see SDNScripts parser)
*
* @param jarName
* @param scriptName
* @param author
* @param category
* @param version
* @param description
* @param servers
* @param sdnId
*/
public ScriptDescription(final String jarName, final String scriptName,
final String author, final String category, final double version,
final String description, final String[] servers, final int sdnId) {
this(scriptName, author, category, version, description, servers, null,
null, sdnId, jarName);
}
/**
* Used by bot (java scripts and python scripts) and SDN Manager (sdn
* manager is a private program)
*
* @param scriptName
* @param author
* @param category
* @param version
* @param description
* @param servers
* @param vip
* @param premium
*/
public ScriptDescription(final String scriptName, final String author,
final String category, final double version,
final String description, final String[] servers, final String vip,
final String premium) {
this(scriptName, author, category, version, description, servers, vip,
premium, -1, null);
}
/**
* Main constructor
*
* @param scriptName
* @param author
* @param category
* @param version
* @param description
* @param servers
* @param vip
* @param premium
* @param sdnId
* @param jarName
*/
public ScriptDescription(final String scriptName, final String author,
final String category, final double version,
final String description, final String[] servers, final String vip,
final String premium, final int sdnId, final String jarName) {
this.scriptName = scriptName; this.scriptName = scriptName;
this.author = author; this.author = author;
this.category = category; this.category = category;
this.version = version; this.version = version;
this.description = description; this.description = description;
this.servers = servers; this.servers = servers;
this.scriptIndex = scriptIndex; this.isVip = vip;
this.isPremium = premium;
this.sdnId = sdnId;
this.jarName = jarName;
} }
@Override
public String toString() {
final StringBuilder b = new StringBuilder();
b.append("[name: ").append(this.scriptName).append(", author: ")
.append(this.author).append(", category: ")
.append(this.category).append(", version: ")
.append(this.version).append(", description: ")
.append(this.description).append(", servers: ");
for (int i = 0; i < this.servers.length; i++) {
b.append(this.servers[i]);
if (i < (this.servers.length - 1)) {
b.append(" ");
}
}
b.append(", vip: ")
.append(this.isVip == null ? "unknown" : this.isVip)
.append(", premium: ")
.append(this.isPremium == null ? "unknown" : this.isPremium)
.append(", sdn id: ")
.append(this.sdnId == -1 ? "unknown" : Integer
.toString(this.sdnId)).append(", jarname: ")
.append(this.jarName == null ? "unknown" : this.jarName)
.append("]");
return b.toString();
}
} }
@@ -1,16 +1,25 @@
package org.parabot.core.desc; package org.parabot.core.desc;
/**
*
* @author Everel
*
*/
public class ServerDescription { public class ServerDescription {
public String serverName = null; public String serverName = null;
public String author = null; public String author = null;
public int revision = 0; public double revision = 0;
public int providerIndex = -1;
public ServerDescription(final String serverName, final String author, final int revision, final int providerIndex) { public ServerDescription(final String serverName, final String author,
final double revision) {
this.serverName = serverName; this.serverName = serverName;
this.author = author; this.author = author;
this.revision = revision; this.revision = revision;
this.providerIndex = providerIndex; }
@Override
public String toString() {
return String.format("[Server: %s, Author: %s, Revision: %.1f]", this.serverName, this.author, this.revision);
} }
} }
@@ -0,0 +1,42 @@
package org.parabot.core.forum;
/**
*
* Class which holds parabot forum account user and pass, only specific classes
* have access to it unless it's a modified version of parabot intended to
* steal user information.
*
* @author Everel
*
*/
public class Account {
private String username = null;
private String password = null;
/**
*
* @param username - UTF-8 encoded forum account username
* @param password - UTF-8 encoded forum account password
*/
public Account(final String username, final String password) {
this.username = username;
this.password = password;
}
/**
* Gets user's parabot account name
* @return username, already URL UTF-8 encoded.
*/
public String getUsername() {
return this.username;
}
/**
* Gets user's parabot password
* @return password, already URL UTF-8 encoded.
*/
public String getPassword() {
return this.password;
}
}
@@ -0,0 +1,76 @@
package org.parabot.core.forum;
import java.net.URLEncoder;
import java.util.ArrayList;
import org.parabot.core.Configuration;
import org.parabot.core.Core;
import org.parabot.core.parsers.scripts.SDNScripts;
import org.parabot.core.ui.LoginUI;
import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.scripts.SDNScriptExecuter;
/**
* Handles logging in to parabot forum, only certain classes may use this class.
*
* @author Everel
*
*/
public final class AccountManager {
private static boolean validated = false;
private static AccountManager instance = null;
private Account account = null;
private AccountManager() {
}
public static final void validate() {
if (validated) {
return;
}
instance = new AccountManager();
Core.verbose("Initializing account manager accessors...");
final ArrayList<AccountManagerAccess> accessors = new ArrayList<AccountManagerAccess>();
accessors.add(SDNScripts.MANAGER_FETCHER);
accessors.add(LoginUI.MANAGER_FETCHER);
accessors.add(SDNScriptExecuter.MANAGER_FETCHER);
for (final AccountManagerAccess accessor : accessors) {
accessor.setManager(instance);
}
Core.verbose("Account managers initialized.");
}
public final boolean isLoggedIn() {
return account != null;
}
public final Account getAccount() {
return account;
}
public final boolean login(final String user, final String pass) {
if (account != null) {
throw new IllegalStateException("Already logged in.");
}
String contents = null;
try {
contents = WebUtil.getContents(String.format(
Configuration.LOGIN_SERVER,
URLEncoder.encode(user, "UTF-8"),
URLEncoder.encode(pass, "UTF-8")));
} catch (Throwable t) {
return false;
}
if (contents.equals("correct")) {
account = new Account(user, pass);
return true;
}
return false;
}
}
@@ -0,0 +1,7 @@
package org.parabot.core.forum;
public interface AccountManagerAccess {
public void setManager(AccountManager manager);
}
@@ -0,0 +1,9 @@
package org.parabot.core.io;
public interface ProgressListener {
public void onProgressUpdate(double value);
public void updateDownloadSpeed(double mbPerSecond);
}
@@ -0,0 +1,63 @@
package org.parabot.core.io;
import java.io.IOException;
import java.io.InputStream;
public class SizeInputStream extends InputStream {
private InputStream in = null;
private double size = 0;
public int bytesRead = 0;
private ProgressListener l;
private long startTime = 0L;
public SizeInputStream(InputStream in, int size, ProgressListener l) {
this.in = in;
this.size = size;
this.l = l;
this.startTime = System.currentTimeMillis();
}
public int available() {
return ((int) size - bytesRead);
}
public int read() throws IOException {
int b = in.read();
if (b != -1) {
bytesRead++;
}
updateListener();
return b;
}
public int read(byte[] b) throws IOException {
int read = in.read(b);
bytesRead += read;
updateListener();
return read;
}
public int read(byte[] b, int off, int len) throws IOException {
int read = in.read(b, off, len);
bytesRead += read;
updateListener();
return read;
}
private void updateListener() {
if(l != null) {
double percent = ( bytesRead / size) * 100.0D;
l.onProgressUpdate(percent);
long curTime = System.currentTimeMillis();
double timeSeconds = (curTime - startTime) / 1000.0D;
double speed = bytesRead / (1024.0D * 1024.0D) / timeSeconds;
l.updateDownloadSpeed(speed);
}
}
}
@@ -0,0 +1,89 @@
package org.parabot.core.jython;
import java.io.File;
import java.net.URL;
import org.parabot.core.Core;
import org.parabot.core.Directories;
import org.parabot.core.build.BuildPath;
/**
*
* @author Everel
*
*/
public class Jython {
private static boolean valid = false;
/**
* Determines if jython jar has been downloaded.
* @return <b>false</b> if jython jar has not been downloaded.....
*/
public static final boolean hasJar() {
return getJarFile().exists();
}
/**
* Adds the jython jar to the build path
*/
public static void init() {
if(!hasJar()) {
System.err.println("Failed to load jython... [jar missing]");
return;
}
Core.verbose("Adding jyton jar file to build path: " + getLocalJarFile().getPath());
BuildPath.add(getLocalJarFile());
try {
Class.forName("org.python.Version");
valid = true;
} catch (ClassNotFoundException e) {
System.err.println("Failed to add jython to build path, or incorrupt download");
}
Core.verbose("Jython initialized.");
}
/**
* Determines if jython jar has been successfully added to the buildpath
* @return if jython jar was successfully added to the buildpath
*/
public static boolean isValid() {
return valid;
}
/**
* Gets jython's local jar file
* @return file
*/
public static final File getJarFile() {
return new File(Directories.getCachePath(), "jython.jar");
}
/**
* Gets jython's local jar file in URL format
* @return URL
*/
public static final URL getLocalJarFile() {
try {
return getJarFile().toURI().toURL();
} catch (Throwable t ) {
t.printStackTrace();
}
return null;
}
/**
* Location where jython jar is located on the parabot site
* @return URL
*/
public static final URL getDownloadLink() {
try {
return new URL("http://bot.parabot.org/libs/jython.jar");
} catch (Throwable t ) {
t.printStackTrace();
}
return null;
}
}
@@ -7,13 +7,11 @@ import java.util.logging.LogRecord;
import javax.swing.JLabel; import javax.swing.JLabel;
public class LabelLogHandler extends Handler public class LabelLogHandler extends Handler {
{
public final JLabel label = new JLabel(); public final JLabel label = new JLabel();
private final Color defaultColor; private final Color defaultColor;
public LabelLogHandler() public LabelLogHandler() {
{
super(); super();
defaultColor = label.getForeground(); defaultColor = label.getForeground();
} }
@@ -1,6 +1,7 @@
package org.parabot.core.logging; package org.parabot.core.logging;
import java.util.logging.ConsoleHandler; import java.util.logging.ConsoleHandler;
import java.util.logging.LogRecord;
/** /**
* Logs to System.out * Logs to System.out
@@ -10,4 +11,10 @@ public class SystemConsoleHandler extends ConsoleHandler {
super(); super();
setOutputStream(System.out); setOutputStream(System.out);
} }
@Override
public void publish(final LogRecord logRecord) {
System.out.println("PUBLISH");
System.out.println(logRecord.getMessage());
}
} }
@@ -10,7 +10,7 @@ import org.parabot.core.Context;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class PaintDebugger { public class PaintDebugger {
@@ -9,8 +9,10 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.parabot.core.asm.adapters.AddInterfaceAdapter; import org.parabot.core.asm.adapters.AddInterfaceAdapter;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
import org.parabot.core.asm.wrappers.Callback;
import org.parabot.core.asm.wrappers.Getter; import org.parabot.core.asm.wrappers.Getter;
import org.parabot.core.asm.wrappers.Interface; import org.parabot.core.asm.wrappers.Interface;
import org.parabot.core.asm.wrappers.Invoker;
import org.parabot.core.asm.wrappers.Setter; import org.parabot.core.asm.wrappers.Setter;
import org.parabot.core.asm.wrappers.Super; import org.parabot.core.asm.wrappers.Super;
import org.parabot.environment.api.utils.WebUtil; import org.parabot.environment.api.utils.WebUtil;
@@ -21,9 +23,10 @@ import org.w3c.dom.NodeList;
/** /**
* *
* Parses an XML files which injects the hooks and other bytecode manipulation methods * Parses an XML files which injects the hooks and other bytecode manipulation
* methods
* *
* @author Clisprail * @author Everel
* *
*/ */
public class HookParser { public class HookParser {
@@ -35,11 +38,12 @@ public class HookParser {
public HookParser(URL url) { public HookParser(URL url) {
try { try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(WebUtil.getInputStream(url)); doc = dBuilder.parse(WebUtil.getInputStream(url));
doc.getDocumentElement().normalize(); doc.getDocumentElement().normalize();
if(!doc.getDocumentElement().getNodeName().equals("injector")) { if (!doc.getDocumentElement().getNodeName().equals("injector")) {
throw new RuntimeException("Incorrect hook file."); throw new RuntimeException("Incorrect hook file.");
} }
} catch (Throwable t) { } catch (Throwable t) {
@@ -49,28 +53,30 @@ public class HookParser {
public final Interface[] getInterfaces() { public final Interface[] getInterfaces() {
parsedInterfaces = true; parsedInterfaces = true;
final NodeList interfaceRootList = doc.getElementsByTagName("interfaces"); final NodeList interfaceRootList = doc
switch(interfaceRootList.getLength()) { .getElementsByTagName("interfaces");
switch (interfaceRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException("Hook file may not contains multiple <interfaces> tags "); throw new RuntimeException(
"Hook file may not contains multiple <interfaces> tags ");
} }
final Node node = interfaceRootList.item(0); final Node node = interfaceRootList.item(0);
if(node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element interfaceRoot = (Element) node; final Element interfaceRoot = (Element) node;
final NodeList interfaces = interfaceRoot.getElementsByTagName("add"); final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
if(interfaces.getLength() == 0) { if (interfaces.getLength() == 0) {
return null; return null;
} }
final ArrayList<Interface> interfaceList = new ArrayList<Interface>(); final ArrayList<Interface> interfaceList = new ArrayList<Interface>();
for(int x = 0; x < interfaces.getLength(); x++) { for (int x = 0; x < interfaces.getLength(); x++) {
final Node n = interfaces.item(x); final Node n = interfaces.item(x);
if(n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addInterface = (Element) n; final Element addInterface = (Element) n;
@@ -85,27 +91,28 @@ public class HookParser {
public final Super[] getSupers() { public final Super[] getSupers() {
final NodeList interfaceRootList = doc.getElementsByTagName("supers"); final NodeList interfaceRootList = doc.getElementsByTagName("supers");
switch(interfaceRootList.getLength()) { switch (interfaceRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException("Hook file may not contains multiple <supers> tags "); throw new RuntimeException(
"Hook file may not contains multiple <supers> tags ");
} }
final Node node = interfaceRootList.item(0); final Node node = interfaceRootList.item(0);
if(node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element superRoot = (Element) node; final Element superRoot = (Element) node;
final NodeList supers = superRoot.getElementsByTagName("add"); final NodeList supers = superRoot.getElementsByTagName("add");
if(supers.getLength() == 0) { if (supers.getLength() == 0) {
return null; return null;
} }
final ArrayList<Super> superList = new ArrayList<Super>(); final ArrayList<Super> superList = new ArrayList<Super>();
for(int x = 0; x < supers.getLength(); x++) { for (int x = 0; x < supers.getLength(); x++) {
final Node n = supers.item(x); final Node n = supers.item(x);
if(n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addSuper = (Element) n; final Element addSuper = (Element) n;
@@ -119,57 +126,70 @@ public class HookParser {
public final Getter[] getGetters() { public final Getter[] getGetters() {
final NodeList getterRootList = doc.getElementsByTagName("getters"); final NodeList getterRootList = doc.getElementsByTagName("getters");
switch(getterRootList.getLength()) { switch (getterRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException("Hook file may not contains multiple <getters> tags "); throw new RuntimeException(
"Hook file may not contains multiple <getters> tags ");
} }
final Node node = getterRootList.item(0); final Node node = getterRootList.item(0);
if(node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element getterRoot = (Element) node; final Element getterRoot = (Element) node;
final NodeList getters = getterRoot.getElementsByTagName("add"); final NodeList getters = getterRoot.getElementsByTagName("add");
if(getters.getLength() == 0) { if (getters.getLength() == 0) {
return null; return null;
} }
final ArrayList<Getter> getterList = new ArrayList<Getter>(); final ArrayList<Getter> getterList = new ArrayList<Getter>();
for(int x = 0; x < getters.getLength(); x++) { for (int x = 0; x < getters.getLength(); x++) {
final Node n = getters.item(x); final Node n = getters.item(x);
if(n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addGetter = (Element) n; final Element addGetter = (Element) n;
if(isSet("classname", addGetter) && isSet("accessor", addGetter)) { if (isSet("classname", addGetter) && isSet("accessor", addGetter)) {
throw new RuntimeException("Can't set classname and accessor tag together."); throw new RuntimeException(
"Can't set classname and accessor tag together.");
} }
if(isSet("accessor", addGetter) && !parsedInterfaces) { if (isSet("accessor", addGetter) && !parsedInterfaces) {
throw new RuntimeException("You'll need to parse interfaces first."); 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 className = isSet("classname", addGetter) ? getValue(
final String into = isSet("into", addGetter) ? getValue("into", addGetter) : className; "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 fieldName = getValue("field", addGetter);
final String methodName = getValue("methodname", addGetter); final String methodName = getValue("methodname", addGetter);
boolean staticMethod = isSet("methstatic", addGetter) ? (getValue("methstatic", addGetter).equals("true")) : false; boolean staticMethod = isSet("methstatic", addGetter) ? (getValue(
String returnDesc = isSet("desc", addGetter) ? getValue("desc", addGetter) : null; "methstatic", addGetter).equals("true")) : false;
String returnDesc = isSet("desc", addGetter) ? getValue("desc",
addGetter) : null;
String array = ""; String array = "";
if(returnDesc != null && returnDesc.contains("%s")) { if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
if(returnDesc.startsWith("[")) { if (returnDesc.startsWith("[")) {
for( int i=0; i<returnDesc.length(); i++ ) { for (int i = 0; i < returnDesc.length(); i++) {
if( returnDesc.charAt(i) == '[' ) { if (returnDesc.charAt(i) == '[') {
array += '['; array += '[';
} }
} }
returnDesc = returnDesc.replaceAll("\\[", ""); returnDesc = returnDesc.replaceAll("\\[", "");
} }
str.append(array).append('L').append(String.format(returnDesc, AddInterfaceAdapter.getAccessorPackage())).append(";"); str.append(array)
.append('L')
.append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage()))
.append(";");
returnDesc = str.toString(); returnDesc = str.toString();
} }
final Getter get = new Getter(into, className, fieldName, methodName, returnDesc, staticMethod); final Getter get = new Getter(into, className, fieldName,
methodName, returnDesc, staticMethod);
getterList.add(get); getterList.add(get);
} }
return getterList.toArray(new Getter[getterList.size()]); return getterList.toArray(new Getter[getterList.size()]);
@@ -178,126 +198,283 @@ public class HookParser {
public Injectable[] getInjectables() { public Injectable[] getInjectables() {
ArrayList<Injectable> injectables = new ArrayList<Injectable>(); ArrayList<Injectable> injectables = new ArrayList<Injectable>();
Interface[] interfaces = getInterfaces(); Interface[] interfaces = getInterfaces();
if(interfaces != null) { if (interfaces != null) {
for(Interface inf : interfaces) { for (Interface inf : interfaces) {
injectables.add(inf); injectables.add(inf);
} }
} }
Getter[] getters = getGetters(); Getter[] getters = getGetters();
if(getters != null) { if (getters != null) {
for(Getter get : getters) { for (Getter get : getters) {
injectables.add(get); injectables.add(get);
} }
} }
Setter[] setters = getSetters(); Setter[] setters = getSetters();
if(setters != null) { if (setters != null) {
for(Setter set : setters) { for (Setter set : setters) {
injectables.add(set); injectables.add(set);
} }
} }
Super[] supers = getSupers(); Super[] supers = getSupers();
if(supers != null) { if (supers != null) {
for(Super sup : supers) { for (Super sup : supers) {
injectables.add(sup); injectables.add(sup);
} }
} }
Invoker[] invokers = getInvokers();
if (invokers != null) {
for (Invoker vok : invokers) {
injectables.add(vok);
}
}
Callback[] callbacks = getCallbacks();
if (callbacks != null) {
for (Callback callback : callbacks) {
injectables.add(callback);
}
}
return injectables.toArray(new Injectable[injectables.size()]); return injectables.toArray(new Injectable[injectables.size()]);
} }
public final Setter[] getSetters() { public final Setter[] getSetters() {
final NodeList setterRootList = doc.getElementsByTagName("setters"); final NodeList setterRootList = doc.getElementsByTagName("setters");
switch(setterRootList.getLength()) { switch (setterRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException("Hook file may not contains multiple <setters> tags "); throw new RuntimeException(
"Hook file may not contains multiple <setters> tags ");
} }
final Node node = setterRootList.item(0); final Node node = setterRootList.item(0);
if(node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element setterRoot = (Element) node; final Element setterRoot = (Element) node;
final NodeList setters = setterRoot.getElementsByTagName("add"); final NodeList setters = setterRoot.getElementsByTagName("add");
if(setters.getLength() == 0) { if (setters.getLength() == 0) {
return null; return null;
} }
final ArrayList<Setter> setterList = new ArrayList<Setter>(); final ArrayList<Setter> setterList = new ArrayList<Setter>();
for(int x = 0; x < setters.getLength(); x++) { for (int x = 0; x < setters.getLength(); x++) {
final Node n = setters.item(x); final Node n = setters.item(x);
if(n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addSetter = (Element) n; final Element addSetter = (Element) n;
if(isSet("classname", addSetter) && isSet("accessor", addSetter)) { if (isSet("classname", addSetter) && isSet("accessor", addSetter)) {
throw new RuntimeException("Can't set classname and accessor tag together."); throw new RuntimeException(
"Can't set classname and accessor tag together.");
} }
if(isSet("accessor", addSetter) && !parsedInterfaces) { if (isSet("accessor", addSetter) && !parsedInterfaces) {
throw new RuntimeException("You'll need to parse interfaces first."); throw new RuntimeException(
"You'll need to parse interfaces first.");
} }
final String className = isSet("classname", addSetter) ? getValue("classname", addSetter) : interfaceMap.get(getValue("accessor", addSetter)); final String className = isSet("classname", addSetter) ? getValue(
final String into = isSet("into", addSetter) ? getValue("into", addSetter) : className; "classname", addSetter) : interfaceMap.get(getValue(
"accessor", addSetter));
final String into = isSet("into", addSetter) ? getValue("into",
addSetter) : className;
final String fieldName = getValue("field", addSetter); final String fieldName = getValue("field", addSetter);
final String methodName = getValue("methodname", addSetter); final String methodName = getValue("methodname", addSetter);
boolean staticMethod = isSet("methstatic", addSetter) ? (getValue("methstatic", addSetter).equals("true")) : false; boolean staticMethod = isSet("methstatic", addSetter) ? (getValue(
String returnDesc = isSet("desc", addSetter) ? getValue("desc", addSetter) : null; "methstatic", addSetter).equals("true")) : false;
String returnDesc = isSet("desc", addSetter) ? getValue("desc",
addSetter) : null;
String array = ""; String array = "";
if(returnDesc != null && returnDesc.contains("%s")) { if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
if(returnDesc.startsWith("[")) { if (returnDesc.startsWith("[")) {
for( int i=0; i<returnDesc.length(); i++ ) { for (int i = 0; i < returnDesc.length(); i++) {
if( returnDesc.charAt(i) == '[' ) { if (returnDesc.charAt(i) == '[') {
array += '['; array += '[';
} }
} }
returnDesc = returnDesc.replaceAll("\\[", ""); returnDesc = returnDesc.replaceAll("\\[", "");
} }
str.append(array).append('L').append(String.format(returnDesc, AddInterfaceAdapter.getAccessorPackage())).append(";"); str.append(array)
.append('L')
.append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage()))
.append(";");
returnDesc = str.toString(); returnDesc = str.toString();
} }
final Setter get = new Setter(into, className, fieldName, methodName, returnDesc, staticMethod); final Setter get = new Setter(className, into, fieldName,
methodName, returnDesc, staticMethod);
setterList.add(get); setterList.add(get);
} }
return setterList.toArray(new Setter[setterList.size()]); return setterList.toArray(new Setter[setterList.size()]);
} }
public final Invoker[] getInvokers() {
final NodeList invokerRootList = doc.getElementsByTagName("invokers");
switch (invokerRootList.getLength()) {
case 0:
return null;
case 1:
break;
default:
throw new RuntimeException(
"Hook file may not contains multiple <invokers> tags ");
}
final Node node = invokerRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) {
return null;
}
final Element invokerRoot = (Element) node;
final NodeList invokers = invokerRoot.getElementsByTagName("add");
if (invokers.getLength() == 0) {
return null;
}
final ArrayList<Invoker> invokerList = new ArrayList<Invoker>();
for (int x = 0; x < invokers.getLength(); x++) {
final Node n = invokers.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
final Element addInvoker = (Element) n;
if (isSet("classname", addInvoker) && isSet("accessor", addInvoker)) {
throw new RuntimeException(
"Can't set classname and accessor tag together.");
}
if (isSet("accessor", addInvoker) && !parsedInterfaces) {
throw new RuntimeException(
"You'll need to parse interfaces first.");
}
final String className = isSet("classname", addInvoker) ? getValue(
"classname", addInvoker) : interfaceMap.get(getValue(
"accessor", addInvoker));
final String into = isSet("into", addInvoker) ? getValue("into",
addInvoker) : className;
final String methodName = getValue("methodname", addInvoker);
final String invMethodName = getValue("invokemethod", addInvoker);
final String argsDesc = getValue("argsdesc", addInvoker);
String returnDesc = isSet("desc", addInvoker) ? resolveDesc(getValue(
"desc", addInvoker)) : null;
final Invoker invoker = new Invoker(into, className, invMethodName,
argsDesc, returnDesc, methodName);
invokerList.add(invoker);
}
return invokerList.toArray(new Invoker[invokerList.size()]);
}
public final Callback[] getCallbacks() {
final NodeList callbackRootList = doc.getElementsByTagName("callbacks");
switch (callbackRootList.getLength()) {
case 0:
return null;
case 1:
break;
default:
throw new RuntimeException(
"Hook file may not contains multiple <callbacks> tags ");
}
final Node node = callbackRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) {
return null;
}
final Element callbackRoot = (Element) node;
final NodeList callbacks = callbackRoot.getElementsByTagName("add");
if (callbacks.getLength() == 0) {
return null;
}
final ArrayList<Callback> callbackList = new ArrayList<Callback>();
for (int x = 0; x < callbacks.getLength(); x++) {
final Node n = callbacks.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
final Element addCallback = (Element) n;
if (isSet("classname", addCallback)
&& isSet("accessor", addCallback)) {
throw new RuntimeException(
"Can't set classname and accessor tag together.");
}
if (isSet("accessor", addCallback) && !parsedInterfaces) {
throw new RuntimeException(
"You'll need to parse interfaces first.");
}
final String className = isSet("classname", addCallback) ? getValue(
"classname", addCallback) : interfaceMap.get(getValue(
"accessor", addCallback));
final String methodName = getValue("methodname", addCallback);
final String callClass = getValue("callclass", addCallback);
final String callMethod = getValue("callmethod", addCallback);
final String callDesc = getValue("calldesc", addCallback);
final String callArgs = getValue("callargs", addCallback);
final String desc = getValue("desc", addCallback);
final Callback callback = new Callback(className, methodName, desc,
callClass, callMethod, callDesc, callArgs);
callbackList.add(callback);
}
return callbackList.toArray(new Callback[callbackList.size()]);
}
private static String resolveDesc(String returnDesc) {
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();
}
return returnDesc;
}
private static final boolean isSet(String tag, Element element) { private static final boolean isSet(String tag, Element element) {
return element.getElementsByTagName(tag).getLength() > 0; return element.getElementsByTagName(tag).getLength() > 0;
} }
private static final String getValue(String tag, Element element) { private static final String getValue(String tag, Element element) {
NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes(); NodeList nodes = element.getElementsByTagName(tag).item(0)
.getChildNodes();
Node node = (Node) nodes.item(0); Node node = (Node) nodes.item(0);
return node.getNodeValue(); return node.getNodeValue();
} }
public final HashMap<String, String> getConstants() { public final HashMap<String, String> getConstants() {
if(!constants.isEmpty()) { if (!constants.isEmpty()) {
return constants; return constants;
} }
final NodeList constantsRootList = doc.getElementsByTagName("constants"); final NodeList constantsRootList = doc
switch(constantsRootList.getLength()) { .getElementsByTagName("constants");
switch (constantsRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException("Hook file may not contains multiple <constants> tags "); throw new RuntimeException(
"Hook file may not contains multiple <constants> tags ");
} }
final Node node = constantsRootList.item(0); final Node node = constantsRootList.item(0);
if(node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element constantRoot = (Element) node; final Element constantRoot = (Element) node;
final NodeList constantsList = constantRoot.getElementsByTagName("add"); final NodeList constantsList = constantRoot.getElementsByTagName("add");
if(constantsList.getLength() == 0) { if (constantsList.getLength() == 0) {
// return empty hashmap // return empty hashmap
return constants; return constants;
} }
for(int x = 0; x < constantsList.getLength(); x++) { for (int x = 0; x < constantsList.getLength(); x++) {
final Node n = constantsList.item(x); final Node n = constantsList.item(x);
if(n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addConstant = (Element) n; final Element addConstant = (Element) n;
@@ -308,6 +485,4 @@ public class HookParser {
return constants; return constants;
} }
} }
@@ -1,118 +0,0 @@
package org.parabot.core.parsers;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.parabot.core.Core;
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.ServerProvider;
import org.parabot.environment.servers.loader.ServerLoader;
/**
*
* @author Clisprail
*
*/
public class ServerManifestParser {
public static Map<ServerDescription, ServerCache> cache = new HashMap<ServerDescription, ServerCache>();
/**
* Gets server descriptions
*
* @return list of descriptions
*/
public ServerDescription[] getDescriptions() {
if (Core.inDebugMode()) {
return localDesc();
}
return publicDesc();
}
private ServerDescription[] publicDesc() {
return null;
}
private ServerDescription[] localDesc() {
// parse classes in server directories
final ClassPath basePath = new ClassPath();
basePath.parseJarFiles(false);
basePath.loadClasses(Directories.getServerPath(), null);
ArrayList<ClassPath> classPaths = new ArrayList<ClassPath>();
classPaths.add(basePath);
for (final ClassPath classPath : basePath.getJarFiles()) {
classPaths.add(classPath);
}
// list of descriptions
final List<ServerDescription> allDescs = new ArrayList<ServerDescription>();
for (final ClassPath path : classPaths) {
final List<ServerDescription> descs = new ArrayList<ServerDescription>();
// init the server loader
final ServerLoader loader = new ServerLoader(path);
// list of providers
final List<ServerProvider> providers = new ArrayList<ServerProvider>();
// 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();
final ServerProvider server = (ServerProvider) con.newInstance();
providers.add(server);
descs.add(new ServerDescription(manifest.name(), manifest
.author(), 0, providers.size() - 1));
} catch (Throwable t) {
t.printStackTrace();
}
}
if (providers.isEmpty()) {
continue;
}
final ServerCache cachedServer = new ServerCache(loader, providers.toArray(new ServerProvider[providers.size()]));
for (final ServerDescription desc : descs) {
allDescs.add(desc);
cache.put(desc, cachedServer);
}
}
return allDescs.toArray(new ServerDescription[allDescs.size()]);
}
public class ServerCache {
private ServerLoader serverLoader = null;
private ServerProvider[] serverProviders = null;
private ServerCache(final ServerLoader serverLoader,
final ServerProvider[] serverProviders) {
this.serverLoader = serverLoader;
this.serverProviders = serverProviders;
}
public ServerLoader getLoader() {
return serverLoader;
}
public ServerProvider[] getProviders() {
return serverProviders;
}
}
}
@@ -1,52 +1,32 @@
package org.parabot.core.parsers; package org.parabot.core.parsers.scripts;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.parabot.core.Core;
import org.parabot.core.Directories; import org.parabot.core.Directories;
import org.parabot.core.classpath.ClassPath; import org.parabot.core.classpath.ClassPath;
import org.parabot.core.desc.ScriptDescription; import org.parabot.core.desc.ScriptDescription;
import org.parabot.environment.scripts.LocalScriptExecuter;
import org.parabot.environment.scripts.Script; import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest; import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.loader.ScriptLoader; import org.parabot.environment.scripts.loader.JavaScriptLoader;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class ScriptManifestParser { public class LocalJavaScripts extends ScriptParser {
public static Map<ScriptDescription, Script> scriptCache = new HashMap<ScriptDescription, Script>(); @Override
public void execute() {
/**
* Gets server descriptions
*
* @return list of descriptions
*/
public ScriptDescription[] getDescriptions() {
scriptCache.clear();
if (Core.inDebugMode()) {
return localDesc();
}
return publicDesc();
}
private ScriptDescription[] publicDesc() {
return null;
}
private ScriptDescription[] localDesc() {
// parse classes in server directories // parse classes in server directories
final ClassPath path = new ClassPath(); final ClassPath path = new ClassPath();
path.loadClasses(Directories.getScriptCompiledPath(), null); path.addClasses(Directories.getScriptCompiledPath());
// init the script loader // init the script loader
final ScriptLoader loader = new ScriptLoader(path); final JavaScriptLoader loader = new JavaScriptLoader(path);
// list of scripts // list of scripts
final List<Script> scripts = new ArrayList<Script>(); final List<Script> scripts = new ArrayList<Script>();
@@ -58,7 +38,13 @@ public class ScriptManifestParser {
for (final String className : loader.getScriptClassNames()) { for (final String className : loader.getScriptClassNames()) {
try { try {
// get class // get class
final Class<?> scriptClass = loader.loadClass(className); final Class<?> scriptClass;
try {
scriptClass = loader.loadClass(className);
} catch (NoClassDefFoundError ignored) {
// script for an other server provider
continue;
}
// get annotation // get annotation
final Object annotation = scriptClass final Object annotation = scriptClass
.getAnnotation(ScriptManifest.class); .getAnnotation(ScriptManifest.class);
@@ -72,19 +58,21 @@ public class ScriptManifestParser {
final Constructor<?> con = scriptClass.getConstructor(); final Constructor<?> con = scriptClass.getConstructor();
final Script script = (Script) con.newInstance(); final Script script = (Script) con.newInstance();
scripts.add(script); scripts.add(script);
final ScriptDescription desc = new ScriptDescription(manifest.name(), manifest final ScriptDescription desc = new ScriptDescription(
.author(), manifest.category().toString(), manifest.version(), manifest.description(), manifest.name(), manifest.author(), manifest.category()
manifest.servers(), scripts.size() - 1); .toString(), manifest.version(),
scriptCache.put(desc, script); manifest.description(), manifest.servers(),
manifest.vip() ? "yes" : "no",
manifest.premium() ? "yes" : "no");
SCRIPT_CACHE.put(desc, new LocalScriptExecuter(script));
descs.add(desc); descs.add(desc);
} catch (ClassNotFoundException ignored) {
} catch (NoClassDefFoundError ignored) {
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
} }
if (scripts.isEmpty()) {
return null;
}
return descs.toArray(new ScriptDescription[descs.size()]);
} }
} }
@@ -0,0 +1,102 @@
package org.parabot.core.parsers.scripts;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import org.parabot.core.Directories;
import org.parabot.core.desc.ScriptDescription;
import org.parabot.environment.scripts.Category;
import org.parabot.environment.scripts.LocalScriptExecuter;
import org.parabot.environment.scripts.framework.PythonScript;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
/**
*
* Parser python scripts
*
* @author Everel
*
*/
public class LocalPythonScripts extends ScriptParser {
private PythonInterpreter interpreter = new PythonInterpreter();
private static final FilenameFilter PYTHON_SCRIPT_FILTER = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".py");
}
};
/**
*
* @param name
* - local var name
* @return script instance
*/
public PythonScript getScript(String name) {
PyObject clazz = interpreter.get(name);
if (clazz.toString().startsWith("<class '__main__.")) {
final PyObject instanceClass = clazz.__call__();
final Object javaInstance = instanceClass
.__tojava__(PythonScript.class);
if (javaInstance instanceof PythonScript) {
return (PythonScript) javaInstance;
}
}
return null;
}
@Override
public void execute() {
for (final File scriptFile : Directories.getScriptSourcesPath()
.listFiles(PYTHON_SCRIPT_FILTER)) {
try {
interpreter.execfile(new FileInputStream(scriptFile));
final String name = interpreter.get("__scriptname__")
.asString();
final String author = interpreter.get("__author__").asString();
final Category cat = (Category) interpreter.get("__category__")
.__tojava__(Category.class);
final double version = interpreter.get("__version__")
.asDouble();
final String description = interpreter.get("__description__")
.asString();
final String[] servers = (String[]) interpreter.get(
"__servers__").__tojava__(String[].class);
Object ob;
String vip = "no";
if( (ob = interpreter.get("__vip__")) != null) {
final String isVip = ob.toString();
vip = isVip.equals("True") ? "yes" : "no";
}
String prem = "no";
if( (ob = interpreter.get("__premium__")) != null) {
final String isPrem = ob.toString();
prem = isPrem.equals("True") ? "yes" : "no";
}
final ScriptDescription desc = new ScriptDescription(name,
author, cat.toString(), version, description, servers, vip, prem);
for (final PyObject o : interpreter.getLocals().asIterable()) {
PythonScript script = getScript(o.asString());
if (script != null) {
SCRIPT_CACHE.put(desc, new LocalScriptExecuter(script));
break;
}
}
interpreter.cleanup();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
@@ -0,0 +1,96 @@
package org.parabot.core.parsers.scripts;
import java.io.BufferedReader;
import java.net.URL;
import org.parabot.core.Configuration;
import org.parabot.core.desc.ScriptDescription;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.forum.AccountManagerAccess;
import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.scripts.SDNScriptExecuter;
/**
*
* @author Everel
*
*/
public class SDNScripts extends ScriptParser {
private static AccountManager manager = null;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override
public final void setManager(AccountManager manager) {
SDNScripts.manager = manager;
}
};
@Override
public void execute() {
if (!manager.isLoggedIn()) {
System.err.println("Not logged in...");
return;
}
try {
BufferedReader br = WebUtil.getReader(new URL(String.format(Configuration.SDN_SCRIPTS, manager.getAccount()
.getUsername())));
int count = 0;
String line;
String jarName = null;
int sdnId = -1;
String scriptName = null;
String author = null;
double version = 0D;
String category = null;
String description = null;
String[] servers = null;
while ((line = br.readLine()) != null) {
count++;
switch (count % 8) {
case 1:
// jarname
jarName = line;
break;
case 2:
// sdn id
sdnId = Integer.parseInt(line);
break;
case 3:
scriptName = line;
break;
case 4:
author = line;
break;
case 5:
version = Double.parseDouble(line);
break;
case 6:
category = line;
break;
case 7:
description = line;
break;
case 0:
if (line.contains(", ")) {
servers = line.split(", ");
} else {
servers = new String[] { line };
}
final ScriptDescription desc = new ScriptDescription(jarName, scriptName,
author, category, version, description,
servers, sdnId);
SCRIPT_CACHE.put(desc, new SDNScriptExecuter(sdnId));
}
}
br.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
@@ -0,0 +1,50 @@
package org.parabot.core.parsers.scripts;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.parabot.core.Core;
import org.parabot.core.desc.ScriptDescription;
import org.parabot.core.jython.Jython;
import org.parabot.environment.scripts.ScriptExecuter;
/**
*
* @author Everel
*
*/
public abstract class ScriptParser {
public static final Map<ScriptDescription, ScriptExecuter> SCRIPT_CACHE = new HashMap<ScriptDescription, ScriptExecuter>();
public abstract void execute();
public static ScriptDescription[] getDescriptions() {
SCRIPT_CACHE.clear();
final ArrayList<ScriptParser> parsers = new ArrayList<ScriptParser>();
if(Core.inDebugMode()) {
parsers.add(new LocalJavaScripts());
if(Jython.isValid()) {
parsers.add(new LocalPythonScripts());
}
} else {
parsers.add(new SDNScripts());
}
Core.verbose("Parsing scripts...");
for(final ScriptParser parser : parsers) {
parser.execute();
}
if(Core.inVerboseMode()) {
for(final ScriptDescription desc : SCRIPT_CACHE.keySet()) {
Core.verbose(desc.toString());
}
Core.verbose("Scripts parsed.");
}
return SCRIPT_CACHE.keySet().toArray(new ScriptDescription[SCRIPT_CACHE.size()]);
}
}
@@ -0,0 +1,73 @@
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.LocalServerExecuter;
import org.parabot.environment.servers.ServerManifest;
import org.parabot.environment.servers.ServerProvider;
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<ClassPath> classPaths = new ArrayList<ClassPath>();
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();
final ServerProvider serverProvider = (ServerProvider) con
.newInstance();
SERVER_CACHE.put(
new ServerDescription(manifest.name(), manifest
.author(), manifest.version()),
new LocalServerExecuter(serverProvider, path,
manifest.name()));
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
}
@@ -0,0 +1,62 @@
package org.parabot.core.parsers.servers;
import java.io.BufferedReader;
import java.net.URL;
import org.parabot.core.Configuration;
import org.parabot.core.desc.ServerDescription;
import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.servers.PublicServerExecuter;
/**
*
* Parses servers hosted on parabot
*
* @author Everel
*
*/
public class PublicServers extends ServerParser {
@Override
public void execute() {
try {
BufferedReader br = WebUtil.getReader(new URL(
Configuration.GET_SERVER_PROVIDERS));
int count = 0;
String line;
String name = null;
String author = null;
double version = 0D;
while ((line = br.readLine()) != null) {
count++;
switch (count % 4) {
case 1:
// server name
name = line;
break;
case 2:
// author
author = line;
break;
case 3:
// version
version = Double.parseDouble(line);
break;
case 0:
// jarName
ServerDescription desc = new ServerDescription(name,
author, version);
SERVER_CACHE.put(desc, new PublicServerExecuter(name, line));
}
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,48 @@
package org.parabot.core.parsers.servers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.parabot.core.Core;
import org.parabot.core.desc.ServerDescription;
import org.parabot.environment.servers.ServerExecuter;
/**
*
* Abstract class for parsing server providers
*
* @author Everel
*
*/
public abstract class ServerParser {
public static final Map<ServerDescription, ServerExecuter> SERVER_CACHE = new HashMap<ServerDescription, ServerExecuter>();
public abstract void execute();
public static final ServerDescription[] getDescriptions() {
SERVER_CACHE.clear();
final ArrayList<ServerParser> parsers = new ArrayList<ServerParser>();
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.");
}
return SERVER_CACHE.keySet().toArray(new ServerDescription[SERVER_CACHE.size()]);
}
}
+12 -10
View File
@@ -14,16 +14,16 @@ import javax.swing.JPopupMenu;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JToolBar; import javax.swing.JToolBar;
import org.parabot.core.ui.applet.LoadApplet;
import org.parabot.core.ui.components.BotToolbar; import org.parabot.core.ui.components.BotToolbar;
import org.parabot.core.ui.components.GamePanel; import org.parabot.core.ui.components.GamePanel;
import org.parabot.core.ui.components.LogArea; import org.parabot.core.ui.components.LogArea;
import org.parabot.core.ui.components.VerboseLoader;
import org.parabot.core.ui.images.Images; import org.parabot.core.ui.images.Images;
import org.parabot.core.ui.utils.SwingUtil; import org.parabot.core.ui.utils.SwingUtil;
/** /**
* *
* @author Dane * @author Dane, Everel
* *
*/ */
public class BotUI extends JFrame implements ActionListener { public class BotUI extends JFrame implements ActionListener {
@@ -35,7 +35,7 @@ public class BotUI extends JFrame implements ActionListener {
return instance == null ? instance = new BotUI() : instance; return instance == null ? instance = new BotUI() : instance;
} }
public BotUI() { private BotUI() {
JPopupMenu.setDefaultLightWeightPopupEnabled(false); JPopupMenu.setDefaultLightWeightPopupEnabled(false);
this.setTitle("Parabot"); this.setTitle("Parabot");
@@ -55,10 +55,10 @@ public class BotUI extends JFrame implements ActionListener {
JMenuBar menubar = new JMenuBar(); JMenuBar menubar = new JMenuBar();
JMenu mnuFile = new JMenu("File"); JMenu mnuFile = new JMenu("File");
JMenuItem itmScreenshot = new JMenuItem("Screenshot"); JMenuItem exit = new JMenuItem("Exit");
itmScreenshot.addActionListener(this); exit.addActionListener(this);
mnuFile.add(itmScreenshot); mnuFile.add(exit);
menubar.add(mnuFile); menubar.add(mnuFile);
this.setJMenuBar(menubar); this.setJMenuBar(menubar);
@@ -84,14 +84,14 @@ public class BotUI extends JFrame implements ActionListener {
panel.add(toolbar); panel.add(toolbar);
panel.add(gamePanel); panel.add(gamePanel);
gamePanel.add(LoadApplet.get()); gamePanel.add(VerboseLoader.get());
panel.add(scrlConsole); panel.add(scrlConsole);
this.add(panel, BorderLayout.CENTER); this.add(panel, BorderLayout.CENTER);
SwingUtil.finalize(this); SwingUtil.finalize(this);
LogArea.log("Welcome to parabot v2!"); LogArea.log("parabot v2.01 started");
} }
@Override @Override
@@ -99,11 +99,13 @@ public class BotUI extends JFrame implements ActionListener {
String command = e.getActionCommand(); String command = e.getActionCommand();
switch (command) { switch (command) {
case "Screenshot": case "Exit":
LogArea.log("Boop"); System.exit(0);
break; break;
default: default:
System.out.println("Invalid command: "); System.out.println("Invalid command: ");
} }
} }
} }
@@ -0,0 +1,180 @@
package org.parabot.core.ui;
import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.net.URI;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import org.parabot.core.Core;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.forum.AccountManagerAccess;
import org.parabot.core.ui.images.Images;
import org.parabot.core.ui.utils.SwingUtil;
/**
*
* @author Everel
*
*/
public class LoginUI extends JFrame {
private static final long serialVersionUID = 2032832552863466297L;
private static LoginUI instance = null;
private JTextField txtUsername;
private JPasswordField txtPassword;
private JButton cmdLogin;
private JButton cmdRegister;
private static AccountManager manager = null;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override
public final void setManager(AccountManager manager) {
LoginUI.manager = manager;
}
};
public void attemptLogin() {
String username = txtUsername.getText();
String password = new String(txtPassword.getPassword());
if (username.length() > 0 && password.length() > 0) {
attempt(username, password);
}
}
private void attempt(String user, String pass) {
Core.verbose("Logging in...");
if (manager.login(user, pass)) {
Core.verbose("Logged in.");
instance.dispose();
Core.verbose("Running server selector.");
ServerSelector.getInstance();
} else {
Core.verbose("Failed to log in.");
JOptionPane.showMessageDialog(null,
"Incorrect username or password.", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
public LoginUI(String username, String password) {
instance = this;
attempt(username, password);
}
public LoginUI() {
instance = this;
this.setTitle("Login");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationByPlatform(true);
this.setLayout(new BorderLayout());
this.setResizable(false);
this.setIconImage(Images
.getResource("/org/parabot/core/ui/images/icon.png"));
int w = 250;
int x = 8;
int y = 64;
JPanel panel = new JPanel() {
private static final long serialVersionUID = 2258761648532714183L;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawImage(Images
.getResource("/org/parabot/core/ui/images/para.png"),
0, 8, 250, 45, null);
}
};
panel.setLayout(null);
txtUsername = new JTextField("");
txtUsername.setBounds(x, y, w - (x << 1), 26);
txtUsername.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10 || e.getKeyCode() == 13) {
txtPassword.requestFocus();
}
}
});
y += 30;
txtPassword = new JPasswordField("");
txtPassword.setBounds(x, y, w - (x << 1), 26);
txtPassword.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10 || e.getKeyCode() == 13) {
attemptLogin();
}
}
});
y += 30;
cmdLogin = new JButton("Login");
cmdLogin.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
attemptLogin();
}
});
cmdLogin.setBounds(x, y, (w - (x << 1)) / 2 - 8, 24);
cmdRegister = new JButton("Register");
cmdRegister.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
URI uri = URI
.create("http://www.parabot.org/community/index.php?app=core&module=global&section=register");
try {
Desktop.getDesktop().browse(uri);
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "Connection Error",
"Error", JOptionPane.ERROR_MESSAGE);
e1.printStackTrace();
}
}
});
cmdRegister.setBounds(x + (w - (x << 1)) / 2 + 8, y,
(w - (x << 1)) / 2 - 8, 24);
panel.add(txtUsername);
panel.add(txtPassword);
panel.add(cmdLogin);
panel.add(cmdRegister);
this.add(panel, BorderLayout.CENTER);
this.setVisible(true);
this.requestFocus();
this.setSize(255, 182);
SwingUtil.center(this);
}
}
@@ -26,16 +26,18 @@ import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeCellRenderer;
import org.parabot.core.Context; import org.parabot.core.Context;
import org.parabot.core.Core;
import org.parabot.core.Directories; import org.parabot.core.Directories;
import org.parabot.core.desc.ScriptDescription; import org.parabot.core.desc.ScriptDescription;
import org.parabot.core.parsers.ScriptManifestParser; import org.parabot.core.parsers.scripts.ScriptParser;
import org.parabot.environment.scripts.Category; import org.parabot.environment.scripts.Category;
/** /**
* @author Clisprail *
* Script Selector GUI, shows all scripts
*
* @author Everel
*/ */
public class ScriptSelector extends JFrame { public final class ScriptSelector extends JFrame {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private HashMap<String, DefaultMutableTreeNode> categories = new HashMap<String, DefaultMutableTreeNode>(); private HashMap<String, DefaultMutableTreeNode> categories = new HashMap<String, DefaultMutableTreeNode>();
private HashMap<String, ScriptDescription> format = new HashMap<String, ScriptDescription>(); private HashMap<String, ScriptDescription> format = new HashMap<String, ScriptDescription>();
@@ -44,7 +46,7 @@ public class ScriptSelector extends JFrame {
private final int WIDTH = 640; private final int WIDTH = 640;
private final int HEIGHT = 256 + 128; private final int HEIGHT = 256 + 128;
public static ScriptManifestParser parser = null; public static ScriptParser parser = null;
public ScriptSelector() { public ScriptSelector() {
model = new DefaultTreeModel(root); model = new DefaultTreeModel(root);
@@ -56,16 +58,11 @@ public class ScriptSelector extends JFrame {
dispose(); dispose();
final ThreadGroup tg = Context.threadGroups.keySet().iterator() final ThreadGroup tg = Context.threadGroups.keySet().iterator()
.next(); .next();
new Thread(tg, ScriptManifestParser.scriptCache.get(desc)).start(); ScriptParser.SCRIPT_CACHE.get(desc).run(tg);
} }
private void putScripts() { private void putScripts() {
localScripts(); final ScriptDescription[] descs = ScriptParser.getDescriptions();
}
private void localScripts() {
parser = new ScriptManifestParser();
final ScriptDescription[] descs = parser.getDescriptions();
if (descs == null) { if (descs == null) {
return; return;
} }
@@ -84,6 +81,7 @@ public class ScriptSelector extends JFrame {
} }
} }
private String getScriptName(String path) { private String getScriptName(String path) {
return path.split(", ")[2].replaceAll("\\]", ""); return path.split(", ")[2].replaceAll("\\]", "");
} }
@@ -166,14 +164,12 @@ public class ScriptSelector extends JFrame {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String s = getScriptName(tree.getSelectionPath().toString()); String s = getScriptName(tree.getSelectionPath().toString());
if (s != null) { if (s != null) {
if (Core.inDebugMode()) { runScript(format.get(s));
runScript(format.get(s));
}
} }
} }
}); });
JButton cmdHome = new JButton("Open Home"); JButton cmdHome = new JButton("Open home");
cmdHome.setBounds(WIDTH - (96 * 2) - 4 - 32, HEIGHT - 24 - 4, 96 + 32, cmdHome.setBounds(WIDTH - (96 * 2) - 4 - 32, HEIGHT - 24 - 4, 96 + 32,
24); 24);
cmdHome.addActionListener(new ActionListener() { cmdHome.addActionListener(new ActionListener() {
@@ -10,14 +10,16 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import org.parabot.core.desc.ServerDescription; import org.parabot.core.desc.ServerDescription;
import org.parabot.core.parsers.ServerManifestParser; import org.parabot.core.parsers.servers.ServerParser;
import org.parabot.core.ui.utils.SwingUtil; import org.parabot.core.ui.utils.SwingUtil;
import org.parabot.core.ui.widgets.ServerWidget; import org.parabot.core.ui.widgets.ServerWidget;
import org.parabot.environment.Environment; import org.parabot.environment.Environment;
/** /**
* *
* @author Dane, Clisprail * Shows a list of every supported server which can be started
*
* @author Dane, Everel
* *
*/ */
@@ -81,22 +83,27 @@ public class ServerSelector extends JFrame {
* @param widgets * @param widgets
*/ */
private boolean runServer(Queue<ServerWidget> widgets) { private boolean runServer(Queue<ServerWidget> widgets) {
// TODO: test this method
if(widgets == null || widgets.isEmpty()) { if(widgets == null || widgets.isEmpty()) {
return false; return false;
} }
final String serverName = initServer.toLowerCase(); final String serverName = initServer.toLowerCase();
for(ServerWidget widget : widgets) { for(ServerWidget widget : widgets) {
if(widget.desc.serverName.toLowerCase().equals(serverName)) { if(widget.desc.serverName.toLowerCase().equals(serverName)) {
Environment.load(widget.desc, widget.desc.serverName.replaceAll(" ", "")); Environment.load(widget.desc);
return true; return true;
} }
} }
return false; return false;
} }
/**
* Fetches array of server widgets
* @return widgets array
*/
public Queue<ServerWidget> getServers() { public Queue<ServerWidget> getServers() {
final Queue<ServerWidget> widgets = new LinkedList<ServerWidget>(); final Queue<ServerWidget> widgets = new LinkedList<ServerWidget>();
ServerDescription[] servers = new ServerManifestParser().getDescriptions(); ServerDescription[] servers = ServerParser.getDescriptions();
if (servers != null) { if (servers != null) {
for (ServerDescription desc : servers) { for (ServerDescription desc : servers) {
widgets.add(new ServerWidget(desc)); widgets.add(new ServerWidget(desc));
@@ -25,7 +25,7 @@ import org.parabot.environment.scripts.Script;
/** /**
* Bot toolbar * Bot toolbar
* *
* @author Clisprail * @author Everel
* *
*/ */
public class BotToolbar extends JToolBar { public class BotToolbar extends JToolBar {
@@ -8,20 +8,18 @@ import javax.swing.GroupLayout;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.parabot.core.Context; import org.parabot.core.Context;
import org.parabot.core.ui.applet.LoadApplet;
/** /**
* *
* Main panel where applets are added. * Main panel where applets are added.
* *
* @author Clisprail * @author Everel
*
* *
*/ */
public class GamePanel extends JPanel { public class GamePanel extends JPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static GamePanel instance = null; private static GamePanel instance = null;
private static LoadApplet loader = LoadApplet.get(); private static VerboseLoader loader = VerboseLoader.get();
public Context context = null; public Context context = null;
private GamePanel() { private GamePanel() {
@@ -10,11 +10,17 @@ import java.util.logging.Logger;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneConstants;
import org.parabot.core.Core;
import org.parabot.core.logging.LogFormatter; import org.parabot.core.logging.LogFormatter;
import org.parabot.core.logging.LogTextArea; import org.parabot.core.logging.LogTextArea;
import org.parabot.core.logging.SystemConsoleHandler; import org.parabot.core.logging.SystemConsoleHandler;
import org.parabot.core.logging.TextAreaLogHandler; import org.parabot.core.logging.TextAreaLogHandler;
/**
*
* @author Everel
*
*/
public class LogArea extends JScrollPane { public class LogArea extends JScrollPane {
private static final long serialVersionUID = 6571141103751675714L; private static final long serialVersionUID = 6571141103751675714L;
@@ -22,7 +28,9 @@ public class LogArea extends JScrollPane {
private static LogTextArea logArea = new LogTextArea(); private static LogTextArea logArea = new LogTextArea();
private LogArea() { private LogArea() {
super(TextAreaLogHandler.TEXT_AREA, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); super(TextAreaLogHandler.TEXT_AREA,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
setVisible(true); setVisible(true);
registerLogging(); registerLogging();
} }
@@ -54,20 +62,26 @@ public class LogArea extends JScrollPane {
} }
public void registerLogging() { public void registerLogging() {
Core.verbose("Registering logging...");
final Properties logging = new Properties(); final Properties logging = new Properties();
final String logFormatter = LogFormatter.class.getCanonicalName(); final String logFormatter = LogFormatter.class.getCanonicalName();
final String fileHandler = FileHandler.class.getCanonicalName(); final String fileHandler = FileHandler.class.getCanonicalName();
logging.setProperty("handlers", TextAreaLogHandler.class.getCanonicalName() + "," + fileHandler); logging.setProperty("handlers",
TextAreaLogHandler.class.getCanonicalName() + "," + fileHandler);
logging.setProperty(".level", "INFO"); logging.setProperty(".level", "INFO");
logging.setProperty(SystemConsoleHandler.class.getCanonicalName() + ".formatter", logFormatter); logging.setProperty(SystemConsoleHandler.class.getCanonicalName()
+ ".formatter", logFormatter);
logging.setProperty(fileHandler + ".formatter", logFormatter); logging.setProperty(fileHandler + ".formatter", logFormatter);
logging.setProperty(TextAreaLogHandler.class.getCanonicalName() + ".formatter", logFormatter); logging.setProperty(TextAreaLogHandler.class.getCanonicalName()
+ ".formatter", logFormatter);
final ByteArrayOutputStream logout = new ByteArrayOutputStream(); final ByteArrayOutputStream logout = new ByteArrayOutputStream();
try { try {
logging.store(logout, ""); logging.store(logout, "");
LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(logout.toByteArray())); LogManager.getLogManager().readConfiguration(
new ByteArrayInputStream(logout.toByteArray()));
} catch (final Exception ignored) { } catch (final Exception ignored) {
} }
Core.verbose("Done.");
} }
} }
@@ -0,0 +1,78 @@
package org.parabot.core.ui.components;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
/**
*
* @author Everel
*
*/
public class ProgressBar {
private double value = 0;
private int width = 0;
private int height = 0;
private double locX = 0;
private Color progColor = new Color(255, 0, 0);
private Color backColor = new Color(74, 74, 72, 100);
private FontMetrics fontMetrics = null;
private String text = "";
public ProgressBar(int width, int height) {
this.width = width;
this.height = height;
}
public void setText(final String text) {
this.text = text;
}
public void setValue(double value) {
if(value < 0 || value > 100) {
return;
}
if(value > 99) {
value = 100;
}
this.value = value;
this.locX = (width / 100.0D) * value;
int val = (int) value;
if (value <= 50) {
this.progColor = new Color(255, (2 * val), 0);
} else {
val -= 50;
this.progColor = new Color((int) (255 - (5.1D * val)),
100 + (2 * val), 0);
}
}
public double getValue() {
return value;
}
public void draw(Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
if (fontMetrics == null) {
fontMetrics = g2.getFontMetrics();
}
g2.setColor(backColor);
g2.fillRect(x, y, width, height);
g2.setColor(Color.DARK_GRAY);
g2.drawRect(x - 1, y - 1, width + 1, height + 1);
g2.setColor(this.progColor);
g2.fill(new Rectangle2D.Double(x, y, locX, height));
int value = (int) getValue();
String percent = Integer.toString(value) + "% " + text;
int strX = (x + (width / 2)) - (fontMetrics.stringWidth(percent) / 2);
g2.setColor(Color.white);
g2.drawString(percent, strX, y + 13);
}
}
@@ -9,7 +9,7 @@ import javax.swing.JPanel;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class ServerPanel extends JPanel { public class ServerPanel extends JPanel {
@@ -1,43 +1,45 @@
package org.parabot.core.ui.applet; package org.parabot.core.ui.components;
import java.applet.Applet;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import org.parabot.core.io.ProgressListener;
import org.parabot.core.ui.images.Images; import org.parabot.core.ui.images.Images;
/** /**
* An informative applet which tells the user what bot is doing * An informative JPanel which tells the user what bot is doing
* *
* @author Clisprail * @author Everel
* *
*/ */
public class LoadApplet extends Applet { public class VerboseLoader extends JPanel implements ProgressListener {
private static final long serialVersionUID = 7412412644921803896L; private static final long serialVersionUID = 7412412644921803896L;
private static LoadApplet current = null; private static VerboseLoader current = null;
private static String state = "Initializing loader..."; private static String state = "Initializing loader...";
private FontMetrics fontMetrics = null; private FontMetrics fontMetrics = null;
private BufferedImage bot_image = null; private BufferedImage bot_image = null;
private ProgressBar p = new ProgressBar(400, 20);
public LoadApplet() { public VerboseLoader() {
bot_image = Images.getResource("/org/parabot/core/ui/images/para.png"); bot_image = Images.getResource("/org/parabot/core/ui/images/para.png");
}
@Override
public void init() {
setSize(775, 510); setSize(775, 510);
setBackground(Color.black); setBackground(Color.black);
setDoubleBuffered(true);
setOpaque(false);
} }
/** /**
* Paints on this applet * Paints on this panel
*/ */
@Override @Override
public void paint(Graphics g) { public void paint(Graphics g) {
g.setFont(new Font("Calibri", Font.PLAIN, 18)); p.draw(g, (getWidth() / 2) - 200, 220);
g.setFont(new Font("Courier New", Font.PLAIN, 14));
if (fontMetrics == null) { if (fontMetrics == null) {
fontMetrics = g.getFontMetrics(); fontMetrics = g.getFontMetrics();
} }
@@ -54,21 +56,15 @@ public class LoadApplet extends Applet {
} }
/** /**
* Gets instance of this applet * Gets instance of this panel
* @return instance of this applet * @return instance of this panel
*/ */
public static LoadApplet get() { public static VerboseLoader get() {
if (current != null) { return current == null ? current = new VerboseLoader() : current;
return current;
}
final LoadApplet splash = new LoadApplet();
splash.init();
current = splash;
return current;
} }
/** /**
* Updates the status message and repaints the applet * Updates the status message and repaints the panel
* @param message * @param message
*/ */
public static void setState(final String message) { public static void setState(final String message) {
@@ -76,4 +72,15 @@ public class LoadApplet extends Applet {
current.repaint(); current.repaint();
} }
@Override
public void onProgressUpdate(double value) {
p.setValue(value);
this.repaint();
}
@Override
public void updateDownloadSpeed(double mbPerSecond) {
p.setText(String.format("(%.2fMB/s)", mbPerSecond));
}
} }
@@ -5,7 +5,12 @@ import java.util.HashMap;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
public class Images { /**
*
* @author Everel
*
*/
public final class Images {
private static final HashMap<String, BufferedImage> imageCache = new HashMap<String, BufferedImage>(); private static final HashMap<String, BufferedImage> imageCache = new HashMap<String, BufferedImage>();
public static BufferedImage getResource(final String resource) { public static BufferedImage getResource(final String resource) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 116 KiB

@@ -3,6 +3,11 @@ package org.parabot.core.ui.utils;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Toolkit; import java.awt.Toolkit;
/**
*
* @author Dane
*
*/
public class AwtUtil { public class AwtUtil {
private static Toolkit toolkit; private static Toolkit toolkit;
@@ -2,6 +2,11 @@ package org.parabot.core.ui.utils;
import javax.swing.JFrame; import javax.swing.JFrame;
/**
*
* @author Dane
*
*/
public class SwingUtil { public class SwingUtil {
/** /**
@@ -2,6 +2,11 @@ package org.parabot.core.ui.utils;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
/**
*
* @author Everel
*
*/
public class UILog { public class UILog {
public static void log(final String title, final String message) { public static void log(final String title, final String message) {
@@ -12,12 +12,14 @@ import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.parabot.core.desc.ServerDescription; import org.parabot.core.desc.ServerDescription;
import org.parabot.core.ui.BotUI;
import org.parabot.core.ui.ServerSelector; import org.parabot.core.ui.ServerSelector;
import org.parabot.environment.Environment; import org.parabot.environment.Environment;
/** /**
* A colorful server widget * A colorful server widget
* @author Clisprail *
* @author Everel
* *
*/ */
public class ServerWidget extends JPanel { public class ServerWidget extends JPanel {
@@ -29,7 +31,7 @@ public class ServerWidget extends JPanel {
final ActionListener play = new ActionListener() { final ActionListener play = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
load(desc, name); load(desc);
} }
}; };
@@ -41,7 +43,7 @@ public class ServerWidget extends JPanel {
l.setFont(new Font("Arial", Font.BOLD, 16)); l.setFont(new Font("Arial", Font.BOLD, 16));
l.setForeground(Color.white); l.setForeground(Color.white);
l.setText(desc.serverName); l.setText(desc.serverName);
l.setBounds(10, 10, 100, 20); l.setBounds(10, 10, 200, 20);
add(l); add(l);
final Font f = new Font("Arial", Font.PLAIN, 12); final Font f = new Font("Arial", Font.PLAIN, 12);
add(l); add(l);
@@ -85,8 +87,15 @@ public class ServerWidget extends JPanel {
g2d.fillRect(0, 0, w, h); g2d.fillRect(0, 0, w, h);
} }
public void load(final ServerDescription desc, final String serverName) { public void load(final ServerDescription desc) {
ServerSelector.getInstance().dispose(); ServerSelector.getInstance().dispose();
Environment.load(desc, serverName); BotUI.getInstance().setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
Environment.load(desc);
}
}).start();
} }
} }
@@ -1,24 +1,16 @@
package org.parabot.environment; package org.parabot.environment;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import org.parabot.core.Context; import org.parabot.core.Context;
import org.parabot.core.Core; 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.ServerDescription; import org.parabot.core.desc.ServerDescription;
import org.parabot.core.parsers.ServerManifestParser; import org.parabot.core.jython.Jython;
import org.parabot.core.parsers.ServerManifestParser.ServerCache; import org.parabot.core.parsers.servers.ServerParser;
import org.parabot.core.ui.BotUI; import org.parabot.core.ui.components.VerboseLoader;
import org.parabot.core.ui.components.BotToolbar; import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.servers.ServerProvider;
import org.parabot.environment.servers.loader.ServerLoader;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Environment { public class Environment {
@@ -28,65 +20,23 @@ public class Environment {
* *
* @param url * @param url
*/ */
public static void load(final ServerDescription desc, final String serverName) { public static void load(final ServerDescription desc) {
if (!BotUI.getInstance().isVisible()) { if (!Jython.hasJar()) {
BotUI.getInstance().setVisible(true); Core.verbose("Downloading jython...");
VerboseLoader.setState("Downloading jython...");
WebUtil.downloadFile(Jython.getDownloadLink(), Jython.getJarFile(),
VerboseLoader.get());
Core.verbose("Downloaded jython.");
} }
Core.verbose("Initializing jython...");
Jython.init();
final ClassPath classPath = Core.inDebugMode() ? null : new ClassPath(); Core.verbose("Loading server: " + desc.toString());
final ServerCache cache = Core.inDebugMode() ? ServerManifestParser.cache.get(desc) : null;
// buildpath
if(cache != null) {
if(cache.getLoader().getClassPath().isJar()) {
cache.getLoader().getClassPath().addToBuildPath();
} else {
try {
BuildPath.add(Directories.getServerPath().toURI().toURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
final ServerLoader serverLoader = Core.inDebugMode() ? cache.getLoader() : new ServerLoader(classPath);
String[] serverProviders = null;
if (!Core.inDebugMode()) {
serverProviders = serverLoader.getServerClassNames();
if (serverProviders == null) {
throw new RuntimeException("No server provided.");
}
}
final String id = "tab" + Context.getID(); final String id = "tab" + Context.getID();
final ThreadGroup bot = new ThreadGroup(id); final ThreadGroup bot = new ThreadGroup(id);
new Thread(bot, new Runnable() {
@Override
public void run() {
try {
final ServerProvider server = !Core.inDebugMode() ? fetchServerProvider(serverLoader) : cache.getProviders()[desc.providerIndex];
final Context context = new Context(server);
context.setEnvironment(serverLoader);
BotToolbar.getInstance().addTab(context, serverName);
context.load();
} catch (Throwable t) {
t.printStackTrace();
}
}
}).start();
}
private static ServerProvider fetchServerProvider(ServerLoader loader) { ServerParser.SERVER_CACHE.get(desc).run(bot);
try {
final String[] serverProviders = loader.getServerClassNames();
if (serverProviders == null) {
throw new RuntimeException("No server provided.");
}
final Class<?> serverProviderClass = loader.loadClass(serverProviders[0]);
final Constructor<?> con = serverProviderClass.getConstructor();
return (ServerProvider) con.newInstance();
} catch (Throwable t) {
throw new RuntimeException("Error while loading server. " + t.getMessage());
}
}
}
} }
@@ -1,7 +1,6 @@
package org.parabot.environment; package org.parabot.environment;
public enum OperatingSystem public enum OperatingSystem {
{
WINDOWS, LINUX, MAC, OTHER; WINDOWS, LINUX, MAC, OTHER;
@@ -17,4 +16,3 @@ public enum OperatingSystem
} }
} }
@@ -4,7 +4,7 @@ import java.awt.Graphics;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public interface Paintable { public interface Paintable {
@@ -3,7 +3,7 @@ package org.parabot.environment.api.utils;
/** /**
* A simple class to filter things * A simple class to filter things
* *
* @author Clisprail * @author Everel
* *
* @param <F> * @param <F>
*/ */
@@ -2,7 +2,7 @@ package org.parabot.environment.api.utils;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Random { public class Random {
@@ -2,7 +2,7 @@ package org.parabot.environment.api.utils;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Time { public class Time {
@@ -4,7 +4,7 @@ package org.parabot.environment.api.utils;
* *
* A simple timer class * A simple timer class
* *
* @author Clisprail, Parameter * @author Everel, Parameter
* *
*/ */
public class Timer public class Timer
@@ -1,6 +1,9 @@
package org.parabot.environment.api.utils; package org.parabot.environment.api.utils;
import java.io.BufferedInputStream;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@@ -8,9 +11,12 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import org.parabot.core.io.ProgressListener;
import org.parabot.core.io.SizeInputStream;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class WebUtil { public class WebUtil {
@@ -18,6 +24,7 @@ public class WebUtil {
/** /**
* Agent to set at a URL connection * Agent to set at a URL connection
*
* @param userAgent * @param userAgent
*/ */
public static void setUserAgent(final String userAgent) { public static void setUserAgent(final String userAgent) {
@@ -26,6 +33,7 @@ public class WebUtil {
/** /**
* Gets useragent * Gets useragent
*
* @return useragent * @return useragent
*/ */
public static String getUserAgent() { public static String getUserAgent() {
@@ -34,6 +42,7 @@ public class WebUtil {
/** /**
* Fetches content of a page * Fetches content of a page
*
* @param location * @param location
* @return contents of page * @return contents of page
* @throws MalformedURLException * @throws MalformedURLException
@@ -45,12 +54,23 @@ public class WebUtil {
/** /**
* Get contents from URL * Get contents from URL
*
* @param url * @param url
* @return page contents * @return page contents
*/ */
public static String getContents(final URL url) { public static String getContents(final URL url) {
return getContents(getConnection(url));
}
/**
* Gets contents from URLConnection
*
* @param urlConnection
* @return page contents
*/
public static String getContents(URLConnection urlConnection) {
try { try {
final BufferedReader in = getReader(url); final BufferedReader in = getReader(urlConnection);
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
String line; String line;
while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
@@ -64,14 +84,35 @@ public class WebUtil {
return null; return null;
} }
/**
* Gets buffered reader from string url
*
* @param url
* @return bufferedreader
*/
public static BufferedReader getReader(final String url) {
try {
return getReader(new URL(url));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
/** /**
* Gets BufferedReader from URL * Gets BufferedReader from URL
*
* @param url * @param url
* @return BufferedReader from URL * @return BufferedReader from URL
*/ */
public static BufferedReader getReader(final URL url) { public static BufferedReader getReader(final URL url) {
return getReader(getConnection(url));
}
public static BufferedReader getReader(final URLConnection urlConnection) {
try { try {
return new BufferedReader(new InputStreamReader(getInputStream(url))); return new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
@@ -80,6 +121,7 @@ public class WebUtil {
/** /**
* Gets inputstream from url * Gets inputstream from url
*
* @param url * @param url
* @return inputstream from url * @return inputstream from url
*/ */
@@ -95,6 +137,7 @@ public class WebUtil {
/** /**
* Opens a connection * Opens a connection
*
* @param url * @param url
* @return URLConnection to URL * @return URLConnection to URL
*/ */
@@ -109,4 +152,36 @@ public class WebUtil {
return null; return null;
} }
/**
* Downloads a file on the internet
* @param url
* @param destination
* @param listener
*/
public static void downloadFile(final URL url, final File destination,
final ProgressListener listener) {
try {
final URLConnection connection = getConnection(url);
int size = connection.getContentLength();
SizeInputStream sizeInputStream = new SizeInputStream(
connection.getInputStream(), size, listener);
BufferedInputStream in = new BufferedInputStream(sizeInputStream);
FileOutputStream fileOut = new FileOutputStream(destination);
try {
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
fileOut.write(data, 0, count);
}
} finally {
if (in != null)
in.close();
if (fileOut != null)
fileOut.close();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
} }
@@ -10,7 +10,7 @@ import org.parabot.core.Context;
/** /**
* *
* @author Clisprail, Matt, Dane * @author Everel, Matt, Dane
* *
*/ */
public class Keyboard implements KeyListener { public class Keyboard implements KeyListener {
@@ -11,7 +11,7 @@ import org.parabot.environment.api.utils.Time;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Mouse implements MouseListener, MouseMotionListener { public class Mouse implements MouseListener, MouseMotionListener {
@@ -6,6 +6,11 @@ import org.parabot.environment.scripts.framework.AbstractFramework;
import org.parabot.environment.scripts.framework.LoopTask; import org.parabot.environment.scripts.framework.LoopTask;
import org.parabot.environment.scripts.framework.Strategy; import org.parabot.environment.scripts.framework.Strategy;
/**
*
* @author Everel
*
*/
public class Frameworks { public class Frameworks {
public static Looper getLooper(LoopTask loopTask) { public static Looper getLooper(LoopTask loopTask) {
@@ -0,0 +1,20 @@
package org.parabot.environment.scripts;
/**
*
* @author Everel
*
*/
public class LocalScriptExecuter extends ScriptExecuter {
private Script script = null;
public LocalScriptExecuter(final Script script) {
this.script = script;
}
@Override
public void run(ThreadGroup tg) {
super.finalize(tg, this.script);
}
}
@@ -0,0 +1,94 @@
package org.parabot.environment.scripts;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLConnection;
import javax.swing.JOptionPane;
import org.parabot.core.Configuration;
import org.parabot.core.classpath.ClassPath;
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.scripts.loader.JavaScriptLoader;
/**
*
* @author Everel
*
*/
public class SDNScriptExecuter extends ScriptExecuter {
private int id = -1;
private static AccountManager manager = null;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override
public final void setManager(AccountManager manager) {
SDNScriptExecuter.manager = manager;
}
};
public SDNScriptExecuter(final int id) {
this.id = id;
}
@Override
public void run(ThreadGroup tg) {
try {
final URLConnection urlConnection = WebUtil.getConnection(new URL(String.format(Configuration.GET_SDN_SCRIPT, manager.getAccount().getUsername(), manager.getAccount().getPassword(), this.id)));
final String contentType = urlConnection.getHeaderField("Content-type");
if(contentType.equals("text/html")) {
// failed to fetch script
UILog.log("Error", new StringBuilder("Failed to load SDN script, error: [Page returned: ").append(WebUtil.getContents(urlConnection)).append("]").toString(), JOptionPane.ERROR_MESSAGE);
} else if(contentType.equals("application/jar")) {
//// JAR LOADING PART ////////
// succesfull request, jar returned
final ClassPath classPath = new ClassPath();
classPath.addJar(urlConnection);
final JavaScriptLoader loader = new JavaScriptLoader(classPath);
final String[] scriptClasses = loader.getScriptClassNames();
if(scriptClasses == null || scriptClasses.length == 0) {
UILog.log("Error", "Failed to load SDN script, error: [No script found in jar file.]", JOptionPane.ERROR_MESSAGE);
return;
} else if(scriptClasses.length > 1) {
UILog.log("Error", "Failed to load SDN script, error: [Multiple scripts found in jar file.]");
return;
}
final String className = scriptClasses[0];
try {
final Class<?> scriptClass = loader.loadClass(className);
final Constructor<?> con = scriptClass.getConstructor();
final Script script = (Script) con.newInstance();
super.finalize(tg, script);
} catch (NoClassDefFoundError ignored) {
UILog.log("Error", "Failed to load SDN script, error: [This server provider does not support this script]", JOptionPane.ERROR_MESSAGE);
} catch(ClassNotFoundException ignored) {
UILog.log("Error", "Failed to load SDN script, error: [This server provider does not support this script]", JOptionPane.ERROR_MESSAGE);
} catch (Throwable t) {
t.printStackTrace();
UILog.log("Error", "Failed to load SDN script, post the stacktrace/error on the parabot forums.", JOptionPane.ERROR_MESSAGE);
}
//// END JAR LOADING ////
} else {
UILog.log("Error", new StringBuilder("Failed to load SDN script, error: [Unknown content type: ").append(contentType).append("]").toString(), JOptionPane.ERROR_MESSAGE);
}
} catch (Throwable t) {
t.printStackTrace();
UILog.log("Error", "Failed to load SDN script, post the stacktrace/error on the parabot forums.", JOptionPane.ERROR_MESSAGE);
}
}
}
@@ -3,7 +3,9 @@ package org.parabot.environment.scripts;
import java.util.Collection; import java.util.Collection;
import org.parabot.core.Context; import org.parabot.core.Context;
import org.parabot.core.Core;
import org.parabot.core.ui.components.BotToolbar; import org.parabot.core.ui.components.BotToolbar;
import org.parabot.core.ui.components.LogArea;
import org.parabot.environment.api.utils.Time; import org.parabot.environment.api.utils.Time;
import org.parabot.environment.scripts.framework.AbstractFramework; import org.parabot.environment.scripts.framework.AbstractFramework;
import org.parabot.environment.scripts.framework.LoopTask; import org.parabot.environment.scripts.framework.LoopTask;
@@ -12,7 +14,7 @@ import org.parabot.environment.scripts.framework.Strategy;
/** /**
* *
* @author Clisprail * @author Everel
* *
*/ */
public class Script implements Runnable { public class Script implements Runnable {
@@ -58,24 +60,35 @@ public class Script implements Runnable {
@Override @Override
public final void run() { public final void run() {
Core.verbose("Initializing script...");
Context.resolve().getServerProvider().initScript(this); Context.resolve().getServerProvider().initScript(this);
Core.verbose("Done.");
if(!onExecute()) { if(!onExecute()) {
Core.verbose("Script#onExecute returned false, unloading and stopping script...");
Context.resolve().getServerProvider().unloadScript(this); Context.resolve().getServerProvider().unloadScript(this);
this.state = STATE_STOPPED; this.state = STATE_STOPPED;
Core.verbose("Done.");
return; return;
} }
Core.verbose("Detecting script framework...");
Context.resolve().setRunningScript(this); Context.resolve().setRunningScript(this);
BotToolbar.getInstance().toggleRun(); BotToolbar.getInstance().toggleRun();
if(this instanceof LoopTask) { if(this instanceof LoopTask) {
Core.verbose("Script framework detected: LoopTask");
frameWorkType = TYPE_LOOP; frameWorkType = TYPE_LOOP;
frameWork = Frameworks.getLooper((LoopTask) this); frameWork = Frameworks.getLooper((LoopTask) this);
} else if(strategies != null && !strategies.isEmpty()) { } else if(strategies != null && !strategies.isEmpty()) {
Core.verbose("Script framework detected: Strategies");
frameWorkType = TYPE_STRATEGY; frameWorkType = TYPE_STRATEGY;
frameWork = Frameworks.getStrategyWorker(strategies); frameWork = Frameworks.getStrategyWorker(strategies);
} else { } else {
Core.verbose("Unknown script framework: Other");
frameWorkType = TYPE_OTHER; frameWorkType = TYPE_OTHER;
} }
Core.verbose("Running script...");
LogArea.log("Script started.");
try { try {
while(this.state != STATE_STOPPED) { while(this.state != STATE_STOPPED) {
if(this.state == STATE_PAUSE) { if(this.state == STATE_PAUSE) {
@@ -89,12 +102,14 @@ public class Script implements Runnable {
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
Core.verbose("Script stopped/finished, unloading and stopping...");
onFinish(); onFinish();
LogArea.log("Script stopped.");
Context.resolve().getServerProvider().unloadScript(this); Context.resolve().getServerProvider().unloadScript(this);
this.state = STATE_STOPPED; this.state = STATE_STOPPED;
Context.resolve().setRunningScript(null); Context.resolve().setRunningScript(null);
BotToolbar.getInstance().toggleRun(); BotToolbar.getInstance().toggleRun();
Core.verbose("Done.");
} }
/** /**
@@ -0,0 +1,12 @@
package org.parabot.environment.scripts;
public abstract class ScriptExecuter {
public abstract void run(final ThreadGroup tg);
public final void finalize(final ThreadGroup tg, final Script script) {
new Thread(tg, script).start();
}
}
@@ -5,7 +5,7 @@ import java.lang.annotation.RetentionPolicy;
/** /**
* A script manifest * A script manifest
* @author Clisprail * @author Everel
* *
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@@ -23,4 +23,8 @@ public @interface ScriptManifest {
String[] servers(); String[] servers();
boolean vip() default false;
boolean premium() default false;
} }
@@ -0,0 +1,9 @@
package org.parabot.environment.scripts.framework;
import org.parabot.environment.scripts.Script;
public abstract class PythonScript extends Script {
public abstract int loop();
}
@@ -12,14 +12,14 @@ import org.parabot.environment.scripts.Script;
* *
* An environment to load a server * An environment to load a server
* *
* @author Clisprail * @author Everel
* *
* *
*/ */
public class ScriptLoader extends ASMClassLoader { public class JavaScriptLoader extends ASMClassLoader {
private ClassPath classPath = null; private ClassPath classPath = null;
public ScriptLoader(ClassPath classPath) { public JavaScriptLoader(ClassPath classPath) {
super(classPath); super(classPath);
this.classPath = classPath; this.classPath = classPath;
} }
@@ -0,0 +1,49 @@
package org.parabot.environment.servers;
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;
/**
*
* Loads locally stored server providers
*
* @author Everel
*
*/
public class LocalServerExecuter extends ServerExecuter {
private final ServerProvider serverProvider;
private ClassPath classPath = null;
private String serverName = null;
public LocalServerExecuter(ServerProvider serverProvider,
ClassPath classPath, final String serverName) {
this.serverProvider = serverProvider;
this.classPath = classPath;
this.serverName = serverName;
}
@Override
public void run(ThreadGroup tg) {
// 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(tg, this.serverProvider, this.serverName);
}
}
@@ -0,0 +1,105 @@
package org.parabot.environment.servers;
import java.io.File;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLEncoder;
import javax.swing.JOptionPane;
import org.parabot.core.Configuration;
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.ui.components.VerboseLoader;
import org.parabot.core.ui.utils.UILog;
import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.servers.loader.ServerLoader;
/**
*
* @author Everel
*
*/
public class PublicServerExecuter extends ServerExecuter {
private String serverName = null;
private String jarName = null;
public PublicServerExecuter(final String serverName, final String jarName) {
this.serverName = serverName;
this.jarName = jarName;
}
@Override
public void run(ThreadGroup tg) {
try {
final File destination = new File(Directories.getCachePath(),
this.jarName);
final String jarUrl = String.format(
Configuration.GET_SERVER_PROVIDER,
URLEncoder.encode(this.jarName, "UTF-8"));
Core.verbose("Downloading: " + jarUrl + " ...");
WebUtil.downloadFile(new URL(jarUrl), destination,
VerboseLoader.get());
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();
super.finalize(tg, serverProvider, this.serverName);
} catch (NoClassDefFoundError 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 (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);
}
}
}
@@ -0,0 +1,31 @@
package org.parabot.environment.servers;
import org.parabot.core.Context;
import org.parabot.core.ui.components.BotToolbar;
/**
*
* @author Everel
*
*/
public abstract class ServerExecuter {
public abstract void run(final ThreadGroup tg);
public void finalize(final ThreadGroup tg, final ServerProvider provider, final String serverName) {
// loads the server and its it to the gui
new Thread(tg, new Runnable() {
@Override
public void run() {
try {
final Context context = new Context(provider);
BotToolbar.getInstance().addTab(context, serverName);
context.load();
} catch (Throwable t) {
t.printStackTrace();
}
}
}).start();
}
}
@@ -5,7 +5,7 @@ import java.lang.annotation.RetentionPolicy;
/** /**
* A server manifest * A server manifest
* @author Clisprail * @author Everel
* *
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@@ -16,7 +16,7 @@ import org.parabot.environment.scripts.Script;
/** /**
* Provides a server to the bot * Provides a server to the bot
* *
* @author Clisprail * @author Everel
* *
*/ */
public abstract class ServerProvider implements Opcodes { public abstract class ServerProvider implements Opcodes {
@@ -4,7 +4,7 @@ package org.parabot.environment.servers;
* *
* Bot type * Bot type
* *
* @author Clisprail * @author Everel
* *
*/ */
public enum Type { public enum Type {
@@ -12,7 +12,7 @@ import org.parabot.environment.servers.ServerProvider;
* *
* An environment to load a server * An environment to load a server
* *
* @author Clisprail * @author Everel
* *
* *
*/ */