Moved to Maven

This commit is contained in:
JKetelaar
2015-09-13 22:51:13 +02:00
parent a3bf8d0d0d
commit 52836a3e9a
303 changed files with 56775 additions and 35 deletions
+181
View File
@@ -0,0 +1,181 @@
package org.parabot;
import org.parabot.core.Configuration;
import org.parabot.core.Core;
import org.parabot.core.Directories;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.network.NetworkInterface;
import org.parabot.core.network.proxy.ProxySocket;
import org.parabot.core.network.proxy.ProxyType;
import org.parabot.core.ui.BotUI;
import org.parabot.core.ui.ServerSelector;
import org.parabot.core.ui.utils.UILog;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
/**
* Parabot v2.1
*
* @author Everel/Parnassian/Clisprail, Paradox/JKetelaar, Matt, Dane
* @version 2.1
* @see <a href="http://www.parabot.org">Homepage</a>
*/
public final class Landing {
private static String username;
private static String password;
public static void main(String... args) throws IOException {
parseArgs(args);
Core.verbose("Debug mode: " + Core.inDebugMode());
try {
Core.verbose("Setting look and feel: "
+ UIManager.getSystemLookAndFeelClassName());
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable t) {
t.printStackTrace();
}
if (!Core.inDebugMode() && !Core.isValid()) {
UILog.log("Updates",
"Please download the newest version of Parabot at "
+ Configuration.DOWNLOAD_BOT,
JOptionPane.INFORMATION_MESSAGE);
URI uri = URI.create(Configuration.DOWNLOAD_BOT);
try {
Desktop.getDesktop().browse(uri);
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "Connection Error",
"Error", JOptionPane.ERROR_MESSAGE);
e1.printStackTrace();
}
return;
}
Core.verbose("Validating directories...");
Directories.validate();
Core.verbose("Validating account manager...");
AccountManager.validate();
if (getCredentials() != null && getCredentials().length == 2) {
if ((username = getCredentials()[0]) != null
&& (password = getCredentials()[1]) != null) {
new BotUI(username, password);
}
username = null;
password = null;
} else if (username != null && password != null) {
new BotUI(username, password);
username = null;
password = null;
return;
}
Core.verbose("Starting login gui...");
new BotUI(null, null);
}
/**
* TODO Returns an array of string containing only the username and password
*
* @return String array with username and password
*/
private static String[] getCredentials() {
// try {
// BufferedReader bufferedReader = WebUtil.getReader(new URL(
// Configuration.GET_PASSWORD));
// if (bufferedReader.readLine() != null) {
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
return null;
}
private static void parseArgs(String... args) {
for (int i = 0; i < args.length; i++) {
final String arg = args[i].toLowerCase();
switch (arg.toLowerCase()) {
case "-createdirs":
Directories.validate();
System.out
.println("Directories created, you can now run parabot.");
System.exit(0);
break;
case "-debug":
Core.setDebug(true);
break;
case "-v":
case "-verbose":
Core.setVerbose(true);
break;
case "-server":
ServerSelector.initServer = args[++i];
break;
case "-login":
username = args[++i];
password = args[++i];
break;
case "-loadlocal":
Core.setLoadLocal(true);
break;
case "-dump":
Core.setDump(true);
break;
case "-scriptsbin":
Directories.setScriptCompiledDirectory(new File(args[++i]));
break;
case "-serversbin":
Directories.setServerCompiledDirectory(new File(args[++i]));
break;
case "-clearcache":
File[] cache = Directories.getCachePath().listFiles();
if (cache != null) {
for (File f : cache) {
if (f.exists() && f.canWrite()) {
f.delete();
}
}
}
break;
case "-mac":
byte[] mac = new byte[6];
String str = args[++i];
if (str.toLowerCase().equals("random")) {
new java.util.Random().nextBytes(mac);
} else {
i--;
for (int j = 0; j < 6; j++) {
mac[j] = Byte.parseByte(args[++i], 16); // parses a hex
// number
}
}
NetworkInterface.setMac(mac);
break;
case "-proxy":
ProxyType type = ProxyType.valueOf(args[++i].toUpperCase());
if (type == null) {
System.err.println("Invalid proxy type:" + args[i]);
System.exit(1);
return;
}
ProxySocket.setProxy(type, args[++i],
Integer.parseInt(args[++i]));
break;
case "-auth":
ProxySocket.auth = true;
ProxySocket.setLogin(args[++i], args[++i]);
break;
case "-no_sec":
Core.disableSec();
break;
}
}
}
}
@@ -0,0 +1,25 @@
package org.parabot.core;
/**
* Holds some important constants
*
* @author Everel
*/
public class Configuration {
// public static final String LOGIN_SERVER = "https://www.parabot.org/community/api/login.php?username=%s&password=%s";
public static final String LOGIN_SERVER = "http://bdn.parabot.org/api/v2/users/login";
public static final String GET_SCRIPTS = "http://bdn.parabot.org/api/get.php?action=scripts_scripts&server=";
public static final String GET_SCRIPT = "http://bdn.parabot.org/api/get.php?action=scripts_script&id=";
public static final String GET_SERVER_PROVIDERS = "http://bdn.parabot.org/api/get.php?action=server_providers";
public static final String GET_SERVER_PROVIDER = "http://bdn.parabot.org/api/get.php?action=server_provider&name=";
public static final String GET_SERVER_PROVIDER_INFO = "http://bdn.parabot.org/api/get.php?action=server_information&name=";
public static final String GET_BOT_VERSION = "http://bdn.parabot.org/api/v2/bot/version";
public static final String DOWNLOAD_BOT = "http://bdn.parabot.org/versions/";
public static final String REGISTRATION_PAGE = "https://www.parabot.org/community/index.php?app=core&module=global&section=register";
public static final String GET_PASSWORD = "http://bdn.parabot.org/api/get.php?action=password";
public static final String GET_RANDOMS = "http://bdn.parabot.org/api/get.php?action=randoms";
public static final String DATA_API = "http://bdn.parabot.org/api/v2/data/";
public static final String ITEM_API = DATA_API + "items/";
public static final String BOT_VERSION = "2.2";
}
+363
View File
@@ -0,0 +1,363 @@
package org.parabot.core;
import org.json.simple.parser.JSONParser;
import org.parabot.core.asm.ASMClassLoader;
import org.parabot.core.classpath.ClassPath;
import org.parabot.core.desc.ServerProviderInfo;
import org.parabot.core.paint.PaintDebugger;
import org.parabot.core.parsers.hooks.HookParser;
import org.parabot.core.ui.BotDialog;
import org.parabot.core.ui.BotUI;
import org.parabot.core.ui.components.GamePanel;
import org.parabot.environment.api.interfaces.Paintable;
import org.parabot.environment.input.Keyboard;
import org.parabot.environment.input.Mouse;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.randoms.RandomHandler;
import org.parabot.environment.scripts.uliratha.UlirathaClient;
import org.parabot.environment.servers.ServerProvider;
import java.applet.Applet;
import java.awt.Dimension;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.TimerTask;
/**
* Game context
*
* @author Everel
*/
public class Context {
public static final HashMap<ThreadGroup, Context> threadGroups = new HashMap<ThreadGroup, Context>();
private static ArrayList<Paintable> paintables = new ArrayList<Paintable>();
private static Context instance;
private static String username;
public boolean added;
private ASMClassLoader classLoader;
private ClassPath classPath;
private ServerProvider serverProvider;
private Applet gameApplet;
private HookParser hookParser;
private Script runningScript;
private RandomHandler randomHandler;
private Object clientInstance;
private PaintDebugger paintDebugger;
private Mouse mouse;
private Keyboard keyboard;
private ServerProviderInfo providerInfo;
private UlirathaClient ulirathaClient;
private JSONParser jsonParser;
private Context(final ServerProvider serverProvider) {
threadGroups.put(Thread.currentThread().getThreadGroup(), this);
System.setProperty("sun.java.command", "");
this.serverProvider = serverProvider;
this.paintDebugger = new PaintDebugger();
this.classPath = new ClassPath();
this.classLoader = new ASMClassLoader(classPath);
this.randomHandler = new RandomHandler();
this.jsonParser = new JSONParser();
}
public static Context getInstance(ServerProvider serverProvider) {
return instance == null ? instance = new Context(serverProvider) : instance;
}
public static Context getInstance() {
return getInstance(null);
}
/**
* Sets the main client instance
*/
public void setClientInstance(Object object) {
this.clientInstance = object;
}
/**
* Sets the hook parser
*
* @param hookParser
*/
public void setHookParser(final HookParser hookParser) {
this.hookParser = hookParser;
}
/**
* Sets the mouse
*
* @param mouse
*/
public void setMouse(final Mouse mouse) {
this.mouse = mouse;
}
/**
* Gets the mouse
*
* @return mouse
*/
public Mouse getMouse() {
return mouse;
}
/**
* Sets the keyboard
*
* @param keyboard
*/
public void setKeyboard(final Keyboard keyboard) {
this.keyboard = keyboard;
}
/**
* Gets the keyboard
*
* @return keyboard
*/
public Keyboard getKeyboard() {
return keyboard;
}
/**
* ClassPath
*
* @return classpath
*/
public ClassPath getClassPath() {
return classPath;
}
/**
* Determines if applet has been set
*
* @return <b>true</b> if set
*/
public boolean appletSet() {
return gameApplet != null;
}
/**
* Gets game applet
*
* @return applet
*/
public Applet getApplet() {
return gameApplet;
}
/**
* Loads the game
*/
public void load() {
Core.verbose("Parsing server jar...");
serverProvider.init();
serverProvider.parseJar();
Core.verbose("Done.");
Core.verbose("Injecting hooks...");
serverProvider.injectHooks();
Core.verbose("Done.");
Core.verbose("Fetching game applet...");
if(Core.shouldDump()) {
Core.verbose("Dumping injected client...");
classPath.dump(new File(Directories.getWorkspace(), "dump.jar"));
Core.verbose("Done.");
}
Applet applet = serverProvider.fetchApplet();
// if applet is null the server provider will call setApplet itself
if(applet != null) {
setApplet(applet);
}
}
/**
* Sets the bot target applet
* @param applet
*/
public void setApplet(final Applet applet) {
gameApplet = applet;
if (getClient() == null) {
setClientInstance(gameApplet);
}
Core.verbose("Applet fetched.");
final GamePanel panel = GamePanel.getInstance();
final Dimension appletSize = serverProvider.getGameDimensions();
panel.setPreferredSize(appletSize);
serverProvider.addMenuItems(BotUI.getInstance().getJMenuBar());
BotUI.getInstance().pack();
BotUI.getInstance().validate();
panel.removeComponents();
gameApplet.setSize(appletSize);
panel.add(gameApplet);
panel.validate();
gameApplet.init();
gameApplet.start();
java.util.Timer t = new java.util.Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
gameApplet.setBounds(0, 0, appletSize.width, appletSize.height);
}
}, 1000);
Core.verbose("Initializing mouse...");
serverProvider.initMouse();
Core.verbose("Done.");
Core.verbose("Initializing keyboard...");
serverProvider.initKeyboard();
Core.verbose("Done.");
BotDialog.getInstance().validate();
}
/**
* Gets the server prodiver belonging to this context
*
* @return server provider
*/
public ServerProvider getServerProvider() {
return serverProvider;
}
/**
*
* Sets provider info of this context
*
* @param providerInfo
*/
public void setProviderInfo(ServerProviderInfo providerInfo) {
this.providerInfo = providerInfo;
}
/**
* Gets ServerProvider info
* Can be null if this is not a public server provider
* @return info about this provider
*/
public ServerProviderInfo getServerProviderInfo() {
return this.providerInfo;
}
/**
* Gets class loader of server from this context
*
* @return class loader
*/
public ASMClassLoader getASMClassLoader() {
return classLoader;
}
/**
* Adds a paintable instance to the paintables
*
* @param paintable
*/
public void addPaintable(Paintable paintable) {
paintables.add(paintable);
}
/**
* Removes a paintable instance from the paintables
*
* @param paintable
*/
public void removePaintable(Paintable paintable) {
paintables.remove(paintable);
}
/**
* Gets the paintable instances
*
* @return array of paintable instances
*/
public Paintable[] getPaintables() {
return paintables.toArray(new Paintable[paintables.size()]);
}
/**
* The client debug painter
*
* @return debug painter
*/
public PaintDebugger getPaintDebugger() {
return paintDebugger;
}
/**
* Gets the main/client instance
*
* @return instance of the the client
*/
public Object getClient() {
return this.clientInstance;
}
/**
* Gets the hook parser, may be null if injection is not used or a custom hook parser is used for injecting
*
* @return hook parser
*/
public HookParser getHookParser() {
return hookParser;
}
/**
* Sets the current running script, if a script stops it will call this method with a null argument
*
* @param script
*/
public void setRunningScript(final Script script) {
this.runningScript = script;
}
/**
* Gets the current running script
*
* @return script
*/
public Script getRunningScript() {
return this.runningScript;
}
/**
* Gets the random handler
* @return random handler
*/
public RandomHandler getRandomHandler() {
return this.randomHandler;
}
public static String getUsername() {
return username;
}
public UlirathaClient getUlirathaClient() {
return ulirathaClient;
}
public void setUlirathaClient(UlirathaClient ulirathaClient) {
this.ulirathaClient = ulirathaClient;
}
public static void setUsername(String username) {
Context.username = username;
}
public JSONParser getJsonParser() {
return jsonParser;
}
}
+244
View File
@@ -0,0 +1,244 @@
package org.parabot.core;
import org.json.simple.JSONObject;
import org.json.simple.parser.ParseException;
import org.parabot.Landing;
import org.parabot.core.ui.utils.UILog;
import org.parabot.environment.api.utils.WebUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* The core of parabot
*
* @author Everel, JKetelaar
*/
public class Core {
public static boolean mDebug;
private static boolean debug;
private static boolean verbose;
private static boolean dump;
private static boolean loadLocal; //Loads both local and public scripts/servers
private static boolean secure = true;
/**
* Enabled loadLocal mode
*
* @param loadLocal
*/
public static void setLoadLocal(final boolean loadLocal) {
Core.loadLocal = loadLocal;
}
/**
* @return if the client is in loadLocal mode.
*/
public static boolean inLoadLocal() {
return loadLocal;
}
/**
* Enabled debug mode
*
* @param debug
*/
public static void setDebug(final boolean debug) {
Core.debug = debug;
}
/**
* Enables dump mode
*
* @param dump
*/
public static void setDump(final boolean dump) {
Core.dump = dump;
}
public static void disableSec(){
UILog.log(
"Security Warning",
"Disabling the securty manager is ill advised.\n"
+ " Only do so if the client fails to load, or functions incorrectly (freezes,crashes, etc.)\n"
+ "The security manager protects you from malicous code within the client, without it you are exposed!\n"
+ "\nPlease contact Parabot staff to resolve whatever problem you are having!");
Core.secure = false;
}
public static boolean isSecure(){
return secure;
}
/**
* @return if the client is in debug mode.
*/
public static boolean inDebugMode() {
return debug;
}
/**
* @return if the client is in verbose mode.
*/
public static boolean inVerboseMode() {
return verbose;
}
/**
* @return if parabot should dump injected jar
*/
public static boolean shouldDump() {
return dump;
}
/**
* 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 the version of the bot using a checksum of the jar comparison against checksum given by the website
* @return <b>true</b> if no new version is found, otherwise <b>false</b>.
*/
@SuppressWarnings("unused")
private static boolean checksumValid(){
File f = new File(Landing.class.getProtectionDomain().getCodeSource().getLocation().getFile());
if (f.isFile()) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
File location = new File(Landing.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
if (location.exists()) {
FileInputStream fis = new FileInputStream(location);
byte[] dataBytes = new byte[1024];
int nread;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
byte[] mdbytes = md.digest();
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < mdbytes.length; i++) {
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
String result;
if ((result = WebUtil.getContents("http://bdn.parabot.org/api/v2/bot/checksum", "checksum=" + URLEncoder.encode(sb.toString(), "UTF-8"))) != null) {
JSONObject object = (JSONObject) WebUtil.getJsonParser().parse(result);
if (!(boolean) object.get("result")){
Core.verbose("Latest checksum: " + sb.toString());
Core.verbose("Latest checksum: " + object.get("current"));
return false;
}
}
}
} catch (NoSuchAlgorithmException | ParseException | IOException | URISyntaxException e) {
e.printStackTrace();
}
}
return true;
}
/**
* Checks the version of the bot using a variable comparison from the bot code and the Parabot website
* @return <b>true</b> if no new version is found, otherwise <b>false</b>.
*/
private static boolean versionValid(){
BufferedReader br = WebUtil.getReader(Configuration.GET_BOT_VERSION);
try {
String version = null;
if (br != null) {
JSONObject object = (JSONObject) WebUtil.getJsonParser().parse(br);
version = (String) object.get("result");
}
if (version != null) {
if (!Configuration.BOT_VERSION.equals(version)) {
Core.verbose("Our version: " + Configuration.BOT_VERSION);
Core.verbose("Latest version: " + version);
return false;
}
}
} catch (NumberFormatException | IOException | ParseException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
private static void validateCache(){
File[] cache = Directories.getCachePath().listFiles();
Integer lowest = null;
if (cache != null) {
for (File f : cache) {
int date = (int) (f.lastModified()/ 1000);
if (lowest == null || date < lowest){
lowest = date;
}
}
}
try {
JSONObject object = (JSONObject) WebUtil.getJsonParser().parse(WebUtil.getContents("http://bdn.parabot.org/api/v2/bot/cache", "date=" + lowest));
if ((boolean) object.get("result")){
Core.verbose("Making space for the latest cache files");
Directories.clearCache();
}else{
Core.verbose("Cache is up to date");
}
} catch (MalformedURLException | ParseException e) {
e.printStackTrace();
}
}
/**
* 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...");
validateCache();
if (versionValid() && checksumValid()){
Core.verbose("No updates available.");
return true;
}else{
Core.verbose("Updates available...");
return false;
}
}
public static void debug(int i) {
if(mDebug) {
System.out.println("DEBUG: " + i);
}
}
}
@@ -0,0 +1,210 @@
package org.parabot.core;
import org.parabot.environment.OperatingSystem;
import javax.swing.*;
import java.io.File;
import java.util.*;
/**
* Holds parabot's used directories
*
* @author Everel
* @author Matt
*/
public class Directories {
private static Map<String, File> cached;
static {
cached = new HashMap<>();
switch (OperatingSystem.getOS()) {
case WINDOWS:
cached.put("Root", new JFileChooser().getFileSystemView().getDefaultDirectory());
break;
default:
cached.put("Root", new File(System.getProperty("user.home")));
}
Core.verbose("Caching directories...");
cached.put("Root", getDefaultDirectory());
cached.put("Workspace", new File(cached.get("Root"), "/Parabot/"));
cached.put("Sources", new File(cached.get("Root"), "/Parabot/scripts/sources/"));
cached.put("Compiled", new File(cached.get("Root"), "/Parabot/scripts/compiled/"));
cached.put("Resources", new File(cached.get("Root"), "/Parabot/scripts/resources/"));
cached.put("Settings", new File(cached.get("Root"), "/Parabot/settings/"));
cached.put("Servers", new File(cached.get("Root"), "/Parabot/servers/"));
cached.put("Cache", new File(cached.get("Root"), "/Parabot/cache/"));
cached.put("Home", new File(cached.get("Root"), "/temp/"));
Core.verbose("Directories cached.");
clearCache(259200);
}
/**
* Set script bin folder
*
* @param f
*/
public static void setScriptCompiledDirectory(File f) {
if (!f.isDirectory()) {
throw new IllegalArgumentException(f + "is not a directory.");
}
cached.put("Compiled", f);
}
/**
* Set server bin folder
*
* @param f
*/
public static void setServerCompiledDirectory(File f) {
if (!f.isDirectory()) {
throw new IllegalArgumentException(f + "is not a directory.");
}
cached.put("Servers", f);
}
/**
* Returns the root directory outside of the main Parabot folder.
*
* @return
*/
public static File getDefaultDirectory() {
return cached.get("Root");
}
/**
* Returns the Parabot folder.
*
* @return
*/
public static File getWorkspace() {
return cached.get("Workspace");
}
/**
* Returns the script sources folder.
*
* @return
*/
public static File getScriptSourcesPath() {
return cached.get("Sources");
}
/**
* Returns the compiled scripts folder.
*
* @return
*/
public static File getScriptCompiledPath() {
return cached.get("Compiled");
}
/**
* Returns the scripts resources folder.
*
* @return
*/
public static File getResourcesPath() {
return cached.get("Resources");
}
/**
* Returns the Parabot settings folder.
*
* @return
*/
public static File getSettingsPath() {
return cached.get("Settings");
}
/**
* Returns the Parabot servers folder.
*
* @return
*/
public static File getServerPath() {
return cached.get("Servers");
}
/**
* Returns the Parabot cache folder.
*
* @return
*/
public static File getCachePath() {
return cached.get("Cache");
}
/**
* Returns the redirected Home Directory
* @return
*/
public static File getHomeDir() {
return cached.get("Home");
}
/**
* Validates all directories and makes them if necessary
*/
public static void validate() {
final File defaultPath = getDefaultDirectory();
if (defaultPath == null || !defaultPath.exists()) {
throw new RuntimeException("Default path not found");
}
final Queue<File> files = new LinkedList<File>();
files.addAll(cached.values());
while (files.size() > 0) {
final File file = files.poll();
if (!file.exists()) {
Core.verbose("Generating directory: " + file.getAbsolutePath());
file.mkdirs();
if (!file.exists()) {
System.err.println("Failed to make directory: " + file.getAbsolutePath());
}
}
}
}
private static File temp = null;
public static File getTempDirectory() {
if (temp != null) {
return temp;
}
int randomNum = new Random().nextInt(999999999);
temp = new File(getResourcesPath(), randomNum + "/");
temp.mkdirs();
temp.deleteOnExit();
return temp;
}
/**
* Clears the cache based on the latest modification
*
* @param remove A long that represents the amount of seconds that a file may have since the latest modification
*/
private static void clearCache(int remove) {
File[] cache = getCachePath().listFiles();
if (cache != null) {
for (File f : cache) {
if (f != null && System.currentTimeMillis() / 1000 - f.lastModified() / 1000 > remove) {
Core.verbose("Clearing " + f.getName() + " from cache...");
f.delete();
}
}
}
}
public static void clearCache() {
File[] cache = getCachePath().listFiles();
if (cache != null) {
for (File f : cache) {
Core.verbose("Clearing " + f.getName() + " from cache...");
f.delete();
}
}
}
}
@@ -0,0 +1,47 @@
package org.parabot.core;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author JKetelaar
* @deprecated
*/
public class ProjectProperties {
private static ProjectProperties instance;
private Properties cached = new Properties();
private ProjectProperties(){
setProperties();
}
private void setProperties(){
InputStream input;
try {
String propertiesFileName = "/app.properties";
Properties properties = new Properties();
InputStream inputStream = this.getClass().getClassLoader()
.getResourceAsStream(propertiesFileName);
cached.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
private Properties getCached(){
return cached;
}
public static Object getProjectVersion(){
System.out.println(getInstance().getCached().getProperty("application.version"));
return getInstance().getCached().getProperty("application.version");
}
public static ProjectProperties getInstance(){
return instance == null ? instance = new ProjectProperties() : instance;
}
}
@@ -0,0 +1,102 @@
package org.parabot.core.asm;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import org.parabot.core.classpath.ClassPath;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Map;
/**
*
* Makes classnodes into runnable classes
*
* @author Everel
* @author Matt
*
*/
public class ASMClassLoader extends ClassLoader {
private Map<String, Class<?>> classCache;
public ClassPath classPath;
public ASMClassLoader(final ClassPath classPath) {
this.classCache = new HashMap<String, Class<?>>();
this.classPath = classPath;
}
@Override
protected URL findResource(String name) {
if (getSystemResource(name) == null) {
if (classPath.resources.containsKey(name)) {
try {
return classPath.resources.get(name).toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
return getSystemResource(name);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return findClass(name);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
return getSystemClassLoader().loadClass(name);
} catch (Exception ignored) {
}
String key = name.replace('.', '/');
if (classCache.containsKey(key)) {
return classCache.get(key);
}
ClassNode node = classPath.classes.get(key);
if (node != null) {
classPath.classes.remove(key);
Class<?> c = nodeToClass(node);
classCache.put(key, c);
return c;
}
return getSystemClassLoader().loadClass(name);
}
private final Class<?> nodeToClass(ClassNode node) {
if (super.findLoadedClass(node.name) != null) {
return findLoadedClass(node.name);
}
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
node.accept(cw);
byte[] b = cw.toByteArray();
return defineClass(node.name.replace('/', '.'), b, 0, b.length,
getDomain());
}
private final ProtectionDomain getDomain() {
CodeSource code = new CodeSource(null, (Certificate[]) null);
return new ProtectionDomain(code, getPermissions());
}
private final Permissions getPermissions() {
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
return permissions;
}
}
@@ -0,0 +1,156 @@
package org.parabot.core.asm;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Context;
import java.lang.reflect.Modifier;
/**
*
* A collection of various asm util methods
*
* @author Everel
*
*/
public class ASMUtils implements Opcodes {
public static FieldNode getField(ClassNode node, String fieldName) {
for (final FieldNode fieldNode : node.fields) {
if (fieldNode.name.equals(fieldName)) {
return fieldNode;
}
}
return null;
}
public static FieldNode getField(ClassNode node, String fieldName, String desc) {
if(desc == null) {
return getField(node, fieldName);
}
for (final FieldNode fieldNode : node.fields) {
if (fieldNode.name.equals(fieldName) && fieldNode.desc.equals(desc)) {
return fieldNode;
}
}
return null;
}
public static ClassNode getClass(String className) {
Context context = Context.getInstance();
for (ClassNode node : context.getClassPath().classes.values()) {
if (node.name.equals(className)) {
return node;
}
}
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);
}
public static void makePublic(ClassNode node) {
if (!Modifier.isPublic(node.access)) {
if (Modifier.isPrivate(node.access)) {
node.access = node.access & (~Opcodes.ACC_PRIVATE);
}
if (Modifier.isProtected(node.access)) {
node.access = node.access & (~Opcodes.ACC_PROTECTED);
}
node.access = node.access | Opcodes.ACC_PUBLIC;
}
}
public static void makePublic(MethodNode node) {
if (!Modifier.isPublic(node.access)) {
if (Modifier.isPrivate(node.access)) {
node.access = node.access & (~Opcodes.ACC_PRIVATE);
}
if (Modifier.isProtected(node.access)) {
node.access = node.access & (~Opcodes.ACC_PROTECTED);
}
node.access = node.access | Opcodes.ACC_PUBLIC;
}
}
public static void makePublic(FieldNode node) {
if (!Modifier.isPublic(node.access)) {
if (Modifier.isPrivate(node.access)) {
node.access = node.access & (~Opcodes.ACC_PRIVATE);
}
if (Modifier.isProtected(node.access)) {
node.access = node.access & (~Opcodes.ACC_PROTECTED);
}
node.access = node.access | Opcodes.ACC_PUBLIC;
}
}
}
@@ -0,0 +1,23 @@
package org.parabot.core.asm;
import org.objectweb.asm.commons.Remapper;
import java.util.HashMap;
public class ClassRemapper extends Remapper {
private static HashMap<String, String> remapNames = new HashMap<String, String>();
static {
remapNames.put("java/net/Socket", "org/parabot/core/network/proxy/ProxySocket");
remapNames.put("java/net/NetworkInterface", "org/parabot/core/network/NetworkInterface");
}
@Override
public String map(String str) {
String s = remapNames.get(str);
if (s != null) {
return s;
} else {
return str;
}
}
}
@@ -0,0 +1,136 @@
package org.parabot.core.asm;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.parabot.core.Core;
import org.parabot.core.Directories;
import org.parabot.core.asm.redirect.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
public class RedirectClassAdapter extends ClassVisitor implements Opcodes {
private static final Map<String, Class<?>> redirects = new HashMap<String, Class<?>>();
private String className;
private static PrintStream str_out, class_out;
static {
redirects.put("java/awt/Toolkit", ToolkitRedirect.class);
redirects.put("java/lang/Class", ClassRedirect.class);
redirects.put("java/lang/ClassLoader", ClassLoaderRedirect.class);
redirects.put("java/lang/Runtime", RuntimeRedirect.class);
redirects.put("java/lang/Thread", ThreadRedirect.class);
redirects.put("java/lang/StackTraceElement",
StackTraceElementRedirect.class);
redirects.put("java/lang/ProcessBuilder", ProcessBuilderRedirect.class);
redirects.put("java/lang/System", SystemRedirect.class);
}
public RedirectClassAdapter(ClassVisitor cv) {
super(ASM5, cv);
if (str_out == null && Core.shouldDump())
try {
str_out = new PrintStream(new FileOutputStream(new File(Directories.getWorkspace(),"strings.txt")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(class_out == null && Core.shouldDump())
try {
class_out = new PrintStream(new FileOutputStream(new File(Directories.getWorkspace(),"classes.txt")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
this.className = name;
super.visit(version, access, name, signature, superName, interfaces);
if(class_out != null)
class_out.println(className + " References:");
}
@Override
public void visitEnd(){
super.visitEnd();
if(class_out != null){
class_out.println();
class_out.println();
}
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
return new ReflectionMethodVisitor(name, desc, super.visitMethod(
access, name, desc, signature, exceptions));
}
private class ReflectionMethodVisitor extends MethodVisitor {
public ReflectionMethodVisitor(String name, String desc,
MethodVisitor mv) {
super(ASM5, mv);
}
@Override
public void visitLdcInsn(Object o) {
if (o instanceof String && str_out != null)
str_out.println(className + " " + o);
super.visitLdcInsn(o);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name,
String desc) {
if (Core.isSecure()) {
if (redirects.containsKey(owner) && !name.equals("<init>")
&& !name.equals("<clinit>")) {
if (opcode != INVOKESTATIC)
desc = "(L" + owner + ";" + desc.substring(1);
opcode = INVOKESTATIC;
owner = redirects.get(owner).getName()
.replaceAll("\\.", "/");
}
}
if(class_out != null)
class_out.println(owner);
super.visitMethodInsn(opcode, owner, name, desc);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name,
String desc){
if (Core.isSecure() && (opcode == GETSTATIC || opcode == PUTSTATIC)) {
if (redirects.containsKey(owner)) {
owner = redirects.get(owner).getName()
.replaceAll("\\.", "/");
}
}
if(class_out != null)
class_out.println(owner);
super.visitFieldInsn(opcode, owner, name, desc);
}
}
public static SecurityException createSecurityException() {
Exception e = new Exception();
StackTraceElement[] elements = e.getStackTrace();
return new SecurityException("Unsafe operation blocked. Op:"
+ elements[1].getMethodName());
}
}
@@ -0,0 +1,98 @@
package org.parabot.core.asm.adapters;
import java.lang.reflect.Modifier;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
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;
private boolean conditional;
public AddCallbackAdapter(final MethodNode method,
final String invokeClass, final String invokeMethod,
final String desc, final int[] args, final boolean conditional) {
this.method = method;
this.invokeClass = invokeClass;
this.invokeMethod = invokeMethod;
this.desc = desc;
this.args = args;
this.conditional = conditional;
}
@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));
int offset = 0;
for (int arg : args) {
if(Modifier.isStatic(method.access)) {
int loadOpcode = ASMUtils.getLoadOpcode(types[arg]
.getDescriptor());
inject.add(new VarInsnNode(loadOpcode, arg + offset));
if(loadOpcode == Opcodes.LLOAD) {
offset++;
}
} else {
inject.add(new VarInsnNode(ASMUtils.getLoadOpcode(types[arg]
.getDescriptor()), arg + 1));
}
}
inject.add(new MethodInsnNode(INVOKESTATIC,
this.invokeClass, this.invokeMethod,
this.desc));
if(this.conditional) {
LabelNode ln = new LabelNode(new Label());
inject.add(new JumpInsnNode(IFEQ, ln));
if(Type.getReturnType(method.desc).equals(Type.BOOLEAN_TYPE)) {
inject.add(new InsnNode(ICONST_1));
inject.add(new InsnNode(IRETURN));
} else {
inject.add(new InsnNode(RETURN));
}
inject.add(ln);
}
if(method.name.startsWith("<") && !Modifier.isStatic(method.access)) {
// find target
AbstractInsnNode target = null;
for(AbstractInsnNode node : this.method.instructions.toArray()) {
if(node.getOpcode() == Opcodes.INVOKESPECIAL) {
target = node;
break;
}
}
if(target != null) {
this.method.instructions.insert(target, inject);
}
} else {
this.method.instructions.insert(inject);
}
}
}
@@ -0,0 +1,43 @@
package org.parabot.core.asm.adapters;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
public class AddDebugAdapter {
private ClassNode owner;
private MethodNode mn;
public AddDebugAdapter(ClassNode owner, MethodNode mn) {
this.owner = owner;
this.mn = mn;
}
public AddDebugAdapter(MethodNode mn) {
this.mn = mn;
}
public void inject() {
InsnList inject = new InsnList();
Label l0 = new Label();
inject.add(new LabelNode(l0));
String callString = owner.name + "." + mn.name + " " + mn.desc;
LdcInsnNode ldc = new LdcInsnNode(callString);
MethodInsnNode methodNode = new MethodInsnNode(Opcodes.INVOKESTATIC, "org/parabot/core/Core", "debug",
"(Ljava/lang/String;)V");
inject.add(ldc);
inject.add(methodNode);
mn.instructions.insert(inject);
}
}
@@ -0,0 +1,184 @@
package org.parabot.core.asm.adapters;
import java.lang.reflect.Modifier;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Core;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable;
/**
* Adds a method into a Classnode which returns a field
*
* @author Everel
*
*/
public class AddGetterAdapter implements Opcodes, Injectable {
private ClassNode into;
private ClassNode fieldLocation;
private FieldNode fieldNode;
private String methodName;
private String returnDesc;
private boolean staticField;
private boolean staticMethod;
private long multiplier;
/**
*
* @param into
* - classnode to inject getter method in
* @param fieldLocation
* - classnode where field is located
* @param fieldName
* - field name to get
* @param methodName
* - method name of getter
* @param returnDesc
* - return type of method, can be null for default return
* @param staticMethod
* - pass true if you want the method to be static
* @param multiplier
* - if this field requires a multipli
*/
public AddGetterAdapter(final ClassNode into,
final ClassNode fieldLocation, final FieldNode fieldNode,
final String methodName, final String returnDesc,
final boolean staticMethod, final long multiplier) {
System.out.println(fieldNode.name);
this.into = into;
this.fieldLocation = fieldLocation;
this.fieldNode = fieldNode;
this.methodName = methodName;
this.returnDesc = returnDesc == null ? fieldNode.desc : returnDesc;
this.staticField = Modifier.isStatic(fieldNode.access);
this.staticMethod = staticMethod;
this.multiplier = multiplier;
}
/**
*
* @param fieldLocation
* @param fieldNode
* @param methodName
*/
public AddGetterAdapter(final ClassNode fieldLocation,
final FieldNode fieldNode, final String methodName) {
this.into = fieldLocation;
this.fieldLocation = fieldLocation;
this.fieldNode = fieldNode;
this.methodName = methodName;
this.returnDesc = fieldNode.desc;
this.staticField = Modifier.isStatic(fieldNode.access);
this.staticMethod = false;
}
/**
* Validates if this getter can be injected, if not a runtime exception is
* thrown
*/
public void validate() {
if (methodName == null) {
throw new RuntimeException("Null method name");
}
if (into == null) {
final StringBuilder sb = new StringBuilder();
sb.append("Into ClassNode is null, at : ").append(methodName)
.append("()");
throw new RuntimeException(sb.toString());
}
if (fieldNode == null) {
final StringBuilder sb = new StringBuilder();
sb.append("FieldLocation ClassNode is null, at : ")
.append(methodName).append("()");
throw new RuntimeException(sb.toString());
}
if (fieldNode == null) {
final StringBuilder sb = new StringBuilder();
sb.append("FieldNode is null, at : ").append(methodName)
.append("()");
throw new RuntimeException(sb.toString());
}
for (final MethodNode methodNode : into.methods) {
if (methodNode.name.equals(methodName)) {
final Type[] args = Type.getArgumentTypes(methodNode.desc);
if (args != null && args.length != 0) {
continue;
}
final StringBuilder sb = new StringBuilder();
sb.append("Duplicated method detected. ").append(methodName)
.append("() in ").append(into.name);
throw new RuntimeException(sb.toString());
}
}
}
/**
* Injects this the method getter
*/
@Override
public void inject() {
Core.verbose("Injecting: " + this.toString());
MethodNode method = new MethodNode(ACC_PUBLIC
| (staticMethod ? ACC_STATIC : 0), methodName, "()"
+ returnDesc, null, null);
if (!staticField) {
method.visitVarInsn(ALOAD, 0);
}
if(staticField) {
ASMUtils.makePublic(fieldNode);
}
method.visitFieldInsn(staticField ? GETSTATIC : GETFIELD,
fieldLocation.name, fieldNode.name, fieldNode.desc);
if (!fieldNode.desc.equals(returnDesc)) {
if (returnDesc.contains("L")) {
if (!returnDesc.contains("[")) {
method.visitTypeInsn(CHECKCAST,
returnDesc.replaceFirst("L", "")
.replaceAll(";", ""));
} else {
method.visitTypeInsn(CHECKCAST, returnDesc);
}
}
}
if (multiplier != 0) {
if (fieldNode.desc.equals("I") || fieldNode.desc.equals("S")) {
method.visitInsn(I2L);
}
method.visitLdcInsn(new Long(multiplier));
method.visitInsn(LMUL);
if (returnDesc.equals("I") || returnDesc.equals("S")) {
method.visitInsn(L2I);
}
if (returnDesc.equals("S")) {
method.visitInsn(I2S);
}
} else if (fieldNode.desc.equals("J") && returnDesc.equals("I")) {
method.visitInsn(L2I);
} else if (fieldNode.desc.equals("I") && returnDesc.equals("J")) {
method.visitInsn(I2L);
}
method.visitInsn(ASMUtils.getReturnOpcode(returnDesc));
method.visitMaxs(1, 1);
into.methods.add(method);
}
@Override
public String toString() {
return new StringBuilder("[Injectable: getter, into classname: ")
.append(into.name).append(", field classname: ")
.append(fieldLocation.name).append(", field name: ")
.append(fieldNode.name).append(", field desc: ")
.append(fieldNode.desc).append(", method name: ")
.append(methodName).append(", return desc: ")
.append(returnDesc).append(", static method: ")
.append(staticMethod).append(", static field: ")
.append(staticField).append("]").toString();
}
}
@@ -0,0 +1,60 @@
package org.parabot.core.asm.adapters;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Core;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* This class appends an interface to a class
*
* @author Everel
*
*/
public class AddInterfaceAdapter implements Injectable {
private static String accessorPackage;
private ClassNode node;
private String interfaceClass;
public AddInterfaceAdapter(ClassNode node, String interfaceClass) {
this.node = node;
this.interfaceClass = interfaceClass;
}
public AddInterfaceAdapter(String className, String interfaceClass) {
this.node = ASMUtils.getClass(className);
this.interfaceClass = interfaceClass;
}
public static void setAccessorPackage(String packageName) {
accessorPackage = packageName;
}
public static String getAccessorPackage() {
return accessorPackage;
}
@Override
public void inject() {
Core.verbose("Injecting: " + this.toString());
addInterface(node, accessorPackage + interfaceClass);
}
protected static void addInterface(ClassNode node, String i) {
ASMUtils.makePublic(node);
for(MethodNode mn : node.methods) {
if(mn.name.startsWith("<init")) {
ASMUtils.makePublic(mn);
}
}
node.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,117 @@
package org.parabot.core.asm.adapters;
import java.lang.reflect.Modifier;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
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;
private ClassNode methodLocation;
private MethodNode mn;
private String argsDesc;
private String returnDesc;
private String methodName;
private boolean isInterface;
private String instanceCast;
private String mName;
private String mDesc;
private String argsCheckCast;
private boolean isStatic;
public AddInvokerAdapter(final ClassNode methodLocation,
final ClassNode into, final MethodNode mn, final String mName, final String mDesc, final String argsDesc,
final String returnDesc, final String methodName,
boolean isInterface, String instanceCast, String argsCheckCastDesc) {
this.into = into;
this.methodLocation = methodLocation;
this.mName = mName;
this.mDesc = mDesc;
this.mn = mn;
this.argsDesc = argsDesc;
this.returnDesc = returnDesc;
this.methodName = methodName;
this.isInterface = isInterface;
this.instanceCast = instanceCast;
this.argsCheckCast = argsCheckCastDesc;
}
@Override
public void inject() {
String mArgsDesc = argsCheckCast == null ? this.argsDesc : this.argsCheckCast;
MethodNode m = new MethodNode(ACC_PUBLIC, this.methodName,
mArgsDesc + this.returnDesc, null, null);
if(!isInterface) {
isStatic = (this.mn.access & ACC_STATIC) != 0;
if (!Modifier.isPublic(mn.access)) {
if (Modifier.isPrivate(mn.access)) {
mn.access = mn.access & (~ACC_PRIVATE);
}
if (Modifier.isProtected(mn.access)) {
mn.access = mn.access & (~ACC_PROTECTED);
}
mn.access = mn.access | ACC_PUBLIC;
//mn.access = mn.access | ACC_SYNCHRONIZED;
}
}
if(!isStatic || isInterface) {
m.visitVarInsn(ALOAD, 0);
}
if(instanceCast != null) {
m.visitTypeInsn(CHECKCAST, instanceCast);
}
if (!this.argsDesc.equals("()")) {
Type[] castArgs = argsCheckCast == null ? null : Type.getArgumentTypes(argsCheckCast + "V");
Type[] methodArgs = Type.getArgumentTypes(argsDesc + "V");
for(int i = 0; i < methodArgs.length; i++) {
m.visitVarInsn(ASMUtils.getLoadOpcode(methodArgs[i].getDescriptor()), i + 1);
if(castArgs != null && !castArgs[i].getDescriptor().equals(methodArgs[i].getDescriptor())) {
String cast = methodArgs[i].getDescriptor();
if(cast.startsWith("L")) {
cast = cast.substring(1).replace(";", "");
}
m.visitTypeInsn(CHECKCAST, cast);
}
}
}
if(isInterface) {
m.visitMethodInsn(INVOKEINTERFACE, instanceCast, mName, mDesc);
} else {
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);
}
}
@@ -0,0 +1,85 @@
package org.parabot.core.asm.adapters;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Core;
import org.parabot.core.asm.interfaces.Injectable;
/**
* Injects methods which sets a field
*
* @author Everel
*
*/
public class AddSetterAdapter implements Opcodes, Injectable {
private ClassNode fieldLocation;
private ClassNode into;
private FieldNode field;
private String name;
private String desc;
private boolean methodStatic;
public AddSetterAdapter(ClassNode fieldLocation, ClassNode into,
FieldNode field, String name, String desc, boolean methodStatic) {
this.fieldLocation = fieldLocation;
this.into = into;
this.field = field;
this.name = name;
this.desc = desc;
this.methodStatic = methodStatic;
}
public AddSetterAdapter(ClassNode fieldLocation, ClassNode into,
FieldNode field, String name, String desc) {
this(fieldLocation, into, field, name, desc, false);
}
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;"))
desc = "Ljava/lang/Object;";
MethodNode method = new MethodNode(ACC_PUBLIC
| (methodStatic ? ACC_STATIC : 0), name, "(" + desc + ")V",
null, null);
boolean isStatic = (field.access & ACC_STATIC) > 0;
if (!isStatic) {
method.visitVarInsn(ALOAD, 0);
}
if (desc.equals("I")) {
method.visitVarInsn(ILOAD, 1);
} else if (desc.equals("J")) {
method.visitVarInsn(Opcodes.LLOAD, 1);
} else {
method.visitVarInsn(ALOAD, 1);
}
method.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD,
fieldLocation.name, field.name, field.desc);
method.visitInsn(RETURN);
method.visitMaxs(2, 2);
into.methods.add(method);
}
/**
* Injects the setter
*/
@Override
public void inject() {
Core.verbose("Injecting: " + this.toString());
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();
}
}
@@ -0,0 +1,68 @@
package org.parabot.core.asm.adapters;
import java.util.ListIterator;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.parabot.core.Core;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* This class is used for changing the super class of a class
*
* @author Everel
*
*/
public class AddSuperAdapter implements Injectable {
private ClassNode node;
private String superClass;
public AddSuperAdapter(final ClassNode node, final String superClass) {
this.node = node;
this.superClass = superClass;
}
public AddSuperAdapter(final String className, final String superClass) {
this.node = ASMUtils.getClass(className);
this.superClass = superClass;
}
@Override
public void inject() {
Core.verbose("Injecting: " + this.toString());
setSuper(node, superClass);
}
private static final void setSuper(final ClassNode node,
final String superClass) {
ListIterator<?> mli = node.methods.listIterator();
while (mli.hasNext()) {
MethodNode mn = (MethodNode) mli.next();
if (mn.name.equals("<init>")) {
ListIterator<?> ili = mn.instructions.iterator();
while (ili.hasNext()) {
AbstractInsnNode ain = (AbstractInsnNode) ili.next();
if (ain.getOpcode() == Opcodes.INVOKESPECIAL) {
MethodInsnNode min = (MethodInsnNode) ain;
min.owner = superClass;
break;
}
}
}
}
node.superName = superClass;
}
@Override
public String toString() {
return new StringBuilder("[Injectable: super, class name: ")
.append(node.name).append(", super: ").append(superClass)
.append("]").toString();
}
}
@@ -0,0 +1,50 @@
package org.parabot.core.asm.hooks;
import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import org.parabot.core.parsers.hooks.HookParser;
import org.parabot.core.parsers.hooks.JSONHookParser;
import org.parabot.core.parsers.hooks.XMLHookParser;
import org.parabot.environment.api.utils.WebUtil;
public class HookFile {
public static final int TYPE_XML = 0;
public static final int TYPE_JSON = 1;
private URL url;
private int type;
public HookFile(File file, int type) throws MalformedURLException {
this(file.toURI().toURL(), type);
}
public HookFile(URL url, int type) {
setType(type);
this.url = url;
}
private void setType(int type) {
if(type < 0 || type > 1) {
throw new IllegalArgumentException("This type does not exist");
}
this.type = type;
}
public InputStream getInputStream() {
return WebUtil.getInputStream(url);
}
public HookParser getParser() {
switch(type) {
case TYPE_XML:
return new XMLHookParser(this);
case TYPE_JSON:
return new JSONHookParser(this);
}
return null;
}
}
@@ -0,0 +1,15 @@
package org.parabot.core.asm.interfaces;
/**
* Injectable
* @author Everel
*
*/
public interface Injectable {
/**
* Injects bytecode into a class
*/
public void inject();
}
@@ -0,0 +1,15 @@
package org.parabot.core.asm.redirect;
import org.parabot.core.asm.RedirectClassAdapter;
public class ClassLoaderRedirect {
public static Class<?>loadClass(ClassLoader c,String name){
throw RedirectClassAdapter.createSecurityException();
}
static int count = 0;
public static ClassLoader getParent(ClassLoader c){
throw RedirectClassAdapter.createSecurityException();
}
}
@@ -0,0 +1,47 @@
package org.parabot.core.asm.redirect;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.parabot.core.asm.RedirectClassAdapter;
public class ClassRedirect {
public static Object newInstance(Class<?>c){
throw RedirectClassAdapter.createSecurityException();
}
public static Field getDeclaredField(Class<?> c, String s) throws NoSuchFieldException, SecurityException{
System.out.println(c.getName() + "." + c.getDeclaredField(s) + " Blocked.");
throw RedirectClassAdapter.createSecurityException();
}
public static Method getDeclaredMethod(Class<?>c,String name,Class<?>... params) throws NoSuchMethodException, SecurityException{
System.out.println(c.getName() + "#" + c.getDeclaredMethod(name,params) + " Blocked.");
throw RedirectClassAdapter.createSecurityException();
}
public static Class<?> forName(String name) throws ClassNotFoundException{
if(name.contains("parabot"))
throw new ClassNotFoundException();
return Class.forName(name);
}
public static ClassLoader getClassLoader(Class<?>c){
throw RedirectClassAdapter.createSecurityException();
}
public static String getName(Class<?>c){
if(c.getName().contains("parabot"))
return "java.lang.String";
return c.getName();
}
public static InputStream getResourceAsStream(Class<?>c, String res){
if(res.contains(".class"))
throw RedirectClassAdapter.createSecurityException();
return c.getResourceAsStream(res);
}
}
@@ -0,0 +1,9 @@
package org.parabot.core.asm.redirect;
public class PacketCallback {
public static void onPacket(String methodName,int value){
System.out.println(methodName + "(" + value + ")");
}
}
@@ -0,0 +1,7 @@
package org.parabot.core.asm.redirect;
/**
* @author JKetelaar
*/
public class PreferencesRedirect {
}
@@ -0,0 +1,5 @@
package org.parabot.core.asm.redirect;
public class ProcessBuilderRedirect {
}
@@ -0,0 +1,21 @@
package org.parabot.core.asm.redirect;
import org.parabot.core.asm.RedirectClassAdapter;
public class RuntimeRedirect {
public static Runtime getRuntime(){
return Runtime.getRuntime();
}
public static int availableProcessors(Runtime r){
//lol faking it, fuck ikov
return 2;
}
public static Process exec(Runtime r,String s){
System.out.println("Blocked attempted command:" + s);
throw RedirectClassAdapter.createSecurityException();
}
}
@@ -0,0 +1,5 @@
package org.parabot.core.asm.redirect;
public class StackTraceElementRedirect {
}
@@ -0,0 +1,94 @@
package org.parabot.core.asm.redirect;
import org.parabot.core.Directories;
import java.io.InputStream;
import java.io.PrintStream;
public class SystemRedirect {
public static PrintStream out = System.out;
public static PrintStream err = System.err;
public static InputStream in = System.in;
public static long currentTimeMillis() {
return System.currentTimeMillis();
}
public static void arraycopy(Object o1, int i1, Object o2, int i2, int i3) {
System.arraycopy(o1, i1, o2, i2, i3);
}
public static void exit(int i) {
System.exit(i);
}
public static String getProperty(String s) {
String value;
switch (s) {
case "user.home":
value = Directories.getHomeDir().getAbsolutePath();
break;
default:
value = System.getProperty(s);
}
System.out.printf("GetSystemProp %s = %s\n", s, value);
return value;
}
public static String getProperty(String s, String s2) {
String value = null;
switch (s2) {
case "user.home":
value = Directories.getHomeDir().getAbsolutePath();
break;
}
if (value == null) {
switch (s) {
case "user.home":
value = Directories.getHomeDir().getAbsolutePath();
break;
default:
value = System.getProperty(s);
}
}
System.out.printf("GetSystemProp %s = %s\n", s, value);
return value;
}
public static void gc() {
System.gc();
}
public static String setProperty(String s1, String s2) {
System.out.printf("SetSystemProp %s = %s", s1, s2);
return System.setProperty(s1, s2);
}
public static String getenv(String string) {
return System.getenv(string);
}
public static void setOut(PrintStream printStream) {
}
public static void setErr(PrintStream printStream) {
}
public static void setIn(PrintStream printStream) {
}
public static void runFinalization() {
}
public static long nanoTime() {
return System.nanoTime();
}
}
@@ -0,0 +1,49 @@
package org.parabot.core.asm.redirect;
import org.parabot.core.asm.RedirectClassAdapter;
public class ThreadRedirect {
private static int count = 0;
public static void start(Thread t){
t.start();
}
public static void setPriority(Thread t,int i){
t.setPriority(i);
}
public static void setDaemon(Thread t,boolean b){
t.setDaemon(b);
}
public static void interrupt(Thread t){
t.interrupt();
}
public static Thread currentThread(){
return null;
}
public static ClassLoader getContextClassLoader(Thread t){
return null;
}
public static ThreadGroup getThreadGroup(Thread t){
throw RedirectClassAdapter.createSecurityException();
}
public static void setName(Thread t, String name){
t.setName(name);
}
public static String getName(Thread t){
return t.getName();
}
public static void sleep(long time) throws InterruptedException{
Thread.sleep(time);
}
}
@@ -0,0 +1,61 @@
package org.parabot.core.asm.redirect;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.net.URL;
public class ToolkitRedirect {
private static final Clipboard clipboard = new Clipboard("default");
static{
clipboard.setContents(new Transferable() {
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[0];
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return false;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
throw new UnsupportedFlavorException(flavor);
}
}, null);
}
public static Toolkit getDefaultToolkit(){
return Toolkit.getDefaultToolkit();
}
public static Dimension getScreenSize(Toolkit t){
return new Dimension(0,0);
}
public static Image createImage(Toolkit t,byte[] b){
return t.createImage(b);
}
public static Image getImage(Toolkit t,URL u){
return t.getImage(u);
}
public static Image getImage(Toolkit t,String str){
return t.getImage(str);
}
public static Cursor createCustomCursor(Toolkit t, Image i, Point p, String s){
return Cursor.getDefaultCursor();
}
public static Clipboard getSystemClipboard(Toolkit toolkit){
return clipboard;
}
}
@@ -0,0 +1,52 @@
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;
/**
*
* This class is used for injecting a callback into a methodnode
*
* @author Everel
*
*/
public class Callback implements Injectable {
private MethodNode method;
private String invokeClass;
private String invokeMethod;
private String desc;
private int[] args;
private boolean conditional;
public Callback(final String className, final String methodName,
final String methodDesc, final String callbackClass,
final String callbackMethod, final String callbackDesc, String args, final boolean conditional) {
this.method = ASMUtils.getMethod(className, methodName, methodDesc);
this.invokeClass = callbackClass;
this.invokeMethod = callbackMethod;
this.desc = callbackDesc;
this.conditional = conditional;
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, this.conditional);
}
}
@@ -0,0 +1,82 @@
package org.parabot.core.asm.wrappers;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.parabot.core.Core;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.adapters.AddGetterAdapter;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* This class injects a getter which gets a specific field
*
* @author Everel
*
*/
public class Getter implements Injectable {
private ClassNode into;
private ClassNode fieldLocation;
private FieldNode fieldNode;
private String methodName;
private String returnDesc;
private boolean staticMethod;
private long multiplier;
/**
*
* @param into - classnode to inject getter method in
* @param fieldLocation - classnode where field is located
* @param fieldName - field name to get
* @param methodName - method name of getter
* @param returnDesc - return type of method, can be null for default return
* @param staticMethod - pass true if you want the method to be static
* @param multiplier - if there is one, otherwise 0L
* @param fieldDesc - desc of the field, null if there are no duplicate field names
*/
public Getter(final String into, final String fieldLocation, final String fieldNode,
final String methodName, final String returnDesc, final boolean staticMethod, final long multiplier,
final String fieldDesc) {
this.into = ASMUtils.getClass(into);
this.fieldLocation = ASMUtils.getClass(fieldLocation);
this.fieldNode = ASMUtils.getField(ASMUtils.getClass(fieldLocation), fieldNode, fieldDesc);
this.methodName = methodName;
this.returnDesc = returnDesc == null ? this.fieldNode.desc : returnDesc;
this.staticMethod = staticMethod;
this.multiplier = multiplier;
Core.verbose(methodName + "[" + fieldLocation + "." + fieldNode + "]");
}
/**
*
* @param fieldLocation
* @param fieldNode
* @param methodName
*/
public Getter(final String fieldLocation, final String fieldNode, final String methodName) {
this.into = ASMUtils.getClass(fieldLocation);
this.fieldLocation = this.into;
this.fieldNode = ASMUtils.getField(this.into, fieldNode);
this.methodName = methodName;
this.returnDesc = this.fieldNode.desc;
this.staticMethod = false;
}
/**
* Short route for getAdaptar().inject();
* @see AddGetterAdapter#inject
*/
@Override
public void inject() {
getAdapter().inject();
}
/**
* Gets the AddGetterAdapter
* @return AddGetterAdapter
*/
public AddGetterAdapter getAdapter() {
return new AddGetterAdapter(into, fieldLocation, fieldNode, methodName, returnDesc, staticMethod, multiplier);
}
}
@@ -0,0 +1,44 @@
package org.parabot.core.asm.wrappers;
import org.parabot.core.asm.adapters.AddInterfaceAdapter;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* This class appends an interface to a class
*
* @author Everel
*
*/
public class Interface implements Injectable {
private String className;
private String interfaceClass;
public Interface(String className, String interfaceClass) {
this.className = className;
this.interfaceClass = interfaceClass;
}
/**
* Adds the interface to the class
* Short route for getAdapter#inject();
*/
@Override
public void inject() {
getAdapter().inject();
}
/**
* Gets the add interface adapter
* @return AddInterface adapter
*/
public AddInterfaceAdapter getAdapter() {
return new AddInterfaceAdapter(className, interfaceClass);
}
@Override
public String toString() {
return String.format("%s implements %s%s", className, AddInterfaceAdapter.getAccessorPackage().replaceAll("/", "."), interfaceClass);
}
}
@@ -0,0 +1,82 @@
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;
/**
*
* This class is used for injecting an invoker into a methodnode
*
* @author Everel
*
*/
public class Invoker implements Injectable {
private ClassNode into;
private ClassNode methodLocation;
private MethodNode mn;
private String argsDesc;
private String returnDesc;
private String methodName;
private boolean isInterface;
private String instanceCast;
private String argsCheckCastDesc;
private String mName;
private String mDesc;
public Invoker(String methodLoc, String invMethName, String argsDesc,
String returnDesc, String methodName) {
this(methodLoc, methodLoc, invMethName, argsDesc, returnDesc,
methodName, false, null, null);
}
public Invoker(String into, String methodLoc, String invMethName,
String argsDesc, String returnDesc, String methodName, boolean isInterface, String instanceCast, String argsCheckCastDesc) {
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;
this.isInterface = isInterface;
this.instanceCast = instanceCast;
this.mName = invMethName;
this.mDesc = argsDesc + returnDesc;
this.argsCheckCastDesc = argsCheckCastDesc;
}
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.mName, this.mDesc,
this.argsDesc, this.returnDesc, this.methodName, this.isInterface, this.instanceCast, this.argsCheckCastDesc);
}
}
@@ -0,0 +1,55 @@
package org.parabot.core.asm.wrappers;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.parabot.core.asm.ASMUtils;
import org.parabot.core.asm.adapters.AddSetterAdapter;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* This class is used for injecting a setter for a specific field
*
* @author Everel
*
*/
public class Setter implements Injectable {
private ClassNode fieldLocation;
private ClassNode into;
private FieldNode field;
private String name;
private String desc;
private boolean methodStatic;
public Setter(final String fieldLocation, String into, final String fieldName, final String methodName, final String desc, final boolean methodStatic, final String fieldDesc) {
this.fieldLocation = ASMUtils.getClass(fieldLocation);
into = (into == null) ? fieldLocation : into;
this.into = ASMUtils.getClass(into);
this.field = ASMUtils.getField(this.fieldLocation, fieldName, fieldDesc);
this.name = methodName;
this.desc = (desc == null) ? this.field.desc : desc;
this.methodStatic = methodStatic;
}
public Setter(final String fieldLocation, final String fieldName, final String methodName) {
this(fieldLocation, null, fieldName, methodName, null, false, null);
}
/**
* Short route for getAdaptar().inject();
* @see AddSetterAdapter#inject
*/
@Override
public void inject() {
getAdapter().inject();
}
/**
* Gets the AddGetterAdapter
* @return AddGetterAdapter
*/
public AddSetterAdapter getAdapter() {
return new AddSetterAdapter(fieldLocation, into, field, name, desc, methodStatic);
}
}
@@ -0,0 +1,34 @@
package org.parabot.core.asm.wrappers;
import org.parabot.core.asm.adapters.AddSuperAdapter;
import org.parabot.core.asm.interfaces.Injectable;
/**
*
* This class is used for changing the super class of a class
*
* @author Everel
*
*/
public class Super implements Injectable {
private String className;
private String superClassName;
public Super(String className, String superClassName) {
this.className = className;
this.superClassName = superClassName;
}
/**
* Adds a superclass to a class
* Short route for getAdapter().inject
*/
@Override
public void inject() {
getAdapter().inject();
}
public AddSuperAdapter getAdapter() {
return new AddSuperAdapter(className, superClassName);
}
}
@@ -0,0 +1,26 @@
package org.parabot.core.build;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
/**
*
* Class used for adding urls to the buildpath
*
* @author Everel
*
*/
public class BuildPath {
public static void add(final URL url) {
try {
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke((URLClassLoader) ClassLoader.getSystemClassLoader(), url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,312 @@
package org.parabot.core.classpath;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.tree.ClassNode;
import org.parabot.core.Directories;
import org.parabot.core.asm.ClassRemapper;
import org.parabot.core.asm.RedirectClassAdapter;
import org.parabot.core.build.BuildPath;
import org.parabot.core.io.SizeInputStream;
import org.parabot.core.ui.components.VerboseLoader;
/**
*
* Manages, parses and dumps class files & jars
*
* @author Everel
* @author Matt
*/
public class ClassPath {
public final ArrayList<String> classNames;
public final HashMap<String, ClassNode> classes;
public final Map<String, File> resources;
public URL lastParsed;
private ClassRemapper classRemapper;
private boolean isJar;
private boolean parseJar;
private ArrayList<URL> jarFiles;
public ClassPath() {
this(false);
}
public ClassPath(final boolean isJar) {
this.classNames = new ArrayList<String>();
this.classes = new HashMap<String, ClassNode>();
this.resources = new HashMap<String, File>();
this.classRemapper = new ClassRemapper();
this.parseJar = true;
this.jarFiles = new ArrayList<URL>();
this.isJar = isJar;
}
public void addJar(final File file) {
try {
addJar(file.toURI().toURL());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public void addJar(final URL url) {
this.lastParsed = url;
try {
addJar(url.openConnection());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Adds a jar to this classpath
*
* @param url
*/
public void addJar(final URLConnection connection) {
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) {
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
*
* @param file
* to find class / jar files
* @param root
*/
public void addClasses(final File f, File root) {
if (f == null)
return;
if (!f.exists()) {
f.mkdirs();
}
if (root == null) {
root = f;
}
for (File f1 : f.listFiles()) {
if (f1 == null) {
continue;
} else if (f1.isDirectory()) {
addClasses(f1, root);
} else {
try (FileInputStream fin = new FileInputStream(f1)) {
if (f1.getName().endsWith(".class"))
loadClass(fin);
else if (f.equals(root) && f1.getName().endsWith(".jar")) {
jarFiles.add(f1.toURI().toURL());
if (this.parseJar) {
// if enabled, there may be problem with duplicate
// class names.......
addJar(f1.toURI().toURL());
}
} else {
String path = f1.toURI().relativize(root.toURI())
.getPath();
loadResource(path, fin);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* Loads class from input stream
*
* @param inputstream
* @throws IOException
*/
protected void loadClass(InputStream in) throws IOException {
ClassReader cr = new ClassReader(in);
ClassNode cn = new ClassNode();
RemappingClassAdapter rca = new RemappingClassAdapter(cn,classRemapper);
RedirectClassAdapter redir = new RedirectClassAdapter(rca);
cr.accept(redir, ClassReader.EXPAND_FRAMES);
classNames.add(cn.name.replace('/', '.'));
classes.put(cn.name, cn);
}
/**
* Determines if this classpath represents a jar file
*
* @return if this classpath represents a jar file
*/
public boolean isJar() {
return isJar;
}
/**
* Gets all jar files in this classpath
*
* @return array of classpath
*/
public ClassPath[] getJarFiles() {
final ClassPath[] jars = new ClassPath[jarFiles.size()];
for (int i = 0; i < jarFiles.size(); i++) {
final ClassPath classPath = new ClassPath(true);
classPath.addJar(jarFiles.get(i));
jars[i] = classPath;
}
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);
}
/**
* Adds this jar to buildpath
*/
public void addToBuildPath() {
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());
}
for(Entry<String, File> entry : this.resources.entrySet()) {
JarEntry je = new JarEntry(entry.getKey());
out.putNextEntry(je);
out.write(Files.readAllBytes(entry.getValue().toPath()));
}
out.close();
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,136 @@
package org.parabot.core.desc;
/**
* Holds information about a script
*
* @author Everel
*
*/
public class ScriptDescription implements Comparable<ScriptDescription> {
public String scriptName;
public String author;
public String category;
public double version;
public String description;
public String[] servers;
public String isVip;
public String isPremium;
public int bdnId;
/**
* The ScriptManifest
*
* @param scriptName
* @param author
* @param category
* @param version
* @param description
* @param servers
*/
public ScriptDescription(final String scriptName, final String author,
final String category, final double version,
final String description, final String[] servers) {
this(scriptName, author, category, version, description, servers, null,
null, -1);
}
/**
* Used for BDN script (see BDNScripts parser)
*
* @param scriptName
* @param author
* @param category
* @param version
* @param description
* @param servers
* @param bdnId
*/
public ScriptDescription(final String scriptName,
final String author, final String category, final double version,
final String description, final String[] servers, final int bdnId) {
this(scriptName, author, category, version, description, servers, null,
null, bdnId);
}
/**
* Used by bot (java scripts and python scripts) and BDN Manager (bdn
* 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);
}
/**
* Main constructor
*
* @param scriptName
* @param author
* @param category
* @param version
* @param description
* @param servers
* @param vip
* @param premium
* @param bdnId
*/
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 bdnId) {
this.scriptName = scriptName;
this.author = author;
this.category = category;
this.version = version;
this.description = description;
this.servers = servers;
this.isVip = vip;
this.isPremium = premium;
this.bdnId = bdnId;
}
@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: ");
if(this.servers != null) {
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(", bdn id: ")
.append(this.bdnId == -1 ? "unknown" : Integer
.toString(this.bdnId))
.append("]");
return b.toString();
}
@Override
public int compareTo(ScriptDescription o) {
return scriptName.compareTo(o.scriptName);
}
}
@@ -0,0 +1,45 @@
package org.parabot.core.desc;
/**
*
* Holds information about a server
*
* @author Everel
*
*/
public class ServerDescription implements Comparable<ServerDescription> {
private String serverName;
private String author;
private double revision;
public ServerDescription(final String serverName, final String author,
final double revision) {
this.serverName = serverName;
this.author = author;
this.revision = revision;
}
public String getServerName() {
return this.serverName;
}
public String getAuthor() {
return this.author;
}
public double getRevision() {
return this.revision;
}
@Override
public String toString() {
return String.format("[Server: %s, Author: %s, Revision: %.2f]",
this.serverName, this.author, this.revision);
}
@Override
public int compareTo(ServerDescription o) {
return this.getServerName().compareTo(o.getServerName());
}
}
@@ -0,0 +1,121 @@
package org.parabot.core.desc;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.parabot.core.Core;
import org.parabot.core.ui.utils.UILog;
import org.parabot.environment.api.utils.WebUtil;
import javax.swing.*;
import java.io.BufferedReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Gets the information for the selected server provider
*
* @author Paradox, Everel
*
*/
public class ServerProviderInfo {
private HashMap<String, Integer> settings;
private Properties properties;
public ServerProviderInfo(URL providerInfo, String username, String password) {
this.properties = new Properties();
this.settings = new HashMap<>();
try {
String line;
Core.verbose("Reading info: " + providerInfo);
BufferedReader br = WebUtil.getReader(new URL(providerInfo.toString()), username, password);
//TODO Make this one line (web sided)
JSONParser parser = new JSONParser();
if ((line = br.readLine()) != null) {
JSONObject jsonObject = (JSONObject) parser.parse(line);
for (Object o : jsonObject.entrySet()) {
Map.Entry<?, ?> pairs = (Map.Entry<?, ?>) o;
if (String.valueOf(pairs.getKey()).equalsIgnoreCase("settings")){
JSONObject object = (JSONObject) pairs.getValue();
for (Object settingObject : object.entrySet()){
Map.Entry<?, ?> settingValue = (Map.Entry<?, ?>) settingObject;
String key = (String) settingValue.getKey();
long value = (Long) settingValue.getValue();
settings.put(key, (int) value);
}
}else {
properties.put(String.valueOf(pairs.getKey()), String.valueOf(pairs.getValue()));
}
}
} else {
UILog.log(
"Error",
"Failed to load server provider, error: [No information about the provider found.]",
JOptionPane.ERROR_MESSAGE);
return;
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public URL getClient() {
try {
return new URL(properties.getProperty("client_jar"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public URL getExtendedHookFile() {
try {
return new URL(properties.getProperty("hooks") /*+ "&extended=true"*/);
} catch (MalformedURLException e) {
e.printStackTrace();
return getHookFile();
}
}
public URL getHookFile() {
try {
return new URL(properties.getProperty("hooks"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public String getClientClass() {
return properties.getProperty("client_class");
}
public String getServerName() {
return properties.getProperty("name");
}
public long getCRC32() {
return Long.parseLong(properties.getProperty("provider_crc32"));
}
public long getClientCRC32() {
return Long.parseLong(properties.getProperty("client_crc32"));
}
public int getBankTabs() {
return Integer.parseInt(properties.getProperty("bank_tabs"));
}
public Properties getProperties() {
return this.properties;
}
public HashMap<String, Integer> getSettings() {
return settings;
}
}
@@ -0,0 +1,81 @@
package org.parabot.core.forum;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
*
* 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;
private String password;
private String api;
/**
*
* @param username - Forum account username
* @param password - Forum account password
*/
public Account(final String username, final String password) {
this.username = username;
this.password = password;
}
public Account(String username, String password, String api) {
this.username = username;
this.password = password;
this.api = api;
}
/**
* Gets user's parabot account name
* @return username.
*/
public String getUsername() {
return this.username;
}
/**
* Gets user's parabot password
* @return password.
*/
public String getPassword() {
return this.password;
}
/**
* Gets user's parabot account name
* @return username, already URL UTF-8 encoded.
*/
public String getURLUsername(){
try {
return URLEncoder.encode(this.username, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* Gets user's password
* @return password, already URL UTF-8 encoded.
*/
public String getURLPassword(){
try {
return URLEncoder.encode(this.password, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public String getApi() {
return api;
}
}
@@ -0,0 +1,118 @@
package org.parabot.core.forum;
import org.json.simple.JSONObject;
import org.parabot.core.Configuration;
import org.parabot.core.Context;
import org.parabot.core.Core;
import org.parabot.core.parsers.scripts.BDNScripts;
import org.parabot.core.parsers.servers.PublicServers;
import org.parabot.core.ui.components.VerboseLoader;
import org.parabot.environment.api.utils.PBPreferences;
import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.scripts.executers.BDNScriptsExecuter;
import org.parabot.environment.servers.executers.PublicServerExecuter;
import javax.swing.*;
import java.io.BufferedReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
/**
* Handles logging in to parabot forum, only certain classes may use this class.
*
* @author Everel
*
*/
public final class AccountManager {
private static boolean validated;
private static AccountManager instance;
private Account account;
private AccountManager() {
}
public static final void validate() {
if (validated) {
return;
}
validated = true;
instance = new AccountManager();
Core.verbose("Initializing account manager accessors...");
final ArrayList<AccountManagerAccess> accessors = new ArrayList<AccountManagerAccess>();
accessors.add(BDNScripts.MANAGER_FETCHER);
accessors.add(VerboseLoader.MANAGER_FETCHER);
accessors.add(BDNScriptsExecuter.MANAGER_FETCHER);
accessors.add(PublicServers.MANAGER_FETCHER);
accessors.add(PublicServerExecuter.MANAGER_FETCHER);
accessors.add(PBPreferences.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, boolean requestTwoStep) {
if (account != null) {
throw new IllegalStateException("Already logged in.");
}
JSONObject result = null;
if (!requestTwoStep){
try {
BufferedReader contents = WebUtil.getReader(WebUtil.getConnection(
new URL(Configuration.LOGIN_SERVER),
URLEncoder.encode(user, "UTF-8"),
URLEncoder.encode(pass, "UTF-8")));
result = (JSONObject) WebUtil.getJsonParser().parse(contents);
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}else{
try {
String two = JOptionPane.showInputDialog("Please provide your two factor authentication code\nYou can find this in either your email or the app you've setup");
if (two != null && two.length() > 0) {
String contents = WebUtil.getContents(Configuration.LOGIN_SERVER,
"username=" + URLEncoder.encode(user, "UTF-8") + "&password=" + URLEncoder.encode(pass, "UTF-8") + "&2fa=" + URLEncoder.encode(two, "UTF-8")
);
result = (JSONObject) WebUtil.getJsonParser().parse(contents);
}
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
if (result != null) {
if (result.get("complete") != null) {
String api = (String) ((JSONObject) result.get("data")).get("api");
account = new Account(user, pass, api);
Context.setUsername(user);
return true;
} else if (result.get("error") != null) {
String errorResult = (String) result.get("error");
if (errorResult.equals("2fa") || errorResult.equals("2fae")) {
return login(user, pass, true);
}
Core.verbose(errorResult);
return false;
}
}
return false;
}
}
@@ -0,0 +1,14 @@
package org.parabot.core.forum;
/**
*
* Gives access to account details
*
* @author Everel
*
*/
public interface AccountManagerAccess {
public void setManager(AccountManager manager);
}
@@ -0,0 +1,24 @@
package org.parabot.core.io;
/**
*
* Keeps track of a progress
*
* @author Everel
*
*/
public interface ProgressListener {
/**
* Called when progress increased
* @param value
*/
public void onProgressUpdate(double value);
/**
* Updates upload speed
* @param mbPerSecond
*/
public void updateDownloadSpeed(double mbPerSecond);
}
@@ -0,0 +1,64 @@
package org.parabot.core.io;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author Everel
*
*/
public class SizeInputStream extends InputStream {
public int bytesRead;
private ProgressListener l;
private InputStream in;
private long startTime;
private double size;
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,61 @@
package org.parabot.core.lib;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
/**
*
* @author Everel
*
*/
public abstract class Library {
/**
* Determines if this library jar has already been downloaded.
* @return <b>false</b> if library jar has not been downloaded, otherwise <b>true</b>
*/
public boolean hasJar() {
return getJarFile().exists();
}
/**
* Adds the library to the buildpath and validates if it has been added
*/
public abstract void init();
/**
* Determines if library has been added to the buildpath
* @return <b>true</b> if library has been added to the buildpath, otherwise <b>false</b>.
*/
public abstract boolean isAdded();
/**
* Gets the local file target/location of the jar file
* @return local file (target) to library
*/
public abstract File getJarFile();
/**
* Gets download url to the library
* @return url
*/
public abstract URL getDownloadLink();
/**
* Fetches URL from {@link Library#getJarFile()}
* @return URL to local library jar file
*/
public URL getJarFileURL() {
try {
return getJarFile().toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public abstract String getLibraryName();
}
@@ -0,0 +1,71 @@
package org.parabot.core.lib.javafx;
import java.io.File;
import java.net.URL;
import org.parabot.core.Core;
import org.parabot.core.Directories;
import org.parabot.core.build.BuildPath;
import org.parabot.core.lib.Library;
/**
*
* Jython util class
*
* @author Everel
*
*/
public class JavaFX extends Library {
private static boolean valid;
@Override
public void init() {
if (!hasJar()) {
System.err.println("Failed to load javafx... [jar missing]");
return;
}
Core.verbose("Adding javafx jar file to build path: "
+ getJarFileURL().getPath());
BuildPath.add(getJarFileURL());
try {
Class.forName("javafx.application.Application");
valid = true;
} catch (ClassNotFoundException e) {
System.err
.println("Failed to add javafx to build path, or incorrupt download");
}
Core.verbose("JavaFX initialized.");
}
@Override
public boolean isAdded() {
return valid;
}
@Override
public File getJarFile() {
return new File(Directories.getCachePath(), "javafx.jar");
}
@Override
public URL getDownloadLink() {
try {
return new URL("http://bot.parabot.org/libs/jfxrt.jar");
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
@Override
public String getLibraryName() {
return "JavaFX";
}
public static boolean isValid() {
return valid;
}
}
@@ -0,0 +1,67 @@
package org.parabot.core.lib.naga;
import org.parabot.core.Core;
import org.parabot.core.Directories;
import org.parabot.core.build.BuildPath;
import org.parabot.core.lib.Library;
import java.io.File;
import java.net.URL;
/**
* @author JKetelaar
*/
public class Naga extends Library {
private static boolean valid;
@Override
public void init() {
if (!hasJar()) {
System.err.println("Failed to load javafx... [jar missing]");
return;
}
Core.verbose("Adding javafx jar file to build path: "
+ getJarFileURL().getPath());
BuildPath.add(getJarFileURL());
try {
Class.forName("javafx.application.Application");
valid = true;
} catch (ClassNotFoundException e) {
System.err
.println("Failed to add javafx to build path, or incorrupt download");
}
Core.verbose("JavaFX initialized.");
}
@Override
public boolean isAdded() {
return valid;
}
@Override
public File getJarFile() {
return new File(Directories.getCachePath(), "naga.jar");
}
@Override
public URL getDownloadLink() {
try {
return new URL("http://bdn.parabot.org/api/v2/data/dependencies/naga");
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
@Override
public String getLibraryName() {
return "Naga";
}
public static boolean isValid() {
return valid;
}
}
@@ -0,0 +1,77 @@
package org.parabot.core.network;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.NoSuchElementException;
public class NetworkInterface {
public static byte[] mac = new byte[] { 11, 11, 11, 11, 11, 11 };
private static byte[] realMac;
private static NetworkInterface cached;
static {
try {
mac = getRealHardwareAddress();
} catch (SocketException ignored) {
}
}
public byte[] getHardwareAddress() {
return mac;
}
public static Enumeration<NetworkInterface> getNetworkInterfaces()
throws SocketException {
final ArrayList<NetworkInterface> netifs = new ArrayList<>();
return new Enumeration<NetworkInterface>() {
private int i = 0;
public NetworkInterface nextElement() {
if (i < netifs.size()) {
NetworkInterface netif = netifs.get(i++);
return netif;
} else {
throw new NoSuchElementException();
}
}
public boolean hasMoreElements() {
return (i < netifs.size());
}
};
}
public static byte[] getRealHardwareAddress() throws SocketException{
if (realMac != null)
return realMac;
try {
return realMac = java.net.NetworkInterface.getByInetAddress(
InetAddress.getLocalHost()).getHardwareAddress();
} catch (Exception ignored) {
}
return mac;
}
public static NetworkInterface getByInetAddress(InetAddress addr) {
if (cached == null)
cached = new NetworkInterface();
return cached;
}
public static void setMac(byte[] mac2) {
System.out.println("Setting mac address to:" + formatMac(mac2));
mac = mac2;
}
public static String formatMac(byte[] mac){
StringBuffer b = new StringBuffer();
for(int i = 0; i < 6;i++){
b.append(String.format("%02X", mac[i]));
if(i < 5)
b.append(':');
}
return b.toString();
}
}
@@ -0,0 +1,66 @@
package org.parabot.core.network;
import java.io.IOException;
public class Runtime {
private java.lang.Runtime rt;
private static Runtime cached;
private Runtime(java.lang.Runtime rt){
this.rt = rt;
}
public void addShutdownHook(Thread t){
rt.addShutdownHook(t);
}
public int availableProcessors(){
return rt.availableProcessors();
}
public void exit(int i){
rt.exit(i);
}
public Process exec(String str) throws IOException{
System.out.println("RT:" + str);
System.out.println("RT:" + str);
return rt.exec(str);
}
public Process exec(String[] cmdarray) throws IOException{
StringBuffer sb = new StringBuffer();
for(int i = 0; i < cmdarray.length;i++){
sb.append(cmdarray[i] + (i < cmdarray.length - 1 ? "," : ""));
}
System.out.println("RT: {" + sb + "}");
System.out.println("RT: {" + sb + "}");
return rt.exec(cmdarray);
}
public long freeMemory() {
return rt.freeMemory();
}
public long totalMemory() {
return rt.totalMemory();
}
public void gc(){
rt.gc();
}
public long maxMemory(){
return rt.maxMemory();
}
public static Runtime getRuntime(){
if(cached == null)
cached = new Runtime(java.lang.Runtime.getRuntime());
return cached;
}
}
@@ -0,0 +1,294 @@
package org.parabot.core.network.proxy;
import org.parabot.core.ui.utils.UILog;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;
public class ProxySocket extends Socket {
private static List<ProxySocket> connections = new ArrayList<ProxySocket>();
private static ProxyType proxyType = ProxyType.NONE;
private static int proxyPort = 0;
private InetAddress addr;
private int port;
private static String username = null, password = null;
public static boolean auth = false;
private static InetAddress proxyInetAddress = null;
private InetSocketAddress cachedAddr;
public static int closeConnections() {
int value = 0;
for (ProxySocket socket : connections)
try {
connections.remove(socket);
if (socket.isClosed())
continue;
socket.close();
value++;
} catch (Exception e) {
}
return value;
}
public ProxySocket(InetAddress addr, int port) throws IOException {
super(addr, port);
}
public ProxySocket() {
super();
}
public ProxySocket(String host, int port) throws IOException {
super(host, port);
}
public static void setProxy(ProxyType type, String host, int port) {
try {
proxyInetAddress = InetAddress.getByName(host);
proxyPort = port;
proxyType = type;
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
public static InetAddress getProxyAddress() {
return proxyInetAddress;
}
public static int getProxyPort() {
return proxyPort;
}
public static ProxyType getProxyType() {
return proxyType;
}
@Override
public void connect(SocketAddress addr) throws IOException {
connections.add(this);
if (addr instanceof InetSocketAddress) {
InetSocketAddress isa = (InetSocketAddress) addr;
this.addr = InetAddress.getByName(isa.getHostString());
this.port = isa.getPort();
}
if (proxyType != ProxyType.NONE) {
try {
super.connect(cachedAddr = new InetSocketAddress(
proxyInetAddress, proxyPort));
initProxy();
} catch (Exception e) {
UILog.log("Proxy Error", e.getMessage(),
JOptionPane.ERROR_MESSAGE);
}
} else
super.connect(addr);
}
private void initProxy() throws IOException {
System.out.println("Proxying:" + addr + ":" + port + " Over:"
+ proxyInetAddress + ":" + proxyPort + " Type:" + proxyType);
switch (proxyType) {
case HTTP:
http_connect();
break;
case SOCKS4:
socks4_connect();
break;
case SOCKS5:
socks5_connect();
break;
default:
throw new IOException("Unsupported proxy type:" + proxyType);
}
}
private void http_connect() throws IOException {
InputStream in = getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
OutputStream out = getOutputStream();
out.write(("CONNECT " + addr.getHostAddress() + ":" + port + "\r\n")
.getBytes());
// out.write("Connection:keep-alive\r\n".getBytes());
out.write("\r\n".getBytes());
String str;
while ((str = br.readLine()) != null) {
if (str.length() == 0)
break;
if (!str.startsWith("HTTP"))
continue;
int code = Integer.parseInt(str.substring(9, 12));
switch (code) {
case 404:
throw new IOException(
"Proxy seems to think we're connecting to a webpage...");
case 403:
throw new IOException(
"Proxy doesn't support connecting to port: " + port
+ "! Try a different proxy.");
}
if (code / 100 != 2)
throw new IOException(
"Unable to connect to proxy server! HTTP Error code:"
+ code);
}
}
private void socks4_connect() throws IOException {
DataOutputStream out = new DataOutputStream(getOutputStream());
DataInputStream in = new DataInputStream(getInputStream());
out.write(0x04);
out.write(0x01); // connection type (TCP stream)
out.writeShort(port);
byte[] b = addr.getAddress();
if (b.length != 4)
throw new IOException("Unsupported IP type for socksv4!");
out.write(b);
out.write(0); // the userID stuff, 0 means end of string (null
// terminated)
out.flush();
if (in.read() != 0x00) // null byte
throw new IOException("Proxy server dun goofed");
if (in.read() != 0x5a)
throw new IOException(
"Proxy server was unable to connect to server!");
in.readShort(); // ignored
in.readFully(b); // ignored
}
private void socks5_connect() throws IOException {
DataOutputStream out = new DataOutputStream(getOutputStream());
DataInputStream in = new DataInputStream(getInputStream());
out.write(0x05); // the version
out.write(auth ? 2 : 1); // number of authentication methods (no auth
// for now)
out.write(0); // the authentication (none)
if (auth) {
out.write(2);
}
out.flush();
if (in.read() != 0x05) // remote proxy version
throw new IOException("Proxy server is not supported!");
switch (in.read()) { // auth method
case 0:
break; // no auth
case 2:
// username and pass stuff
out.write(0x01); // user/pass version #
out.write(username.length());
out.write(username.getBytes());
out.write(password.length());
out.write(password.getBytes());
out.flush();
in.read(); // skip the version
if (in.read() == 0) // Successful login, continue
break;
default:
throw new IOException("Proxy server declined request!");
}
// now to write the actual request
out.write(0x05); // again the socks version
out.write(0x01); // the connection type (0x01 = TCP Connection)
out.write(0x00); // the reserve byte, un-used
byte[] b = addr.getAddress();
out.write(b.length == 4 ? 0x01 : 0x04); // if ipv4 or ipv6 (0x03 =
// domain name, but that's
// unsupported as of yet)
out.write(b);
out.writeShort(port);
out.flush();
// now to read the server's reply
if (in.read() != 0x05) // socks version (again)
throw new IOException("Proxy server dun goofed");
int reply = in.read();
if (reply == 0x08)
throw new IOException("Bad address sent to proxy server");
if (reply != 0x00)
throw new IOException("Unable to connect to server!");
in.read(); // reserve byte
int addrType = in.read();
b = new byte[4];
switch (addrType) {
case 0x01:
b = new byte[4];
break;
case 0x04:
b = new byte[16];
break;
default:
throw new IOException("Bad address type from proxy server!");
}
in.readFully(b);
in.readShort(); // the returned port #, ignored
}
@Override
public int getPort() {
if (super.getInetAddress().equals(proxyInetAddress))
return port;
return super.getPort();
}
@Override
public InetAddress getInetAddress() {
if (super.getInetAddress().equals(proxyInetAddress))
return addr;
return super.getInetAddress();
}
@Override
public SocketAddress getRemoteSocketAddress() {
if (super.getInetAddress().equals(proxyInetAddress))
return cachedAddr;
return super.getRemoteSocketAddress();
}
@Override
public SocketChannel getChannel() {
if (super.getInetAddress().equals(proxyInetAddress))
return null;
return super.getChannel();
}
@Override
public void close() throws IOException {
connections.remove(this);
super.close();
}
public static void setType(ProxyType pt) {
proxyType = pt;
}
public static int getConnectionCount() {
return connections.size();
}
public static void setLogin(String user, char[] pass) {
setLogin(user, new String(pass));
}
public static void setLogin(String user, String pass) {
username = user;
password = pass;
}
}
@@ -0,0 +1,5 @@
package org.parabot.core.network.proxy;
public enum ProxyType {
NONE,SOCKS5, SOCKS4, HTTP
}
@@ -0,0 +1,25 @@
package org.parabot.core.paint;
import org.parabot.environment.api.interfaces.Paintable;
/**
*
* Abstract class for debugging in game values & more
*
* @author Everel
*
*/
public abstract class AbstractDebugger implements Paintable {
/**
* Toggles this debugger
*/
public abstract void toggle();
/**
*
* @return <b>true</b> if this debugger is enabled, otherwise <b>false</b>
*/
public abstract boolean isEnabled();
}
@@ -0,0 +1,61 @@
package org.parabot.core.paint;
import java.awt.Color;
import java.awt.Graphics;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import org.parabot.core.Context;
/**
*
* Manages and paints on a collection of AbstractDebuggers
*
* @author Everel
*
*/
public class PaintDebugger {
private final HashMap<String, AbstractDebugger> debuggers;
private final Queue<String> stringDebug;
public PaintDebugger() {
this.debuggers = new HashMap<String, AbstractDebugger>();
this.stringDebug = new LinkedList<String>();
}
public final void addDebugger(final String name, final AbstractDebugger debugger) {
debuggers.put(name, debugger);
}
public void debug(Graphics g) {
for(final AbstractDebugger d : debuggers.values()) {
if(d.isEnabled()) {
d.paint(g);
}
}
g.setColor(Color.green);
int y = 40;
while(stringDebug.size() > 0) {
g.drawString(stringDebug.poll(), 10, y);
y += 15;
}
}
public static final PaintDebugger getInstance() {
return Context.getInstance().getPaintDebugger();
}
public final void addLine(final String debugLine) {
stringDebug.add(debugLine);
}
public final void toggle(final String name) {
debuggers.get(name).toggle();
}
public final boolean isEnabled(final String name) {
return debuggers.get(name).isEnabled();
}
}
@@ -0,0 +1,66 @@
package org.parabot.core.parsers.hooks;
import org.parabot.core.asm.hooks.HookFile;
import org.parabot.core.asm.interfaces.Injectable;
import org.parabot.core.asm.wrappers.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
/**
* Parses an XML files which injects the hooks and other bytecode manipulation
* methods
*
* @author Everel
*/
public abstract class HookParser {
public HookParser(HookFile hookFile) {
}
public abstract Interface[] getInterfaces();
public abstract Super[] getSupers();
public abstract Getter[] getGetters();
public abstract Setter[] getSetters();
public abstract Invoker[] getInvokers();
public abstract Callback[] getCallbacks();
public abstract HashMap<String, String> getConstants();
public Injectable[] getInjectables() {
ArrayList<Injectable> injectables = new ArrayList<Injectable>();
Interface[] interfaces = getInterfaces();
if (interfaces != null) {
Collections.addAll(injectables, interfaces);
}
Getter[] getters = getGetters();
if (getters != null) {
Collections.addAll(injectables, getters);
}
Setter[] setters = getSetters();
if (setters != null) {
Collections.addAll(injectables, setters);
}
Super[] supers = getSupers();
if (supers != null) {
Collections.addAll(injectables, supers);
}
Invoker[] invokers = getInvokers();
if (invokers != null) {
Collections.addAll(injectables, invokers);
}
Callback[] callbacks = getCallbacks();
if (callbacks != null) {
Collections.addAll(injectables, callbacks);
}
return injectables.toArray(new Injectable[injectables.size()]);
}
}
@@ -0,0 +1,248 @@
package org.parabot.core.parsers.hooks;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.parabot.core.asm.adapters.AddInterfaceAdapter;
import org.parabot.core.asm.hooks.HookFile;
import org.parabot.core.asm.wrappers.Callback;
import org.parabot.core.asm.wrappers.Getter;
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.Super;
/**
*
* @author Dane
*
*/
public class JSONHookParser extends HookParser {
private JSONObject root;
private Map<String, String> interfaces;
private HashMap<String, String> constants;
public JSONHookParser(HookFile file) {
super(file);
JSONParser parser = new JSONParser();
try {
parser.parse(new InputStreamReader(file.getInputStream()));
} catch (Throwable t) {
throw new RuntimeException("Unable to parse hooks: " + t);
}
}
public String get(JSONObject o, String s) {
return this.get(o, s);
}
public String formatDescription(String s) {
StringBuilder b = new StringBuilder();
if (s.charAt(0) == '[') {
for (int j = 0; j < s.length(); j++) {
if (s.charAt(j) == '[') {
b.append('[');
}
}
s = s.replaceAll("\\[", "");
}
return b.append('L').append(String.format(s, AddInterfaceAdapter.getAccessorPackage())).append(';').toString();
}
@Override
public Interface[] getInterfaces() {
JSONArray a = (JSONArray) root.get("interfaces");
interfaces = new HashMap<>();
if (a != null && a.size() > 0) {
Interface[] i = new Interface[a.size()];
for (int j = 0; j < a.size(); j++) {
JSONObject o = (JSONObject) a.get(j);
String clazz = this.get(o, "class");
String interfaze = this.get(o, "interface");
interfaces.put(clazz, interfaze);
i[j] = new Interface(clazz, interfaze);
}
return i;
}
return null;
}
@Override
public Super[] getSupers() {
JSONArray a = (JSONArray) root.get("supers");
if (a != null && a.size() > 0) {
Super[] s = new Super[a.size()];
for (int i = 0; i < a.size(); i++) {
JSONObject o = (JSONObject) a.get(i);
s[i] = new Super(this.get(o, "class"), this.get(o, "super"));
}
return s;
}
return null;
}
@Override
public Getter[] getGetters() {
JSONArray a = (JSONArray) root.get("getters");
if (a != null && a.size() > 0) {
Getter[] g = new Getter[a.size()];
for (int i = 0; i < a.size(); i++) {
JSONObject o = (JSONObject) a.get(i);
if (o.containsKey("class") && o.containsKey("accessor")) {
throw new RuntimeException("Cannot have class AND accessor tags together!");
}
if (o.containsKey("accessor") && this.interfaces == null) {
throw new RuntimeException("Cannot use accessor tag before parsing interfaces!");
}
String desc = this.get(o, "desc");
if (desc != null && desc.contains("%s")) {
desc = formatDescription(desc);
}
String clazz = o.containsKey("class") ? this.get(o, "class") : interfaces.get(this.get(o, "accessor"));
String into = o.containsKey("into") ? this.get(o, "into") : clazz;
g[i] = new Getter(into, clazz, this.get(o, "field"), this.get(o, "method"), desc, o.containsKey("static") ? (boolean) o.get("static") : false, 0, null);
}
return g;
}
return null;
}
@Override
public Setter[] getSetters() {
JSONArray a = (JSONArray) root.get("setters");
if (a != null && a.size() > 0) {
Setter[] s = new Setter[a.size()];
for (int i = 0; i < a.size(); i++) {
JSONObject o = (JSONObject) a.get(i);
if (o.containsKey("class") && o.containsKey("accessor")) {
throw new RuntimeException("Cannot have class AND accessor tags together!");
}
if (o.containsKey("accessor") && this.interfaces == null) {
throw new RuntimeException("Cannot use accessor tag before parsing interfaces!");
}
String desc = this.get(o, "desc");
if (desc != null && desc.contains("%s")) {
desc = formatDescription(desc);
}
String clazz = o.containsKey("class") ? this.get(o, "class") : interfaces.get(this.get(o, "accessor"));
String into = o.containsKey("into") ? this.get(o, "into") : clazz;
s[i] = new Setter(into, clazz, this.get(o, "field"), this.get(o, "method"), desc, o.containsKey("static") ? (boolean) o.get("static") : false, null);
}
return s;
}
return null;
}
@Override
public Invoker[] getInvokers() {
JSONArray a = (JSONArray) root.get("invokers");
if (a != null && a.size() > 0) {
Invoker[] i = new Invoker[a.size()];
for (int j = 0; j < a.size(); j++) {
JSONObject o = (JSONObject) a.get(j);
if (o.containsKey("class") && o.containsKey("accessor")) {
throw new RuntimeException("Cannot have class AND accessor tags together!");
}
if (o.containsKey("accessor") && this.interfaces == null) {
throw new RuntimeException("Cannot use accessor tag before parsing interfaces!");
}
String desc = this.get(o, "desc");
if (desc != null && desc.contains("%s")) {
desc = formatDescription(desc);
}
String clazz = o.containsKey("class") ? this.get(o, "class") : interfaces.get(this.get(o, "accessor"));
String into = o.containsKey("into") ? this.get(o, "into") : clazz;
i[j] = new Invoker(into, clazz, this.get(o, "invokemethod"), this.get(o, "argdesc"), this.get(o, "desc"), this.get(o, "method"), false, null, null);
}
return i;
}
return null;
}
@Override
public Callback[] getCallbacks() {
JSONArray a = (JSONArray) root.get("callbacks");
if (a != null && a.size() > 0) {
Callback[] c = new Callback[a.size()];
for (int j = 0; j < a.size(); j++) {
JSONObject o = (JSONObject) a.get(j);
if (o.containsKey("class") && o.containsKey("accessor")) {
throw new RuntimeException("Cannot have class AND accessor tags together!");
}
if (o.containsKey("accessor") && this.interfaces == null) {
throw new RuntimeException("Cannot use accessor tag before parsing interfaces!");
}
String desc = this.get(o, "desc");
if (desc != null && desc.contains("%s")) {
desc = formatDescription(desc);
}
String clazz = o.containsKey("class") ? this.get(o, "class") : interfaces.get(this.get(o, "accessor"));
c[j] = new Callback(clazz, this.get(o, "method"), this.get(o, "callclass"), this.get(o, "callmethod"), this.get(o, "calldesc"), this.get(o, "callargs"), this.get(o, "desc"), false);
}
return c;
}
return null;
}
@Override
public HashMap<String, String> getConstants() {
if (this.constants == null) {
this.constants = new HashMap<>();
}
if (!this.constants.isEmpty()) {
return this.constants;
}
JSONArray a = (JSONArray) root.get("constants");
if (a != null && a.size() > 0) {
for (int j = 0; j < a.size(); j++) {
JSONObject o = (JSONObject) a.get(j);
this.constants.put(this.get(o, "name"), (String) o.get("value"));
}
}
return this.constants;
}
}
@@ -0,0 +1,457 @@
package org.parabot.core.parsers.hooks;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.parabot.core.Core;
import org.parabot.core.asm.adapters.AddInterfaceAdapter;
import org.parabot.core.asm.hooks.HookFile;
import org.parabot.core.asm.wrappers.Callback;
import org.parabot.core.asm.wrappers.Getter;
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.Super;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XMLHookParser extends HookParser {
private Document doc;
private HashMap<String, String> interfaceMap;
private HashMap<String, String> constants;
private boolean parsedInterfaces;
public XMLHookParser(HookFile hookFile) {
super(hookFile);
interfaceMap = new HashMap<String, String>();
constants = new HashMap<String, String>();
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(hookFile.getInputStream());
doc.getDocumentElement().normalize();
if (!doc.getDocumentElement().getNodeName().equals("injector")) {
throw new RuntimeException("Incorrect hook file.");
}
} catch (Throwable t) {
throw new RuntimeException("Unable to parse hooks " + t);
}
}
@Override
public Interface[] getInterfaces() {
parsedInterfaces = true;
final NodeList interfaceRootList = doc
.getElementsByTagName("interfaces");
switch (interfaceRootList.getLength()) {
case 0:
return null;
case 1:
break;
default:
throw new RuntimeException(
"Hook file may not contains multiple <interfaces> tags ");
}
final Node node = interfaceRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) {
return null;
}
final Element interfaceRoot = (Element) node;
final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
if (interfaces.getLength() == 0) {
return null;
}
final ArrayList<Interface> interfaceList = new ArrayList<Interface>();
for (int x = 0; x < interfaces.getLength(); x++) {
final Node n = interfaces.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
final Element addInterface = (Element) n;
final String className = getValue("classname", addInterface);
final String interfaceClass = getValue("interface", addInterface);
interfaceMap.put(interfaceClass, className);
final Interface inf = new Interface(className, interfaceClass);
interfaceList.add(inf);
}
return interfaceList.toArray(new Interface[interfaceList.size()]);
}
@Override
public Super[] getSupers() {
final NodeList interfaceRootList = doc.getElementsByTagName("supers");
switch (interfaceRootList.getLength()) {
case 0:
return null;
case 1:
break;
default:
throw new RuntimeException(
"Hook file may not contains multiple <supers> tags ");
}
final Node node = interfaceRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) {
return null;
}
final Element superRoot = (Element) node;
final NodeList supers = superRoot.getElementsByTagName("add");
if (supers.getLength() == 0) {
return null;
}
final ArrayList<Super> superList = new ArrayList<Super>();
for (int x = 0; x < supers.getLength(); x++) {
final Node n = supers.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
final Element addSuper = (Element) n;
final String className = getValue("classname", addSuper);
final String superClass = getValue("super", addSuper);
final Super sup = new Super(className, superClass);
superList.add(sup);
}
return superList.toArray(new Super[superList.size()]);
}
@Override
public Getter[] getGetters() {
final NodeList getterRootList = doc.getElementsByTagName("getters");
switch (getterRootList.getLength()) {
case 0:
return null;
case 1:
break;
default:
throw new RuntimeException(
"Hook file may not contains multiple <getters> tags ");
}
final Node node = getterRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) {
return null;
}
final Element getterRoot = (Element) node;
final NodeList getters = getterRoot.getElementsByTagName("add");
if (getters.getLength() == 0) {
return null;
}
final ArrayList<Getter> getterList = new ArrayList<Getter>();
for (int x = 0; x < getters.getLength(); x++) {
final Node n = getters.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
final Element addGetter = (Element) n;
if (isSet("classname", addGetter) && isSet("accessor", addGetter)) {
throw new RuntimeException(
"Can't set classname and accessor tag together.");
}
if (isSet("accessor", addGetter) && !parsedInterfaces) {
throw new RuntimeException(
"You'll need to parse interfaces first.");
}
final String className = isSet("classname", addGetter) ? getValue(
"classname", addGetter) : interfaceMap.get(getValue(
"accessor", addGetter));
final String into = isSet("into", addGetter) ? getValue("into",
addGetter) : className;
final long multiplier = isSet("multiplier", addGetter) ? Long.parseLong(getValue("multiplier", addGetter)) : 0L;
final String fieldName = getValue("field", addGetter);
final String fieldDesc = isSet("descfield", addGetter) ? getValue("descfield", addGetter) : null;
final String methodName = getValue("methodname", addGetter);
boolean staticMethod = isSet("methstatic", addGetter) ? (getValue(
"methstatic", addGetter).equals("true")) : false;
String returnDesc = isSet("desc", addGetter) ? getValue("desc",
addGetter) : null;
String array = "";
if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder();
if (returnDesc.startsWith("[")) {
for (int i = 0; i < returnDesc.length(); i++) {
if (returnDesc.charAt(i) == '[') {
array += '[';
}
}
returnDesc = returnDesc.replaceAll("\\[", "");
}
str.append(array)
.append('L')
.append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage()))
.append(";");
returnDesc = str.toString();
}
final Getter get = new Getter(into, className, fieldName,
methodName, returnDesc, staticMethod, multiplier, fieldDesc);
getterList.add(get);
}
Core.verbose("Fields hooked: " + getterList.size());
return getterList.toArray(new Getter[getterList.size()]);
}
@Override
public Setter[] getSetters() {
final NodeList setterRootList = doc.getElementsByTagName("setters");
switch (setterRootList.getLength()) {
case 0:
return null;
case 1:
break;
default:
throw new RuntimeException(
"Hook file may not contains multiple <setters> tags ");
}
final Node node = setterRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) {
return null;
}
final Element setterRoot = (Element) node;
final NodeList setters = setterRoot.getElementsByTagName("add");
if (setters.getLength() == 0) {
return null;
}
final ArrayList<Setter> setterList = new ArrayList<Setter>();
for (int x = 0; x < setters.getLength(); x++) {
final Node n = setters.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
final Element addSetter = (Element) n;
if (isSet("classname", addSetter) && isSet("accessor", addSetter)) {
throw new RuntimeException(
"Can't set classname and accessor tag together.");
}
if (isSet("accessor", addSetter) && !parsedInterfaces) {
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 into = isSet("into", addSetter) ? getValue("into",
addSetter) : className;
final String fieldName = getValue("field", addSetter);
final String fieldDesc = isSet("descfield", addSetter) ? getValue("descfield", addSetter) : null;
final String methodName = getValue("methodname", addSetter);
boolean staticMethod = isSet("methstatic", addSetter) ? (getValue(
"methstatic", addSetter).equals("true")) : false;
String returnDesc = isSet("desc", addSetter) ? getValue("desc",
addSetter) : null;
String array = "";
if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder();
if (returnDesc.startsWith("[")) {
for (int i = 0; i < returnDesc.length(); i++) {
if (returnDesc.charAt(i) == '[') {
array += '[';
}
}
returnDesc = returnDesc.replaceAll("\\[", "");
}
str.append(array)
.append('L')
.append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage()))
.append(";");
returnDesc = str.toString();
}
final Setter get = new Setter(className, into, fieldName,
methodName, returnDesc, staticMethod, fieldDesc);
setterList.add(get);
}
return setterList.toArray(new Setter[setterList.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) {
return element.getElementsByTagName(tag).getLength() > 0;
}
private static final String getValue(String tag, Element element) {
NodeList nodes = element.getElementsByTagName(tag).item(0)
.getChildNodes();
Node node = (Node) nodes.item(0);
return node.getNodeValue();
}
@Override
public 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 boolean isInterface = isSet("interface", addInvoker) ? Boolean.parseBoolean(getValue("interface", addInvoker)) : false;
final String instanceCast = isSet("instancecast", addInvoker) ? getValue("instancecast", addInvoker) : null;
final String checkCastArgsDesc = isSet("castargs", addInvoker) ? getValue("castargs", addInvoker) : null;
final Invoker invoker = new Invoker(into, className, invMethodName,
argsDesc, returnDesc, methodName, isInterface, instanceCast, checkCastArgsDesc);
invokerList.add(invoker);
}
return invokerList.toArray(new Invoker[invokerList.size()]);
}
@Override
public HashMap<String, String> getConstants() {
if (!constants.isEmpty()) {
return constants;
}
final NodeList constantsRootList = doc
.getElementsByTagName("constants");
switch (constantsRootList.getLength()) {
case 0:
return null;
case 1:
break;
default:
throw new RuntimeException(
"Hook file may not contains multiple <constants> tags ");
}
final Node node = constantsRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) {
return null;
}
final Element constantRoot = (Element) node;
final NodeList constantsList = constantRoot.getElementsByTagName("add");
if (constantsList.getLength() == 0) {
// return empty hashmap
return constants;
}
for (int x = 0; x < constantsList.getLength(); x++) {
final Node n = constantsList.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
final Element addConstant = (Element) n;
final String key = getValue("key", addConstant);
final String value = getValue("value", addConstant);
constants.put(key, value);
}
return constants;
}
@Override
public 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 boolean conditional = isSet("conditional", addCallback);
final Callback callback = new Callback(className, methodName, desc,
callClass, callMethod, callDesc, callArgs, conditional);
callbackList.add(callback);
}
return callbackList.toArray(new Callback[callbackList.size()]);
}
}
@@ -0,0 +1,69 @@
package org.parabot.core.parsers.randoms;
import org.parabot.core.Configuration;
import org.parabot.core.Context;
import org.parabot.core.Core;
import org.parabot.core.Directories;
import org.parabot.core.io.ProgressListener;
import org.parabot.environment.api.utils.WebUtil;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* @author JKetelaar
*/
public class PublicRandoms extends RandomParser {
@Override
public void parse() {
File myJar = new File(Directories.getCachePath() + "/randoms.jar");
if (!myJar.exists() || !myJar.canRead()) {
download();
}
try {
URL url = myJar.toURI().toURL();
URL[] urls = new URL[]{url};
String server = Context.getInstance().getServerProviderInfo().getServerName();
URLClassLoader child = new URLClassLoader(urls, this.getClass().getClassLoader());
Class<?> classToLoad = Class.forName("org.parabot.randoms.Core", true, child);
Method method = classToLoad.getDeclaredMethod("init", String.class);
Object instance = classToLoad.newInstance();
System.out.println(server);
method.invoke(instance, server);
Core.verbose("Successfully parsed public random!");
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | ClassNotFoundException | MalformedURLException e) {
e.printStackTrace();
Core.verbose("Failed to parse random...");
}
}
private void download() {
try {
File random = new File(Directories.getCachePath() + "/randoms.jar");
if (random.exists()) {
Core.verbose("Public random dependency already exists, no need to download it...");
return;
}
String downloadLink = Configuration.GET_RANDOMS;
WebUtil.downloadFile(new URL(downloadLink), random, new ProgressListener() {
@Override
public void onProgressUpdate(double v) {
}
@Override
public void updateDownloadSpeed(double v) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,21 @@
package org.parabot.core.parsers.randoms;
import java.util.ArrayList;
/**
* @author JKetelaar
*/
public abstract class RandomParser {
private static final ArrayList<RandomParser> parsers = new ArrayList<>();
public static void enable() {
parsers.add(new PublicRandoms());
for (RandomParser randomParser : parsers) {
randomParser.parse();
}
}
public abstract void parse();
}
@@ -0,0 +1,70 @@
package org.parabot.core.parsers.scripts;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.parabot.core.Configuration;
import org.parabot.core.Context;
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.executers.BDNScriptsExecuter;
import java.io.BufferedReader;
import java.net.URL;
/**
* Parses scripts stored on the BDN of Parabot
*
* @author Paradox, Everel
*/
public class BDNScripts extends ScriptParser {
private static AccountManager manager;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override
public final void setManager(AccountManager manager) {
BDNScripts.manager = manager;
}
};
@Override
public void execute() {
if (!manager.isLoggedIn()) {
System.err.println("Not logged in...");
return;
}
JSONParser parser = new JSONParser();
try {
BufferedReader br = WebUtil.getReader(new URL(
Configuration.GET_SCRIPTS + Context.getInstance().getServerProviderInfo().getServerName()),
manager.getAccount().getURLUsername(), manager.getAccount().getURLPassword());
String line;
while ((line = br.readLine()) != null) {
JSONObject jsonObject = (JSONObject) parser.parse(line);
int bdnId = Integer.parseInt(String.valueOf(jsonObject.get("id")));
String scriptName = String.valueOf(jsonObject.get("name"));
String author = String.valueOf(jsonObject.get("author"));
double version = Double.parseDouble(String.valueOf(jsonObject.get("version")));
String category = String.valueOf(jsonObject.get("category"));
String description = String.valueOf(jsonObject.get("description"));
final ScriptDescription desc = new ScriptDescription(scriptName,
author, category, version, description,
null, bdnId);
SCRIPT_CACHE.put(desc, new BDNScriptsExecuter(bdnId));
}
br.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
@@ -0,0 +1,66 @@
package org.parabot.core.parsers.scripts;
import org.parabot.core.Directories;
import org.parabot.core.classpath.ClassPath;
import org.parabot.core.desc.ScriptDescription;
import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.executers.LocalScriptExecuter;
import org.parabot.environment.scripts.loader.JavaScriptLoader;
import java.lang.reflect.Constructor;
/**
* Parses locally stored java scripts
*
* @author Everel
*/
public class LocalJavaScripts extends ScriptParser {
@Override
public void execute() {
// parse classes in server directories
final ClassPath path = new ClassPath();
path.addClasses(Directories.getScriptCompiledPath());
// init the script loader
final JavaScriptLoader loader = new JavaScriptLoader(path);
// loop through all classes which extends the 'Script' class
for (final String className : loader.getScriptClassNames()) {
try {
// get class
final Class<?> scriptClass;
try {
scriptClass = loader.loadClass(className);
} catch (NoClassDefFoundError ignored) {
// script for an other server provider
continue;
}
// get annotation
final Object annotation = scriptClass
.getAnnotation(ScriptManifest.class);
if (annotation == null) {
throw new RuntimeException("Missing manifest at "
+ className);
}
// cast object annotation to script manifest annotation
final ScriptManifest manifest = (ScriptManifest) annotation;
// get constructor
final Constructor<?> con = scriptClass.getConstructor();
final ScriptDescription desc = new ScriptDescription(
manifest.name(), manifest.author(), manifest.category()
.toString(), manifest.version(),
manifest.description(), manifest.servers(),
manifest.vip() ? "yes" : "no",
manifest.premium() ? "yes" : "no");
SCRIPT_CACHE.put(desc, new LocalScriptExecuter(con));
} catch (ClassNotFoundException ignored) {
} catch (NoClassDefFoundError ignored) {
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
@@ -0,0 +1,52 @@
package org.parabot.core.parsers.scripts;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import org.parabot.core.Core;
import org.parabot.core.desc.ScriptDescription;
import org.parabot.environment.scripts.executers.ScriptExecuter;
/**
* Abstract class for parsing scripts
*
* @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.inLoadLocal()) {
parsers.add(new LocalJavaScripts());
parsers.add(new BDNScripts());
} else if (Core.inDebugMode()) {
parsers.add(new LocalJavaScripts());
} else {
parsers.add(new BDNScripts());
}
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.");
}
Map<ScriptDescription, ScriptExecuter> SORTED_SCRIPT_CACHE = new TreeMap<ScriptDescription, ScriptExecuter>( SCRIPT_CACHE );
return SORTED_SCRIPT_CACHE.keySet().toArray(new ScriptDescription[SORTED_SCRIPT_CACHE.size()]);
}
}
@@ -0,0 +1,69 @@
package org.parabot.core.parsers.servers;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import org.parabot.core.Directories;
import org.parabot.core.classpath.ClassPath;
import org.parabot.core.desc.ServerDescription;
import org.parabot.environment.servers.ServerManifest;
import org.parabot.environment.servers.executers.LocalServerExecuter;
import org.parabot.environment.servers.loader.ServerLoader;
/**
* Parses local server providers located in the servers directory
*
* @author Everel
*/
public class LocalServers extends ServerParser {
@Override
public void execute() {
// parse classes in server directories
final ClassPath basePath = new ClassPath();
basePath.parseJarFiles(false);
basePath.addClasses(Directories.getServerPath());
final ArrayList<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();
SERVER_CACHE.put(
new ServerDescription(manifest.name(), manifest
.author(), manifest.version()),
new LocalServerExecuter(con, path,
manifest.name()));
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
}
@@ -0,0 +1,62 @@
package org.parabot.core.parsers.servers;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.parabot.core.Configuration;
import org.parabot.core.desc.ServerDescription;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.forum.AccountManagerAccess;
import org.parabot.core.ui.utils.UILog;
import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.servers.executers.PublicServerExecuter;
import javax.swing.*;
import java.io.BufferedReader;
import java.net.URL;
/**
* Parses servers hosted on Parabot
*
* @author Paradox, Everel
*/
public class PublicServers extends ServerParser {
private static AccountManager manager;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override
public final void setManager(AccountManager manager) {
PublicServers.manager = manager;
}
};
@Override
public void execute() {
try {
BufferedReader br = WebUtil.getReader(new URL(
Configuration.GET_SERVER_PROVIDERS), manager.getAccount().getURLUsername(), manager.getAccount().getURLPassword());
String line;
JSONParser parser = new JSONParser();
while ((line = br.readLine()) != null) {
JSONObject jsonObject = (JSONObject) parser.parse(line);
String name = String.valueOf(jsonObject.get("name"));
String author = String.valueOf(jsonObject.get("author"));
double version = Double.parseDouble(String.valueOf(jsonObject.get("version")));
ServerDescription desc = new ServerDescription(name,
author, version);
SERVER_CACHE.put(desc, new PublicServerExecuter(name));
}
br.close();
} catch (Exception e) {
UILog.log("Error", "Failed to load public servers. Either disable your anti-virus or request support on the forums.", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
}
@@ -0,0 +1,51 @@
package org.parabot.core.parsers.servers;
import org.parabot.core.Core;
import org.parabot.core.desc.ServerDescription;
import org.parabot.environment.servers.executers.ServerExecuter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* Abstract class for parsing server providers
*
* @author Everel
*/
public abstract class ServerParser {
public static final Map<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<>();
if (Core.inLoadLocal()) {
parsers.add(new LocalServers());
parsers.add(new PublicServers());
} else if (Core.inDebugMode()) {
parsers.add(new LocalServers());
} else {
parsers.add(new PublicServers());
}
Core.verbose("Parsing server providers...");
for (final ServerParser parser : parsers) {
parser.execute();
}
if (Core.inVerboseMode()) {
for (final ServerDescription desc : SERVER_CACHE.keySet()) {
Core.verbose(desc.toString());
}
Core.verbose("Server providers parsed.");
}
Map<ServerDescription, ServerExecuter> SORTED_SERVER_CACHE = new TreeMap<ServerDescription, ServerExecuter>( SERVER_CACHE );
return SORTED_SERVER_CACHE.keySet().toArray(new ServerDescription[SORTED_SERVER_CACHE.size()]);
}
}
@@ -0,0 +1,329 @@
package org.parabot.core.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
/**
*
* A <code>RefClass</code> represents a class or an instance of that class, if
* no instance is provided this class can only get values from static fields and
* only invoke static methods
*
* @author Everel
*
*/
public class RefClass extends RefModifiers {
private Object instance;
private Class<?> clazz;
public RefClass(Class<?> clazz) {
this(clazz, null);
}
public RefClass(Object instance) {
this(instance.getClass(), instance);
}
public RefClass(Class<?> clazz, Object instance) {
super(clazz.getModifiers());
this.clazz = clazz;
setInstance(instance);
}
/**
* Sets the instance of this class so now non static fields values can be
* retrieved and non static methods can be invoked
*
* @param instance
* instance of this class.
*/
public void setInstance(Object instance) {
if (instance == null) {
this.instance = null;
return;
}
if (this.clazz != null) {
if (!clazz.isInstance(instance)) {
throw new IllegalArgumentException(instance
+ " is not an instance of the class " + clazz);
}
}
this.instance = instance;
}
/**
* Gets the instance of this class
*
* @return if an instance of this class is known it will return that
* instance, otherwise it will return null.
*/
public Object getInstance() {
return this.instance;
}
/**
* Gets the class which this RefClass is representing
*
* @return class which this RefClass is representing
*/
public Class<?> getRepresentingClass() {
return this.clazz;
}
public String getClassName() {
return this.clazz.getName();
}
public String getSimpleName() {
return this.clazz.getSimpleName();
}
public String getCanonicalName() {
return this.clazz.getCanonicalName();
}
/**
* Gets the type of this class
*
* @return type of this class
*/
public org.objectweb.asm.Type getASMType() {
return org.objectweb.asm.Type.getType(this.clazz);
}
/**
* Gets the class' fields
*
* @return all fields if an instance is provided, otherwise only static
* fields
*/
public RefField[] getFields() {
ArrayList<RefField> fields = new ArrayList<RefField>();
// add all static fields
for (Field f : clazz.getDeclaredFields()) {
if (Modifier.isStatic(f.getModifiers())) {
fields.add(new RefField(f, instance));
}
}
if (this.instance != null) {
// add all non static fields
for (Field f : clazz.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers())) {
fields.add(new RefField(f, instance));
}
}
}
return fields.toArray(new RefField[fields.size()]);
}
/**
* Determines if a object is an instance of this class
* @param object the object you want to check
* @return <code>true</code> if the object is an instance of this class; <code>false</code> otherwise
*/
public boolean instanceOf(Object object) {
return this.clazz.isInstance(object);
}
/**
* Gets field by field name
*
* @param name
* name of the field
* @return the field if found
*/
public RefField getField(String name) {
return getField(name, null);
}
/**
* Gets field by field name and desc
*
* @param name
* name of the field
* @param desc
* desc type of the field
* @return the field if found
*/
public RefField getField(String name, String desc) {
RefField[] fields = getFields();
for (RefField f : fields) {
if (f.getName().equals(name)) {
if (desc == null) {
return f;
}
if (desc.equals(f.getTypeDesc())) {
return f;
}
}
}
return null;
}
/**
* Determines if this class has a super class
*
* @return <code>true</code> if this class has a super class and which is
* not the java/lang/Object class, otherwise <code>false.</code>
*/
public boolean hasSuperclass() {
return hasSuperclass(true);
}
/**
* Determines if this class has a super class
*
* @param ignoreObjectClass
* if you want this method to return false when the superclass is
* the java/lang/Object class
* @return <code>true</code> if this class has a superclass, otherwise
* <code>false</code>
*/
public boolean hasSuperclass(boolean ignoreObjectClass) {
if (!ignoreObjectClass) {
return !clazz.equals(Object.class);
}
Class<?> superClass = clazz.getSuperclass();
if(superClass == null) {
return false;
}
return !superClass.equals(Object.class);
}
/**
* Returns a new RefClass representing the superclass of this RefClass
*
* @return superclass of this RefClass
*/
public RefClass getSuperclass() {
return new RefClass(clazz.getSuperclass(), instance);
}
/**
* Creates a new instance of this class
*
* @return a RefClass representing a fresh created instance of that class
*/
public RefClass newInstance() {
try {
return new RefClass(clazz.newInstance());
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Gets the empty (without parameters) constructor of this class if any
*
* @return empty constructor if there, otherwise <code>null</code>
*/
public RefConstructor getConstructor() {
return getConstructor(new Class<?>[] {});
}
/**
* Gets a RefConstructor from this class
*
* @param parameters
* the constructor it's parameters
* @return the retrieved constructor
*/
public RefConstructor getConstructor(Class<?>[] parameters) {
try {
return new RefConstructor(clazz.getDeclaredConstructor(parameters));
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Gets all constructors of this class
*
* @return an array with all the constructors in this class
*/
public RefConstructor[] getConstructors() {
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
RefConstructor[] refConstructors = new RefConstructor[constructors.length];
for (int i = 0; i < constructors.length; i++) {
refConstructors[i] = new RefConstructor(constructors[i]);
}
return refConstructors;
}
/**
* Gets the class' methods
*
* @return all methods if an instance is provided, otherwise only static
* methods
*/
public RefMethod[] getMethods() {
ArrayList<RefMethod> methods = new ArrayList<RefMethod>();
// add all static methods
for (Method m : clazz.getDeclaredMethods()) {
if (Modifier.isStatic(m.getModifiers())) {
methods.add(new RefMethod(m, instance));
}
}
if (this.instance != null) {
// add all non static methods
for (Method m : clazz.getDeclaredMethods()) {
if (!Modifier.isStatic(m.getModifiers())) {
methods.add(new RefMethod(m, instance));
}
}
}
return methods.toArray(new RefMethod[methods.size()]);
}
/**
* Finds and returns the first RefMethod match with given method name
*
* @param name
* method its name
* @return the first match, or if not found <code>null</code>
*/
public RefMethod getMethod(String name) {
return getMethod(name, null);
}
/**
* Finds a RefMethod in this RefClass
*
* @param name
* the method its name
* @param parameters
* the method its parameters
* @return the matched method or if not found null <code>null</code>
*/
public RefMethod getMethod(String name, Class<?>[] parameters) {
try {
for (RefMethod method : getMethods()) {
if (method.getName().equals(name)) {
if (parameters == null) {
return method;
}
if (method.getParameterTypes().equals(parameters)) {
return method;
}
}
}
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public String toString() {
if (this.instance != null) {
return new StringBuilder().append(this.instance.toString())
.append(" : ").append(this.clazz.toString()).toString();
}
return this.clazz.toString();
}
}
@@ -0,0 +1,105 @@
package org.parabot.core.reflect;
import java.lang.reflect.Constructor;
/**
*
* A <code>RefConstructor</code> class represent a constructor method of a
* <code>RefClass</code>.
*
* @author Everel
*
*/
public class RefConstructor extends RefModifiers {
private Constructor<?> constructor;
public RefConstructor(Constructor<?> constructor) {
super(constructor.getModifiers());
this.constructor = constructor;
}
/**
* Creates a new instance of this class by invoking this constructor
*
* @return the instance of the class
*/
public RefClass newInstance() {
return newInstance(new Object[] {});
}
/**
* Creates a new instance of this class by invoking this constructor
*
* @param args
* the arguments for the constructor
* @return the instance of the class
*/
public RefClass newInstance(Object... args) {
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
try {
Object instance = constructor.newInstance(args);
return new RefClass(instance);
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Get the value of the accessible flag for this object.
*
* @return the value of the object's accessible flag
*/
public boolean isAccessible() {
return constructor.isAccessible();
}
/**
* Returns <code>true</code> if this constructor is a synthetic constructor;
* returns <code>false</code> otherwise.
*
* @return <code>true</code> if this constructor is a synthetic constructor;
* returns <code>false</code> otherwise
*/
public boolean isSynthetic() {
return constructor.isSynthetic();
}
/**
* Returns the name of the constructor.
*
* @return name of the constructor
*/
public String getName() {
return constructor.getName();
}
/**
* Returns an array of the parameter types of this constructor
*
* @return an array of the parameter types of this constructor
*/
public Class<?>[] getParameterTypes() {
return constructor.getParameterTypes();
}
/**
* Gets the java reflection API constructor representation
*
* @return constructor
*/
public Constructor<?> getConstructor() {
return this.constructor;
}
public String toGenericString() {
return constructor.toGenericString();
}
public String toString() {
return constructor.toString();
}
}
@@ -0,0 +1,381 @@
package org.parabot.core.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
/**
*
* A <code>RefField</code> represents a field in a <code>RefClass</code>
*
* @author Everel
*
*/
public class RefField extends RefModifiers {
private Field field;
private Object instance;
public RefField(Field field) {
this(field, null);
}
public RefField(Field field, Object instance) {
super(field.getModifiers());
this.field = field;
this.instance = instance;
}
/**
* Retrieves the field it's value as object
*
* @return the value of the field
*/
public Object asObject() {
if (instance == null && !isStatic()) {
throw new IllegalStateException(
"Non static field cannot be fetched without an instance");
}
try {
if (!isAccessible()) {
field.setAccessible(true);
}
return field.get(instance);
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
/**
* Retrieves the field value as an integer
*
* @return integer value of field
*/
public int asInt() {
return (int) asObject();
}
/**
* Retrieves the field value as a long
*
* @return long value of field
*/
public long asLong() {
return (long) asObject();
}
/**
* Retrieves the field value as an double
*
* @return double value of field
*/
public double asDouble() {
return (double) asObject();
}
/**
* Retrieves the field value as a float
*
* @return float value of field
*/
public float asFloat() {
return (float) asObject();
}
/**
* Retrieves the field value as a boolean
*
* @return boolean value of field
*/
public boolean asBoolean() {
return (boolean) asObject();
}
/**
* Retrieves the field value as a short
*
* @return short value of field
*/
public short asShort() {
return (short) asObject();
}
/**
* Retrieves the field value as a byte
*
* @return byte value of field
*/
public byte asByte() {
return (byte) asObject();
}
/**
* Retrieves the field value as a java/lang/String
*
* @return String value of field
*/
public String asString() {
return (String) asObject();
}
/**
* Retrieves the field value as a character
*
* @return char value of field
*/
public char asChar() {
return (char) asObject();
}
/**
* Sets the field value
*
* @param object
* object to set
*/
public void set(Object object) {
if (instance == null && !isStatic()) {
throw new IllegalStateException(
"Non static field cannot be set without an instance");
}
if (!field.isAccessible()) {
field.setAccessible(true);
}
try {
field.set(instance, object);
} catch (Throwable t) {
t.printStackTrace();
}
}
/**
* Sets the field integer value
*
* @param i
* value to set
*/
public void setInt(int i) {
set(i);
}
/**
* Sets the field long value
*
* @param l
* value to set
*/
public void setLong(long l) {
set(l);
}
/**
* Sets the field double value
*
* @param d
* value to set
*/
public void setDouble(double d) {
set(d);
}
/**
* Sets the field float value
*
* @param f
* value to set
*/
public void setFloat(float f) {
set(f);
}
/**
* Sets the field boolean value
*
* @param b
* value to set
*/
public void setBoolean(boolean b) {
set(b);
}
/**
* Sets the field short value
*
* @param s
* value to set
*/
public void setShort(short s) {
set(s);
}
/**
* Sets the byte integer value
*
* @param b
* value to set
*/
public void setByte(byte b) {
set(b);
}
/**
* Sets the field string value
*
* @param s
* value to set
*/
public void setString(String s) {
set(s);
}
/**
* Sets the field char value
*
* @param c
* value to set
*/
public void setChar(char c) {
set(c);
}
/**
* Gets the field type
*
* @return type of field
*/
public Class<?> getType() {
return field.getType();
}
/**
* Gets the field type
*
* @return type of field
*/
public org.objectweb.asm.Type getASMType() {
return org.objectweb.asm.Type.getType(getType());
}
/**
* Gets the field description
*
* @return desc of field
*/
public String getTypeDesc() {
return getASMType().getDescriptor();
}
/**
* Gets the generic type of this field if any
*
* @return generic type
*/
public Type getGenericType() {
return field.getGenericType();
}
/**
* Determines if this field is an array
*
* @return <code>true</code> if this field is an array (type)
*/
public boolean isArray() {
return getASMType().getSort() == org.objectweb.asm.Type.ARRAY;
}
/**
* Returns the number of dimensions of this array type. This method should
* only be used for an array type.
*
* @return the number of dimensions of this array type
*/
public int getArrayDimensions() {
return getASMType().getDimensions();
}
/**
* Determines if field type is a primitive type
*
* @return <code>true</code> if the field is a primitive type, otherwise
* <code>false</code>
*/
public boolean isPrimitiveType() {
return RefUtils.isPrimitive(getType());
}
/**
* Determines if field type is a string type
*
* @return <code>true</code> if the field type is a string type, otherwise
* <code>false</code>
*/
public boolean isString() {
return getType() == String.class;
}
/**
* Returns <code>true</code> if this field represents an element of an
* enumerated type; returns <code>false</code> otherwise.
*
* @return <code>true</code> if and only if this field represents an element
* of an enumerated type.
*/
public boolean isEnumConstants() {
return field.isEnumConstant();
}
/**
* Get the value of the accessible flag for this object.
*
* @return the value of the object's accessible flag
*/
public boolean isAccessible() {
return field.isAccessible();
}
/**
* Returns <code>true</code> if this field is a synthetic field; returns
* <code>false</code> otherwise.
*
* @return <code>true</code> if this field is a synthetic field; returns
* <code>false</code> otherwise
*/
public boolean isSynthetic() {
return field.isSynthetic();
}
/**
* Returns the name of the field.
*
* @return name of the field
*/
public String getName() {
return field.getName();
}
/**
* Gets the java reflection API field representation
*
* @return field
*/
public Field getField() {
return field;
}
/**
* Gets the declaring <code>RefClass</code> of this field
* @return <code>RefClass</code> holding this field
*/
public RefClass getOwner() {
return new RefClass(field.getDeclaringClass(), instance);
}
public String toGenericString() {
return field.toGenericString();
}
public String toString() {
return field.toString();
}
}
@@ -0,0 +1,152 @@
package org.parabot.core.reflect;
import java.lang.reflect.Method;
/**
*
* A <code>RefMethod</code> class represent a method of a <code>RefClass</code>.
*
* @author Everel
*
*/
public class RefMethod extends RefModifiers {
private Method method;
private Object instance;
public RefMethod(Method method) {
this(method, null);
}
public RefMethod(Method method, Object instance) {
super(method.getModifiers());
this.method = method;
this.instance = instance;
}
/**
* Get the value of the accessible flag for this object.
*
* @return the value of the object's accessible flag
*/
public boolean isAccessible() {
return method.isAccessible();
}
/**
* Determines if this method is a bridge method.
*
* @return <code>true</code> if this method is a bridge method, otherwise
* <code>false</code>
*/
public boolean isBridge() {
return method.isBridge();
}
/**
* Determines if this method can take a variable amount of arguments
*
* @return <code>true</code> if this method can take a variable amount of
* arguments
*/
public boolean isVarArgs() {
return method.isVarArgs();
}
/**
* Returns <code>true</code> if this method is a synthetic method; returns
* <code>false</code> otherwise.
*
* @return <code>true</code> if this method is a synthetic method; returns
* <code>false</code> otherwise
*/
public boolean isSynthetic() {
return method.isSynthetic();
}
/**
* Returns the name of the method.
*
* @return name of the method
*/
public String getName() {
return method.getName();
}
/**
* Returns an array of the parameter types of this method
*
* @return an array of the parameter types of this method
*/
public Class<?>[] getParameterTypes() {
return method.getParameterTypes();
}
/**
* Gets the return type of this class
*
* @return return type of this class
*/
public Class<?> getReturnType() {
return method.getReturnType();
}
/**
* Gets the return type of this class
*
* @return return type of this class
*/
public org.objectweb.asm.Type getASMReturnType() {
return org.objectweb.asm.Type.getType(getReturnType());
}
/**
* Gets the java reflection API method representation
*
* @return constructor
*/
public Method getMethod() {
return this.method;
}
/**
* Invokes the method and returns it returned object
*
* @return object returned by the method
*/
public Object invoke() {
return invoke(new Object[] {});
}
/**
*
* Invokes the method and returns it returned object
*
* @param args
* arguments for the invokable method
* @return object returned by the method
*/
public Object invoke(Object... args) {
if (!isStatic() && instance == null) {
throw new IllegalStateException(
"Can not invoke non static method without an instance.");
}
if(!isAccessible()) {
method.setAccessible(true);
}
try {
Object retObject = method.invoke(instance, args);
return retObject;
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
public String toGenericString() {
return method.toGenericString();
}
public String toString() {
return method.toString();
}
}
@@ -0,0 +1,77 @@
package org.parabot.core.reflect;
import java.lang.reflect.Modifier;
/**
*
* @author Everel
*
*/
public class RefModifiers {
private int modifiers;
public RefModifiers() {
}
public RefModifiers(int modifiers) {
setModifiers(modifiers);
}
public void setModifiers(int modifiers) {
this.modifiers = modifiers;
}
public int getModifiers() {
return this.modifiers;
}
public boolean isStatic() {
return Modifier.isStatic(modifiers);
}
public boolean isAbstract() {
return Modifier.isAbstract(modifiers);
}
public boolean isFinal() {
return Modifier.isFinal(modifiers);
}
public boolean isInterface() {
return Modifier.isInterface(modifiers);
}
public boolean isNative() {
return Modifier.isNative(modifiers);
}
public boolean isPrivate() {
return Modifier.isPrivate(modifiers);
}
public boolean isProtected() {
return Modifier.isProtected(modifiers);
}
public boolean isPublic() {
return Modifier.isPublic(modifiers);
}
public boolean isStrict() {
return Modifier.isStrict(modifiers);
}
public boolean isSynchronized() {
return Modifier.isSynchronized(modifiers);
}
public boolean isTransient() {
return Modifier.isTransient(modifiers);
}
public boolean isVolatile() {
return Modifier.isVolatile(modifiers);
}
}
@@ -0,0 +1,23 @@
package org.parabot.core.reflect;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
*
* @author Everel
*
*/
public class RefUtils {
public static final Set<Class<?>> PRIMITIVE_TYPES = new HashSet<Class<?>>(
Arrays.asList(Boolean.class, Character.class, Byte.class,
Short.class, Integer.class, Long.class, Float.class,
Double.class, Void.class));
public static boolean isPrimitive(Class<?> clazz) {
return PRIMITIVE_TYPES.contains(clazz);
}
}
@@ -0,0 +1,68 @@
package org.parabot.core.ui;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JDialog;
import org.parabot.core.ui.components.PaintComponent;
import org.parabot.environment.OperatingSystem;
/**
*
* @author Everel
*
*/
public class BotDialog extends JDialog {
private static final long serialVersionUID = 521800552287194673L;
private static BotDialog instance;
private BotDialog(BotUI botUI) {
super(botUI);
botUI.setDialog(this);
setUndecorated(true);
getRootPane().setOpaque(false);
if (!OperatingSystem.getOS().equals(OperatingSystem.OTHER)) {
try {
setBackground(new Color(0, 0, 0, 0));
} catch (UnsupportedOperationException e) {
//My "fix" for the perpixel errors some user have when using VPSes
if (e.getMessage().contains("PERPIXEL_TRANS")) {
System.err
.println("WARNING: We were unable to set a translucent background!"
+ "\n\tThis generally occurs with old/outdated graphics drivers. Please consider updating them if possible."
+ "\n\tParabot will still attempt to run, however some GUI elements may or may not function.");
}
}
}
setFocusableWindowState(true);
setPreferredSize(botUI.getSize());
setSize(botUI.getSize());
setVisible(true);
setContentPane(PaintComponent.getInstance(botUI.getSize()));
botUI.setVisible(true);
}
public void setDimensions(Dimension dimension) {
setUndecorated(true);
getRootPane().setOpaque(false);
setBackground(new Color(0, 0, 0, 0));
setFocusableWindowState(true);
setPreferredSize(dimension);
setSize(dimension);
setVisible(true);
setContentPane(PaintComponent.getInstance());
PaintComponent.getInstance().setDimensions(dimension);
}
public static BotDialog getInstance(BotUI botUI) {
return instance == null ? instance = new BotDialog(botUI) : instance;
}
public static BotDialog getInstance() {
return getInstance(null);
}
}
@@ -0,0 +1,277 @@
package org.parabot.core.ui;
import org.parabot.core.Context;
import org.parabot.core.ui.components.GamePanel;
import org.parabot.core.ui.components.VerboseLoader;
import org.parabot.core.ui.images.Images;
import org.parabot.core.ui.utils.SwingUtil;
import org.parabot.environment.OperatingSystem;
import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.randoms.Random;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
/**
* The bot user interface
*
* @author Dane, Everel, Paradox
*/
public class BotUI extends JFrame implements ActionListener, ComponentListener, WindowListener {
private static final long serialVersionUID = -2126184292879805519L;
private static BotUI instance;
private static JDialog dialog;
private JMenuItem run, pause, stop;
private boolean runScript, pauseScript;
public BotUI(String username, String password) {
if (instance != null) {
throw new IllegalStateException("BotUI already created");
}
instance = this;
//WebLookAndFeel.install();
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
setTitle("Parabot");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createMenu();
setLayout(new BorderLayout());
addComponentListener(this);
addWindowListener(this);
add(GamePanel.getInstance());
GamePanel.getInstance().add(VerboseLoader.get(username, password), BorderLayout.CENTER);
add(Logger.getInstance(), BorderLayout.SOUTH);
SwingUtil.setParabotIcons(this);
pack();
setLocationRelativeTo(null);
BotDialog.getInstance(this);
if (!OperatingSystem.getOS().equals(OperatingSystem.WINDOWS)) {
BotDialog.getInstance().setVisible(false);
}
}
public static BotUI getInstance() {
return instance;
}
private void createMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("File");
JMenu scripts = new JMenu("Script");
JMenuItem screenshot = new JMenuItem("Create screenshot");
JMenuItem proxy = new JMenuItem("Network");
JMenuItem randoms = new JMenuItem("Randoms");
JMenuItem dialog = new JCheckBoxMenuItem("Disable dialog");
JMenuItem logger = new JCheckBoxMenuItem("Logger");
if (!OperatingSystem.getOS().equals(OperatingSystem.WINDOWS)) {
dialog.setSelected(true);
}
JMenuItem explorer = new JMenuItem("Reflection explorer");
JMenuItem exit = new JMenuItem("Exit");
run = new JMenuItem("Run");
run.setIcon(new ImageIcon(Images.getResource("/org/parabot/core/ui/images/run.png")));
pause = new JMenuItem("Pause");
pause.setEnabled(false);
pause.setIcon(new ImageIcon(Images.getResource("/org/parabot/core/ui/images/pause.png")));
stop = new JMenuItem("Stop");
stop.setEnabled(false);
stop.setIcon(new ImageIcon(Images.getResource("/org/parabot/core/ui/images/stop.png")));
screenshot.addActionListener(this);
proxy.addActionListener(this);
randoms.addActionListener(this);
dialog.addActionListener(this);
logger.addActionListener(this);
explorer.addActionListener(this);
exit.addActionListener(this);
run.addActionListener(this);
pause.addActionListener(this);
stop.addActionListener(this);
file.add(screenshot);
file.add(proxy);
file.add(randoms);
file.add(dialog);
file.add(logger);
file.add(explorer);
file.add(exit);
scripts.add(run);
scripts.add(pause);
scripts.add(stop);
menuBar.add(file);
menuBar.add(scripts);
setJMenuBar(menuBar);
}
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
case "Create screenshot":
JOptionPane.showMessageDialog(this, "We are still working on this...");
break;
case "Exit":
System.exit(0);
break;
case "Network":
NetworkUI.getInstance().setVisible(true);
break;
case "Randoms":
ArrayList<String> randoms = new ArrayList<>();
for (Random r : Context.getInstance().getRandomHandler().getRandoms()) {
randoms.add(r.getName());
}
RandomUI.getInstance().openFrame(randoms);
break;
case "Reflection explorer":
new ReflectUI().setVisible(true);
break;
case "Run":
if (pauseScript) {
pauseScript = false;
pause.setEnabled(true);
run.setEnabled(false);
setScriptState(Script.STATE_RUNNING);
break;
}
new ScriptSelector().setVisible(true);
break;
case "Pause":
setScriptState(Script.STATE_PAUSE);
pause.setEnabled(false);
run.setEnabled(true);
pauseScript = true;
break;
case "Stop":
setScriptState(Script.STATE_STOPPED);
break;
case "Logger":
Logger.getInstance().setVisible(!Logger.getInstance().isVisible());
BotUI.getInstance().pack();
BotUI.getInstance().revalidate();
if (!Logger.getInstance().isClearable()) {
Logger.getInstance().setClearable();
} else if(Logger.getInstance().isClearable() && !Logger.getInstance().isVisible()) {
Logger.clearLogger();
Logger.addMessage("Logger started", false);
}
break;
case "Disable dialog":
BotDialog.getInstance().setVisible(!dialog.isVisible());
break;
default:
System.out.println("Invalid command: " + command);
}
}
protected void setDialog(JDialog dialog) {
BotUI.dialog = dialog;
}
@Override
public void componentMoved(ComponentEvent e) {
if (dialog == null || !isVisible()) {
return;
}
Point gameLocation = GamePanel.getInstance().getLocationOnScreen();
dialog.setLocation(gameLocation.x, gameLocation.y);
}
public void toggleRun() {
runScript = !runScript;
if (runScript) {
scriptRunning();
} else {
scriptStopped();
}
}
private void scriptRunning() {
run.setEnabled(false);
pause.setEnabled(true);
stop.setEnabled(true);
}
private void scriptStopped() {
run.setEnabled(true);
pause.setEnabled(false);
stop.setEnabled(false);
}
private void setScriptState(int state) {
if (Context.getInstance().getRunningScript() != null) {
Context.getInstance().getRunningScript().setState(state);
}
}
@Override
public void componentResized(ComponentEvent e) {
if (isVisible()) {
BotDialog.getInstance().setSize(getSize());
}
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
}
@Override
public void windowActivated(WindowEvent arg0) {
}
@Override
public void windowClosed(WindowEvent arg0) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent arg0) {
}
@Override
public void windowDeiconified(WindowEvent arg0) {
if (isVisible()) {
BotDialog.getInstance().setVisible(false);
BotDialog.getInstance().setVisible(true);
}
}
@Override
public void windowIconified(WindowEvent arg0) {
}
@Override
public void windowOpened(WindowEvent arg0) {
}
}
@@ -0,0 +1,100 @@
package org.parabot.core.ui;
import org.parabot.core.Context;
import org.parabot.core.ui.components.GamePanel;
import org.parabot.environment.scripts.uliratha.UlirathaClient;
import javax.swing.*;
import java.awt.*;
/**
* @author JKetelaar
*/
public class Logger extends JPanel {
private static final long serialVersionUID = 1L;
private static Logger instance;
private final DefaultListModel<String> model;
private final JList<String> list;
private boolean clearable;
private Logger(){
setLayout(new BorderLayout());
list = new JList<>();
JScrollPane pane = new JScrollPane(list);
add(pane, BorderLayout.CENTER);
list.setCellRenderer(getRenderer());
model = new DefaultListModel<>();
list.setModel(model);
setPreferredSize(new Dimension((int) GamePanel.getInstance().getPreferredSize().getWidth(), 150));
model.addElement("Logger started");
setVisible(false);
}
private ListCellRenderer<? super String> getRenderer() {
return new DefaultListCellRenderer(){
private static final long serialVersionUID = -3589192791360628745L;
@Override
public Component getListCellRendererComponent(JList<?> list,
Object value, int index, boolean isSelected,
boolean cellHasFocus) {
JLabel listCellRendererComponent = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected,cellHasFocus);
listCellRendererComponent.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0,Color.BLACK));
return listCellRendererComponent;
}
};
}
public static Logger getInstance() {
return instance == null ? instance = new Logger() : instance;
}
/**
* Logs a message in the logger ui
* @param message
* @param uliratha Determines if this should be sent to the uliratha server
*/
public static void addMessage(String message, boolean uliratha){
instance.model.addElement(message);
if (uliratha){
UlirathaClient client;
if ((client = Context.getInstance().getUlirathaClient()) != null) {
client.sendMessage(message);
}
}
int last = instance.list.getModel().getSize() - 1;
if (last >= 0) {
instance.list.ensureIndexIsVisible(last);
}
if (instance.list.getModel().getSize() > 100 && instance.list.getModel().getElementAt(0) != null){
instance.model.remove(0);
}
}
/**
* @deprecated
* @param message
*/
public static void addMessage(String message){
addMessage(message, true);
}
protected static void clearLogger(){
instance.model.clear();
}
public boolean isClearable() {
return clearable;
}
public void setClearable() {
this.clearable = true;
}
}
@@ -0,0 +1,172 @@
package org.parabot.core.ui;
import org.parabot.core.Configuration;
import org.parabot.core.Core;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.ui.images.Images;
import org.parabot.core.ui.utils.SwingUtil;
import org.parabot.core.ui.utils.UILog;
import javax.swing.*;
import java.awt.*;
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;
/**
*
* Users must login with their parabot account through this LoginUI class
*
* @author Everel
*
*/
public class LoginUI extends JFrame {
private static final long serialVersionUID = 2032832552863466297L;
private static LoginUI instance;
private static AccountManager manager;
private JTextField txtUsername;
private JPasswordField txtPassword;
private JButton cmdLogin;
private JButton cmdRegister;
public void attemptLogin() {
String username = txtUsername.getText();
String password = new String(txtPassword.getPassword());
if (username.length() > 0 && password.length() > 0) {
if (manager.login(username, password, false)) {
Core.verbose("Logged in.");
instance.dispose();
Core.verbose("Running server selector.");
ServerSelector.getInstance();
} else {
Core.verbose("Failed to log in.");
UILog.log("Error", "Incorrect username or password. Have you tried logging into http://bdn.parabot.org/account/", JOptionPane.ERROR_MESSAGE);
}
}
}
private void attempt(String user, String pass) {
Core.verbose("Logging in...");
if (manager.login(user, pass, false)) {
Core.verbose("Logged in.");
instance.dispose();
Core.verbose("Running server selector.");
ServerSelector.getInstance();
} else {
Core.verbose("Failed to log in.");
UILog.log("Error", "Incorrect username or password. Have you tried logging into http://bdn.parabot.org/account/", 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);
SwingUtil.setParabotIcons(this);
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(Configuration.REGISTRATION_PAGE);
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);
this.setLocationRelativeTo(null);
}
}
@@ -0,0 +1,336 @@
package org.parabot.core.ui;
import org.parabot.core.network.NetworkInterface;
import org.parabot.core.network.proxy.ProxySocket;
import org.parabot.core.network.proxy.ProxyType;
import org.parabot.core.ui.utils.UILog;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class NetworkUI extends JFrame implements KeyListener, ActionListener,
DocumentListener {
private static final long serialVersionUID = 1L;
private static NetworkUI instance;
private JComboBox<ProxyType> proxyType;
private JTextField proxyHost;
private IntTextField proxyPort;
private JButton submitButton;
private JList<String>[] macList;
private JScrollPane[] macScrollList;
private JCheckBox authCheckBox;
private JTextField authUsername;
private JPasswordField authPassword;
private NetworkUI() {
initGUI();
}
public static NetworkUI getInstance() {
return instance == null ? instance = new NetworkUI() : instance;
}
@Override
public void setVisible(boolean b) {
BotUI.getInstance().setEnabled(!b);
if (ProxySocket.getProxyAddress() != null)
proxyHost.setText(ProxySocket.getProxyAddress().getHostName());
proxyPort.setText("" + ProxySocket.getProxyPort());
proxyType.setSelectedItem(ProxySocket.getProxyType());
authCheckBox.setSelected(ProxySocket.auth);
setLocationRelativeTo(BotUI.getInstance());
super.setVisible(b);
}
@SuppressWarnings("unchecked")
private void initGUI() {
proxyType = new JComboBox<ProxyType>(ProxyType.values());
proxyType.setSelectedItem(ProxySocket.getProxyType());
proxyType.addActionListener(this);
proxyHost = new JTextField();
proxyHost.addKeyListener(this);
proxyPort = new IntTextField(80, 5);
proxyPort.setColumns(5);
proxyPort.addKeyListener(this);
submitButton = new JButton("Submit");
submitButton.addActionListener(this);
byte[] mac = new byte[6];
mac = NetworkInterface.mac;
macList = new JList[mac.length];
macScrollList = new JScrollPane[mac.length];
for (int i = 0; i < mac.length; i++) {
int value = mac[i] & 0xFF;
macList[i] = createMacList();
macList[i].setSelectedIndex(value);
macScrollList[i] = new JScrollPane(macList[i]);
macList[i].ensureIndexIsVisible(value > 0 ? value - 1 : value);
}
authCheckBox = new JCheckBox("Auth");
authCheckBox.setSelected(ProxySocket.auth);
authCheckBox.addActionListener(this);
authUsername = new JTextField();
authPassword = new JPasswordField();
authUsername.setEnabled(authCheckBox.isSelected());
authPassword.setEnabled(authCheckBox.isSelected());
JPanel p = createPanelUI();
add(p);
setResizable(false);
setDefaultCloseOperation(HIDE_ON_CLOSE);
pack();
setTitle("Network Settings");
}
private JPanel createPanelUI() {
JPanel ret = new JPanel();
ret.setLayout(new BoxLayout(ret, BoxLayout.LINE_AXIS));
Box main = Box.createVerticalBox();
Box type = Box.createHorizontalBox();
type.add(new JLabel("Proxy Type: "));
type.add(proxyType);
Box host = Box.createHorizontalBox();
host.add(new JLabel("Proxy Host: "));
host.add(proxyHost);
Box port = Box.createHorizontalBox();
port.add(new JLabel("Proxy Port: "));
port.add(proxyPort);
Box auth = Box.createHorizontalBox();
auth.add(authCheckBox);
auth.add(Box.createHorizontalStrut(3));
auth.add(new JLabel("User:"));
auth.add(authUsername);
auth.add(Box.createHorizontalStrut(3));
auth.add(new JLabel("Pass:"));
auth.add(authPassword);
Box macBox = Box.createHorizontalBox();
macBox.add(new JLabel("MAC:"));
for (int i = 0; i < macList.length; i++) {
macBox.add(new JScrollPane(macList[i]));
macBox.add(Box.createHorizontalStrut(5));
}
Box submit = Box.createHorizontalBox();
submit.add(submitButton);
main.add(type);
main.add(Box.createVerticalStrut(5));
main.add(host);
main.add(Box.createVerticalStrut(5));
main.add(port);
main.add(Box.createVerticalStrut(5));
main.add(auth);
main.add(Box.createVerticalStrut(5));
main.add(macBox);
main.add(Box.createVerticalStrut(5));
main.add(submit);
ret.add(main);
ret.setBorder(new EmptyBorder(10, 10, 10, 10));
return ret;
}
@Override
public void keyPressed(KeyEvent e) {
Object source = e.getSource();
if (source == proxyPort || source == proxyHost) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
actionPerformed(null);
}
}
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void changedUpdate(DocumentEvent arg0) {
}
@Override
public void insertUpdate(DocumentEvent arg0) {
if (proxyPort.isValid()) {
proxyPort.setText("" + proxyPort.getValue());
}
}
@Override
public void removeUpdate(DocumentEvent arg0) {
insertUpdate(arg0);
}
@Override
public void actionPerformed(ActionEvent arg0) {
boolean b = false;
if (arg0.getSource() == proxyType) {
Object o = proxyType.getSelectedItem();
authCheckBox.setEnabled(o == ProxyType.SOCKS5);
proxyHost.setEnabled(o != ProxyType.NONE);
proxyPort.setEnabled(o != ProxyType.NONE);
b = true;
}
if (b || arg0.getSource() == authCheckBox) {
b = authCheckBox.isSelected() && authCheckBox.isEnabled();
ProxySocket.auth = b;
authUsername.setEnabled(b);
authPassword.setEnabled(b);
return;
}
if (proxyType.getSelectedItem() != ProxyType.NONE) {
if (proxyPort.getText().equals("")
|| proxyHost.getText().equals("")) {
UILog.log("Error", "Please supply proxy information!",
JOptionPane.ERROR_MESSAGE);
return;
}
}
String username = authUsername.getText();
char[] password = authPassword.getPassword();
ProxySocket
.setLogin(username, password);
byte[] mac = new byte[macList.length];
for (int i = 0; i < mac.length; i++)
mac[i] = (byte) Short.parseShort(
(String) macList[i].getSelectedValue(), 16);
NetworkInterface.setMac(mac);
try {
if (ProxySocket.getConnectionCount() > 0) {
try {
System.out.println("Closing Existing Connections...");
ProxySocket.closeConnections();
} catch (Exception e) {
}
}
ProxyType type = (ProxyType) proxyType.getSelectedItem();
String host = proxyHost.getText();
int port = proxyPort.getValue();
ProxySocket.setProxy(type, host, port);
UILog.log("Info", "Network settings have been set!");
} catch (Exception e) {
UILog.log("Error",
"Unable to set proxy info!\n\nReason:" + e.getMessage());
e.printStackTrace();
}
setVisible(false);
}
private JList<String> createMacList() {
String[] hexStrings = new String[256];
for (int i = 0; i < 256; i++) {
hexStrings[i] = String.format("%02X", i);
}
JList<String> ret = new JList<String>(hexStrings);
ret.setVisibleRowCount(3);
ret.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
return ret;
}
class IntTextField extends JTextField {
/**
*
*/
private static final long serialVersionUID = 1L;
public IntTextField(int defval, int size) {
super("" + defval, size);
}
protected Document createDefaultModel() {
return new IntTextDocument();
}
public boolean isValid() {
try {
int i = Integer.parseInt(getText());
return i > 0 && i <= 25565;
} catch (Exception e) {
return false;
}
}
public int getValue() {
try {
return Integer.parseInt(getText());
} catch (NumberFormatException e) {
return 0;
}
}
class IntTextDocument extends PlainDocument {
/**
*
*/
private static final long serialVersionUID = 1L;
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
if (str == null)
return;
String oldString = getText(0, getLength());
String newString = oldString.substring(0, offs) + str
+ oldString.substring(offs);
try {
Integer.parseInt(newString.replace("-", "") + "0");
super.insertString(offs, str, a);
} catch (NumberFormatException e) {
}
}
}
}
}
@@ -0,0 +1,88 @@
package org.parabot.core.ui;
import org.parabot.core.Context;
import org.parabot.core.Core;
import org.parabot.environment.scripts.randoms.Random;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
/**
* @author JKetelaar
*/
public class RandomUI implements ActionListener {
private static RandomUI instance;
private JFrame frame;
private ArrayList<JCheckBox> checkBoxes;
public static RandomUI getInstance() {
return instance == null ? instance = new RandomUI() : instance;
}
public void openFrame(ArrayList<String> randoms) {
frame = new JFrame();
frame.setBounds(100, 100, 351, 100 + (randoms.size() * 35));
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnSubmit = new JButton("Submit");
btnSubmit.setBounds(228, 35 + (randoms.size() * 35), 117, 29);
frame.getContentPane().add(btnSubmit);
JLabel lblRandoms = new JLabel("Randoms:");
lblRandoms.setBounds(6, 6, 250, 16);
frame.getContentPane().add(lblRandoms);
if (randoms.size() > 0) {
checkBoxes = new ArrayList<>();
for (int i = 0; i < randoms.size(); i++) {
JCheckBox checkBox = new JCheckBox(randoms.get(i));
checkBox.setBounds(6, 35 + (i * 35), 250, 23);
frame.getContentPane().add(checkBox);
if (isActive(randoms.get(i))) {
checkBox.setSelected(true);
}
checkBoxes.add(checkBox);
}
} else {
JLabel lblNone = new JLabel("None (yet).");
lblNone.setBounds(6, 35, 120, 16);
frame.getContentPane().add(lblNone);
}
btnSubmit.addActionListener(this);
this.frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
Context.getInstance().getRandomHandler().clearActiveRandoms();
if (checkBoxes != null && checkBoxes.size() > 0) {
for (JCheckBox checkBox : this.checkBoxes) {
if (checkBox.isSelected()) {
for (Random r : Context.getInstance().getRandomHandler().getRandoms()) {
if (r.getName().equalsIgnoreCase(checkBox.getText().toLowerCase())) {
Core.verbose("Actived random '" + r.getName() + "'");
Context.getInstance().getRandomHandler().setActive(r.getName());
}
}
}
}
}
this.frame.dispose();
}
private boolean isActive(String random) {
for (Random r : Context.getInstance().getRandomHandler().getActiveRandoms()) {
if (r.getName().equalsIgnoreCase(random.toLowerCase())) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,198 @@
package org.parabot.core.ui;
import java.awt.Dimension;
import java.util.HashMap;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import org.parabot.core.Context;
import org.parabot.core.asm.ASMClassLoader;
import org.parabot.core.classpath.ClassPath;
import org.parabot.core.reflect.RefClass;
import org.parabot.core.reflect.RefField;
/**
*
* A Reflection explorer
*
* @author Everel
*
*/
public class ReflectUI extends JFrame {
private static final long serialVersionUID = 98565034137367257L;
private DefaultMutableTreeNode root;
private DefaultTreeModel model;
private JEditorPane basicInfoPane;
private JEditorPane selectionInfoPane;
private Object instance;
private HashMap<DefaultMutableTreeNode, RefClass> classes;
private HashMap<DefaultMutableTreeNode, RefField> fields;
public ReflectUI() {
this.root = new DefaultMutableTreeNode("Classes");
this.model = new DefaultTreeModel(root);
this.basicInfoPane = new JEditorPane();
this.selectionInfoPane = new JEditorPane();
this.classes = new HashMap<>();
this.fields = new HashMap<>();
this.instance = Context.getInstance().getClient();
fillModel();
setTitle("Reflection explorer");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
JPanel exploreContent = new JPanel();
exploreContent.setLayout(new BoxLayout(exploreContent, BoxLayout.X_AXIS));
JPanel infoContent = new JPanel();
infoContent.setLayout(new BoxLayout(infoContent, BoxLayout.Y_AXIS));
JTree tree = new JTree();
tree.setRootVisible(true);
tree.setShowsRootHandles(true);
tree.setModel(model);
tree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent event) {
TreePath path = event.getPath();
Object[] pathElements = path.getPath();
Object element = pathElements[pathElements.length-1];
if(pathElements.length == 2) {
// class
setClassInfo(classes.get(element));
}
if(pathElements.length == 3) {
// field
setFieldInfo(fields.get(element));
}
}
});
JScrollPane scrollTreePane = new JScrollPane(tree);
scrollTreePane.setPreferredSize(new Dimension(400, 300));
basicInfoPane.setContentType("text/html");
basicInfoPane.setEditable(false);
selectionInfoPane.setContentType("text/html");
selectionInfoPane.setEditable(false);
JScrollPane scrollBasicInfoPane = new JScrollPane(basicInfoPane);
scrollBasicInfoPane.setPreferredSize(new Dimension(400, 90));
JScrollPane scrollSelectInfoPane = new JScrollPane(selectionInfoPane);
scrollSelectInfoPane.setPreferredSize(new Dimension(400, 200));
infoContent.add(scrollBasicInfoPane);
infoContent.add(Box.createRigidArea(new Dimension(0, 10)));
infoContent.add(scrollSelectInfoPane);
exploreContent.add(scrollTreePane);
exploreContent.add(Box.createRigidArea(new Dimension(10, 0)));
exploreContent.add(infoContent);
content.add(exploreContent);
JScrollPane contentPane = new JScrollPane(content);
Dimension prefSize = content.getPreferredSize();
contentPane.setPreferredSize(new Dimension(prefSize.width + contentPane.getVerticalScrollBar().getPreferredSize().width, prefSize.height + contentPane.getHorizontalScrollBar().getPreferredSize().height));
setContentPane(contentPane);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private void fillModel() {
Context context = Context.getInstance();
ClassPath classPath = context.getClassPath();
ASMClassLoader classLoader = context.getASMClassLoader();
for (String className : classPath.classNames) {
try {
DefaultMutableTreeNode classNode = new DefaultMutableTreeNode(
"Class: " + className);
DefaultMutableTreeNode fieldNode;
Class<?> clazz = classLoader.loadClass(className);
RefClass refClass = new RefClass(clazz);
if(refClass.instanceOf(this.instance)) {
refClass.setInstance(this.instance);
}
for (RefField field : refClass.getFields()) {
fieldNode = new DefaultMutableTreeNode("Field: " + field.getName() + " [type: " + field.getASMType() + "] [value: " + field.asObject() + "]");
classNode.add(fieldNode);
fields.put(fieldNode, field);
}
classes.put(classNode, refClass);
root.add(classNode);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
private void fillBasicInfoPane() {
Context context = Context.getInstance();
ClassPath classPath = context.getClassPath();
StringBuilder builder = new StringBuilder();
builder.append("<b>Classes: </b>").append(classPath.classNames.size()).append("<br/>");
builder.append("<b>Using instance: </b>").append(instance.toString()).append("<br/>");
basicInfoPane.setText(builder.toString());
}
private void setFieldInfo(RefField refField) {
StringBuilder builder = new StringBuilder();
RefClass refClass = refField.getOwner();
builder.append("<h1>").append(refClass.getClassName()).append(".").append(refField.getName()).append("</h1><br/>");
builder.append("<b>Class: </b>").append(refClass.getClassName()).append("<br/>");
builder.append("<b>Value: </b>").append(refField.asObject()).append("<br/>");
builder.append("<b>Type: </b>").append(refField.getASMType().getClassName()).append("<br/>");
builder.append("<b>Static: </b>").append(refField.isStatic() ? "yes" : "no").append("<br/>");
builder.append("<b>Array: </b>").append(refField.isArray() ? refField.getArrayDimensions() + " dimension(s)" : "no").append("<br/>");
selectionInfoPane.setText(builder.toString());
fillBasicInfoPane();
}
private void setClassInfo(RefClass refClass) {
StringBuilder builder = new StringBuilder();
builder.append("<h1>").append(refClass.getClassName()).append("</h1><br/>");
if(refClass.getClassName().contains(".")) {
builder.append("<b>Package: </b>").append(refClass.getClassName().substring(0, refClass.getClassName().lastIndexOf("."))).append("<br/>");
}
builder.append("<b>Abstract: </b>").append(refClass.isAbstract() ? "yes" : "no").append("<br/>");
builder.append("<b>Interface: </b>").append(refClass.isInterface() ? "yes" : "no").append("<br/>");
builder.append("<b>Superclass: </b>").append(refClass.hasSuperclass() ? refClass.getSuperclass().getClassName() : "no").append("<br/>");
builder.append("<b>Fields: </b>").append(refClass.getFields().length).append("<br/>");
builder.append("<b>Methods: </b>").append(refClass.getMethods().length).append("<br/>");
builder.append("<b>Constructors: </b>").append(refClass.getConstructors().length).append("<br/>");
selectionInfoPane.setText(builder.toString());
fillBasicInfoPane();
}
}
@@ -0,0 +1,224 @@
package org.parabot.core.ui;
import org.parabot.core.Context;
import org.parabot.core.Directories;
import org.parabot.core.desc.ScriptDescription;
import org.parabot.core.parsers.scripts.ScriptParser;
import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.scripts.Category;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.util.HashMap;
/**
*
* Script Selector GUI, shows all scripts
*
* @author Everel
*/
public final class ScriptSelector extends JFrame {
public static ScriptParser parser;
private static final long serialVersionUID = 1L;
private HashMap<String, DefaultMutableTreeNode> categories;
private HashMap<String, ScriptDescription> format;
private DefaultMutableTreeNode root;
private DefaultTreeModel model;
private final int WIDTH;
private final int HEIGHT;
public ScriptSelector() {
this.categories = new HashMap<String, DefaultMutableTreeNode>();
this.format = new HashMap<String, ScriptDescription>();
this.root = new DefaultMutableTreeNode("Scripts");
this.WIDTH = 640;
this.HEIGHT = 256 + 128;
this.model = new DefaultTreeModel(root);
putScripts();
createUI();
}
private void runScript(ScriptDescription desc) {
dispose();
final ThreadGroup tg = Context.threadGroups.keySet().iterator()
.next();
ScriptParser.SCRIPT_CACHE.get(desc).run(tg);
}
private void putScripts() {
final ScriptDescription[] descs = ScriptParser.getDescriptions();
if (descs == null) {
return;
}
for (final ScriptDescription scriptDesc : descs) {
if (categories.get(scriptDesc.category) == null) {
DefaultMutableTreeNode cat = new DefaultMutableTreeNode(Category.valueOf(scriptDesc.category.toUpperCase()));
cat.add(new DefaultMutableTreeNode(scriptDesc.scriptName));
root.add(cat);
categories.put(scriptDesc.category, cat);
} else {
categories.get(scriptDesc.category).add(
new DefaultMutableTreeNode(scriptDesc.scriptName));
}
format.put(scriptDesc.scriptName, scriptDesc);
}
}
private String getScriptName(String path) {
return path.split(", ")[2].replaceAll("\\]", "");
}
private String getServerDesc(final String[] servers) {
if (servers == null) {
return "Unknown";
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < servers.length; i++) {
builder.append(servers[i]);
if ((i + 1) < servers.length) {
builder.append(", ");
}
}
return builder.toString();
}
private void createUI() {
this.setTitle("Script Selector");
this.setLayout(new BorderLayout());
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(null);
panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
tree = new JTree();
tree.setCellRenderer(new ScriptTreeCellRenderer());
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
tree.setModel(model);
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
String path = e.getPath().toString();
if (path.split(",").length == 3) {
// local scripts
ScriptDescription def = format.get(getScriptName(e
.getPath().toString()));
if (def != null) {
StringBuilder html = new StringBuilder("<html>");
html.append("<h1><font color=\"black\">")
.append(def.scriptName)
.append("</font></h1><br/>");
html.append("<font color=\"black\"><b>Author: </b>")
.append(def.author).append("</font><br/>");
html.append("<font color=\"black\"><b>Servers: </b>")
.append(getServerDesc(def.servers))
.append("</font><br/>");
html.append("<font color=\"black\"><b>Version: </b>")
.append(def.version).append("</font><br/>");
html.append(
"<font color=\"black\"><b>Description: </b>")
.append(def.description).append("</font><br/>");
html.append("</html>");
scriptInfo.setText(new String(html));
}
}
}
});
scriptInfo = new JEditorPane();
scriptInfo.setContentType("text/html");
scriptInfo.setEditable(false);
JScrollPane scrlScriptTree = new JScrollPane(tree);
scrlScriptTree.setBounds(4, 4, WIDTH / 2 - 4 - 64, HEIGHT - 4 - 28);
JScrollPane scrlScriptInfo = new JScrollPane(scriptInfo);
scrlScriptInfo.setBounds(WIDTH / 2 + 4 - 64, 4, WIDTH / 2 - 8 + 64,
HEIGHT - 4 - 28);
JButton cmdStart = new JButton("Start");
cmdStart.setBounds(WIDTH - 96 - 4, HEIGHT - 24 - 4, 96, 24);
cmdStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String s = getScriptName(tree.getSelectionPath().toString());
if (s != null) {
try {
WebUtil.getContents("http://bdn.parabot.org/api/v2/scripts/local", "script=" + URLEncoder.encode(s, "UTF-8") + "&username=" + URLEncoder.encode(Context.getUsername(), "UTF-8"));
} catch (MalformedURLException | UnsupportedEncodingException e1) {
e1.printStackTrace();
}
runScript(format.get(s));
}
}
});
JButton cmdHome = new JButton("Open home");
cmdHome.setBounds(WIDTH - (96 * 2) - 4 - 32, HEIGHT - 24 - 4, 96 + 32,
24);
cmdHome.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().open(Directories.getWorkspace());
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
panel.add(scrlScriptTree);
panel.add(scrlScriptInfo);
panel.add(cmdStart);
panel.add(cmdHome);
this.add(panel);
this.pack();
this.setLocationRelativeTo(getOwner());
}
private class ScriptTreeCellRenderer implements TreeCellRenderer {
private JLabel label;
ScriptTreeCellRenderer() {
label = new JLabel();
}
@Override
public Component getTreeCellRendererComponent(JTree list, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean focused) {
Object o = ((DefaultMutableTreeNode) value).getUserObject();
BufferedImage icon = (o instanceof Category ? ((Category) o)
.getIcon() : Category.getIcon("script"));
label.setIcon(icon != null ? new ImageIcon(icon) : null);
label.setFont(o instanceof Category ? fontCategory : fontScript);
label.setForeground(selected ? Color.DARK_GRAY : Color.BLACK);
label.setText(String.valueOf(value));
return label;
}
}
private Font fontCategory = new Font("Arial", Font.BOLD, 12);
private Font fontScript = new Font("Arial", Font.PLAIN, 12);
private JTree tree;
private JEditorPane scriptInfo;
}
@@ -0,0 +1,109 @@
package org.parabot.core.ui;
import org.parabot.core.desc.ServerDescription;
import org.parabot.core.parsers.servers.ServerParser;
import org.parabot.core.ui.components.ServerComponent;
import org.parabot.environment.Environment;
import javax.swing.*;
import java.awt.*;
import java.util.LinkedList;
import java.util.Queue;
/**
*
* Shows a list of every supported server which can be started
*
* @author Dane, Everel
*
*/
public class ServerSelector extends JPanel {
public static String initServer;
private static final long serialVersionUID = 5238720307271493899L;
private static ServerSelector instance;
public static ServerSelector getInstance() {
if (instance == null) {
instance = new ServerSelector();
}
return instance;
}
public ServerSelector() {
Queue<ServerComponent> widgets = getServers();
if (initServer != null) {
if (runServer(widgets)) {
initServer = null;
return;
}
}
setLayout(new BorderLayout());
setPreferredSize(new Dimension(600, 400));
JPanel interior = new JPanel(null);
int i = 0;
int y = 0;
while (widgets != null && !widgets.isEmpty()) {
final ServerComponent w = widgets.poll();
w.setSize(300, 100);
if(i % 2 == 0 && i != 0) {
y += 100;
}
w.setLocation(i % 2 == 0 ? 0 : 300, y);
interior.add(w);
i++;
}
y += 100;
interior.setPreferredSize(new Dimension(300, y));
JScrollPane scrlInterior = new JScrollPane(interior);
scrlInterior
.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrlInterior
.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrlInterior, BorderLayout.CENTER);
}
/**
* This method is called when -server argument is given
*
* @param widgets
*/
private boolean runServer(Queue<ServerComponent> widgets) {
if (widgets == null || widgets.isEmpty()) {
return false;
}
final String serverName = initServer.toLowerCase();
for (ServerComponent widget : widgets) {
if (widget.desc.getServerName().toLowerCase().equals(serverName)) {
Environment.load(widget.desc);
return true;
}
}
return false;
}
/**
* Fetches array of server widgets
*
* @return widgets array
*/
public Queue<ServerComponent> getServers() {
final Queue<ServerComponent> widgets = new LinkedList<>();
ServerDescription[] servers = ServerParser.getDescriptions();
if (servers != null) {
for (ServerDescription desc : servers) {
widgets.add(new ServerComponent(desc));
}
}
return widgets;
}
}
@@ -0,0 +1,57 @@
package org.parabot.core.ui.components;
import org.parabot.core.Context;
import javax.swing.*;
import java.awt.*;
/**
*
* Main panel where applets are added.
*
* @author Everel
*
*/
public class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
private static GamePanel instance;
private GamePanel() {
setFocusable(true);
setFocusTraversalKeysEnabled(false);
setOpaque(true);
setBackground(Color.black);
setPreferredSize(new Dimension(770, 503));
GroupLayout panelLayout = new GroupLayout(this);
setLayout(panelLayout);
panelLayout.setHorizontalGroup(panelLayout.createParallelGroup(
GroupLayout.Alignment.LEADING).addGap(0, 770, Short.MAX_VALUE));
panelLayout.setVerticalGroup(panelLayout.createParallelGroup(
GroupLayout.Alignment.LEADING).addGap(0, 418, Short.MAX_VALUE));
}
/**
* Updates context of this panel and adds a different Applet to the panel
*
* @param c
*/
public void setContext(final Context c) {
add(c.getApplet(), BorderLayout.CENTER);
}
/**
* Gets instance of this panel
*
* @return instance of this panel
*/
public static GamePanel getInstance() {
return instance == null ? instance = new GamePanel() : instance;
}
/**
* Removes all components
*/
public void removeComponents() {
removeAll();
}
}
@@ -0,0 +1,90 @@
package org.parabot.core.ui.components;
import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import org.parabot.core.Context;
import org.parabot.environment.api.interfaces.Paintable;
import org.parabot.environment.api.utils.Time;
/**
*
* The panel that is painted on
*
* @author Everel
*
*/
public class PaintComponent extends JComponent implements Runnable {
private static final long serialVersionUID = 4653612412080038193L;
private static PaintComponent instance;
private BufferedImage buffer;
private Graphics2D g2;
private Dimension dimensions;
private Context context;
private PaintComponent(Dimension dimensions) {
this.dimensions = dimensions;
this.buffer = new BufferedImage(dimensions.width, dimensions.height, BufferedImage.TYPE_INT_ARGB);
this.g2 = buffer.createGraphics();
setPreferredSize(dimensions);
setSize(dimensions);
setOpaque(false);
setIgnoreRepaint(true);
}
public void setDimensions(Dimension dimensions) {
this.dimensions = dimensions;
this.dimensions = dimensions;
this.buffer = new BufferedImage(dimensions.width, dimensions.height, BufferedImage.TYPE_INT_ARGB);
this.g2 = buffer.createGraphics();
setPreferredSize(dimensions);
setSize(dimensions);
setOpaque(false);
setIgnoreRepaint(true);
}
public static PaintComponent getInstance(Dimension dimensions) {
return instance == null ? instance = new PaintComponent(dimensions) : instance;
}
public static PaintComponent getInstance() {
return getInstance(null);
}
public void startPainting(Context context) {
this.context = context;
new Thread(this).start();
}
@Override
public void paintComponent(Graphics g) {
g2.setComposite(AlphaComposite.Clear);
g2.fillRect(0, 0, dimensions.width, dimensions.height);
g2.setComposite(AlphaComposite.SrcOver);
if(context != null) {
for(Paintable p : context.getPaintables()) {
p.paint(g);
}
context.getPaintDebugger().debug(g2);
}
g.drawImage(buffer, 0, 0, null);
}
@Override
public void run() {
while(true) {
Time.sleep(100);
repaint();
}
}
}
@@ -0,0 +1,92 @@
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.RenderingHints;
import java.awt.geom.Rectangle2D;
/**
*
* ProgressBar
*
* @author Everel
*
*/
public class ProgressBar {
private double value;
private int width;
private int height;
private double locX;
private Color progColor;
private Color backColor;
private FontMetrics fontMetrics;
private String text;
public ProgressBar(int width, int height) {
this.progColor = new Color(255, 0, 0);
this.backColor = new Color(74, 74, 72, 100);
this.width = width;
this.height = height;
this.text = "";
}
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);
}*/
int r = (int) (((double) (225 - 218) * (double) val) / ((double) 100.D));
int g = (int) (((double) (253 - 165) * (double) val) / ((double) 100.D));
int b = (int) (((double) (145 - 32) * (double) val) / ((double) 100.D));
this.progColor = new Color(255 - r, 253 - g, 145 - b);
}
public double getValue() {
return value;
}
public void draw(Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
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);
}
}
@@ -0,0 +1,130 @@
package org.parabot.core.ui.components;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
import org.parabot.core.desc.ServerDescription;
import org.parabot.environment.Environment;
/**
* A neat looking server component
*
* @author Everel
*
*/
public class ServerComponent extends JPanel implements MouseListener,
MouseMotionListener {
private static final long serialVersionUID = 1L;
public ServerDescription desc;
private String name;
private boolean hovered;
public ServerComponent(final ServerDescription desc) {
this.desc = desc;
setLayout(null);
this.name = desc.getServerName().replaceAll(" ", "");
addMouseListener(this);
addMouseMotionListener(this);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public String getName() {
return name;
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
setOpaque(false);
super.paintComponent(g);
setOpaque(true);
int w = getWidth();
int h = getHeight();
Color bgColor = Color.LIGHT_GRAY;
if (hovered) {
bgColor = Color.GRAY;
}
g2d.setColor(bgColor);
g2d.fillRect(0, 0, w, h);
g.setColor(Color.black);
Font title = new Font("Arial", Font.BOLD, 16);
g.setFont(title);
String serverName = desc.getServerName();
int sw = g.getFontMetrics().stringWidth(serverName);
g.drawString(serverName, (w / 2) - (sw / 2), 30);
Font normal = new Font("Arial", Font.PLAIN, 12);
g.setFont(normal);
FontMetrics fm = g.getFontMetrics();
String author = "Author: " + desc.getAuthor();
String revision = "Revision: " + desc.getRevision();
g.drawString(author, (w / 2) - (fm.stringWidth(author) / 2), 55);
g.drawString(revision, (w / 2) - (fm.stringWidth(revision) / 2), 70);
}
public void load(final ServerDescription desc) {
VerboseLoader.get().switchState(VerboseLoader.STATE_LOADING);
new Thread(new Runnable() {
@Override
public void run() {
Environment.load(desc);
}
}).start();
}
@Override
public void mouseMoved(MouseEvent e) {
if (!hovered) {
hovered = true;
this.repaint();
}
}
@Override
public void mouseExited(MouseEvent e) {
if (hovered) {
hovered = false;
this.repaint();
}
}
@Override
public void mousePressed(MouseEvent e) {
if (hovered) {
load(desc);
}
}
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
}
@@ -0,0 +1,250 @@
package org.parabot.core.ui.components;
import org.parabot.core.Core;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.forum.AccountManagerAccess;
import org.parabot.core.io.ProgressListener;
import org.parabot.core.ui.ServerSelector;
import org.parabot.core.ui.images.Images;
import org.parabot.core.ui.utils.UILog;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
/**
* An informative JPanel which tells the user what bot is doing
*
* @author Everel
*
*/
public class VerboseLoader extends JPanel implements ProgressListener {
private static final long serialVersionUID = 7412412644921803896L;
private static VerboseLoader current;
private static String state = "Initializing loader...";
public static final int STATE_AUTHENTICATION = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_SERVER_SELECT = 2;
private int currentState;
private static AccountManager manager;
private FontMetrics fontMetrics;
private BufferedImage background;
private ProgressBar progressBar;
private JPanel loginPanel;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override
public final void setManager(AccountManager manager) {
VerboseLoader.manager = manager;
}
};
private VerboseLoader(String username, String password) {
if(current != null) {
throw new IllegalStateException("MainScreenComponent already made.");
}
current = this;
this.background = Images.getResource("/org/parabot/core/ui/images/background.png");
this.progressBar = new ProgressBar(400, 20);
setLayout(new GridBagLayout());
setSize(775, 510);
setPreferredSize(new Dimension(775, 510));
setDoubleBuffered(true);
setOpaque(false);
if(username != null && password != null) {
if(Core.inDebugMode() || manager.login(username, password, false)) {
currentState = STATE_SERVER_SELECT;
}
}
if(currentState == STATE_AUTHENTICATION) {
addLoginPanel();
} else if(currentState == STATE_SERVER_SELECT) {
addServerPanel();
}
}
public void addServerPanel() {
JPanel servers = ServerSelector.getInstance();
add(servers, new GridBagConstraints());
}
public void addLoginPanel() {
loginPanel = new JPanel();
loginPanel.setOpaque(false);
loginPanel.setLayout(new BoxLayout(loginPanel, BoxLayout.Y_AXIS));
Font labelFont = new Font("Times New Roman", Font.PLAIN, 11);
JLabel usernameLabel = new JLabel("Username");
usernameLabel.setFont(labelFont);
usernameLabel.setAlignmentX(Box.CENTER_ALIGNMENT);
usernameLabel.setForeground(Color.white);
final JTextField userInput = new JTextField(25);
final JTextField passInput = new JPasswordField(25);
userInput.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
passInput.requestFocus();
}
});
userInput.setFont(labelFont);
userInput.setAlignmentX(Box.CENTER_ALIGNMENT);
userInput.setMaximumSize(userInput.getPreferredSize());
final JButton login = new JButton("Login");
passInput.setAlignmentX(Box.CENTER_ALIGNMENT);
passInput.setMaximumSize(userInput.getPreferredSize());
passInput.setPreferredSize(new Dimension(userInput.getWidth(), 20));
passInput.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
login.doClick();
}
});
JLabel passwordLabel = new JLabel("Password");
passwordLabel.setFont(labelFont);
passwordLabel.setAlignmentX(Box.CENTER_ALIGNMENT);
passwordLabel.setForeground(Color.white);
login.setAlignmentX(Box.CENTER_ALIGNMENT);
login.setOpaque(false);
login.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(manager.login(userInput.getText(), passInput.getText(), false)) {
switchState(STATE_SERVER_SELECT);
} else {
Core.verbose("Failed to log in.");
UILog.log("Error", "Incorrect username or password. Have you tried logging into http://bdn.parabot.org/account/", JOptionPane.ERROR_MESSAGE);
}
}
});
loginPanel.add(Box.createRigidArea(new Dimension(0, 5)));
loginPanel.add(usernameLabel);
loginPanel.add(Box.createRigidArea(new Dimension(0, 5)));
loginPanel.add(userInput);
loginPanel.add(Box.createRigidArea(new Dimension(0, 5)));
loginPanel.add(passwordLabel);
loginPanel.add(Box.createRigidArea(new Dimension(0, 5)));
loginPanel.add(passInput);
loginPanel.add(Box.createRigidArea(new Dimension(0, 5)));
loginPanel.add(login);
loginPanel.add(Box.createRigidArea(new Dimension(0, 5)));
add(loginPanel, new GridBagConstraints());
}
public void switchState(int state) {
removeAll();
if(state == STATE_AUTHENTICATION) {
addLoginPanel();
} else if(state == STATE_SERVER_SELECT) {
addServerPanel();
}
this.currentState = state;
revalidate();
}
/**
* Paints on this panel
*/
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g = (Graphics2D) graphics;
g.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawImage(background, 0, 0, null);
if (fontMetrics == null) {
fontMetrics = g.getFontMetrics();
}
if(currentState == STATE_AUTHENTICATION) {
g.setColor(new Color(74, 74, 72, 100));
g.fillRect(loginPanel.getX() - 10, loginPanel.getY(), loginPanel.getWidth() + 20, loginPanel.getHeight());
g.setColor(Color.black);
g.drawRect(loginPanel.getX() - 10, loginPanel.getY(), loginPanel.getWidth() + 20, loginPanel.getHeight());
}
g.setColor(Color.white);
if(currentState == STATE_LOADING) {
progressBar.draw(g, (getWidth() / 2) - 200, 220);
g.setFont(new Font("Times New Roman", Font.PLAIN, 14));
int x = (getWidth() / 2) - (fontMetrics.stringWidth(state) / 2);
g.drawString(state, x, 200);
}
g.setFont(new Font("Times New Roman", Font.PLAIN, 12));
final String version = "v2.1";
g.drawString(version,
getWidth() - g.getFontMetrics().stringWidth(version) - 10,
getHeight() - 12);
}
/**
* Gets instance of this panel
* @return instance of this panel
*/
public static VerboseLoader get(String username, String password) {
return current == null ? new VerboseLoader(username, password) : current;
}
/**
* Gets instance of this panel
* @return instance of this panel
*/
public static VerboseLoader get() {
return current == null ? new VerboseLoader(null, null) : current;
}
/**
* Updates the status message and repaints the panel
* @param message
*/
public static void setState(final String message) {
state = message;
current.repaint();
}
@Override
public void onProgressUpdate(double value) {
progressBar.setValue(value);
this.repaint();
}
@Override
public void updateDownloadSpeed(double mbPerSecond) {
progressBar.setText(String.format("(%.2fMB/s)", mbPerSecond));
}
}
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="500.0" minWidth="500.0" prefHeight="503.0" prefWidth="735.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<TabPane>
<tabs>
<Tab closable="false" text="Scripts">
<content>
<BorderPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<top>
<ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<items>
<TextField promptText="Search query" />
<Separator prefHeight="30.0" prefWidth="25.0" visible="false" />
<ComboBox prefWidth="150.0" promptText="Category" />
<Separator prefHeight="30.0" prefWidth="25.0" visible="false" />
<CheckBox mnemonicParsing="false" text="All servers" />
<Separator prefHeight="30.0" prefWidth="25.0" visible="false" />
<CheckBox mnemonicParsing="false" text="Include local scripts" />
<Separator prefHeight="30.0" prefWidth="25.0" visible="false" />
<Button alignment="CENTER_RIGHT" mnemonicParsing="false" text="Search" />
</items>
</ToolBar>
</top>
<center>
<TableView prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn prefWidth="75.0" text="Name" />
<TableColumn prefWidth="75.0" text="Category" />
<TableColumn prefWidth="75.0" text="Price" />
</columns>
<contextMenu>
<ContextMenu>
<items>
<MenuItem mnemonicParsing="false" text="View information" />
</items>
</ContextMenu>
</contextMenu>
</TableView>
</center>
<bottom>
<HBox alignment="CENTER_RIGHT" prefHeight="35.0" prefWidth="735.0" BorderPane.alignment="CENTER">
<children>
<Button mnemonicParsing="false" prefHeight="25.0" prefWidth="83.0" text="Start" />
<Separator prefHeight="4.0" prefWidth="35.0" visible="false" />
</children>
</HBox>
</bottom>
</BorderPane>
</content>
</Tab>
<Tab text="JKChicken">
<content>
<BorderPane prefHeight="200.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
</center>
</BorderPane>
@@ -0,0 +1,31 @@
package org.parabot.core.ui.images;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import javax.imageio.ImageIO;
/**
*
* Caches and loads images from resource
*
* @author Everel
*
*/
public final class Images {
private static final HashMap<String, BufferedImage> IMAGE_CACHE = new HashMap<String, BufferedImage>();
public static BufferedImage getResource(final String resource) {
if(IMAGE_CACHE.containsKey(resource)) {
return IMAGE_CACHE.get(resource);
}
try {
final BufferedImage img = ImageIO.read(Images.class.getResourceAsStream(resource));
IMAGE_CACHE.put(resource, img);
return img;
} catch (Throwable t) {
throw new RuntimeException("Failed to load image from resource. " + t.getMessage());
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Some files were not shown because too many files have changed in this diff Show More