Merge pull request #304 from Parabot/development

[RELEASE] Release of V2.8
This commit is contained in:
Jeroen Ketelaar
2019-05-08 15:11:57 -05:00
committed by GitHub
32 changed files with 593 additions and 131 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ env:
- secure: UG+b1tEgc8xv9x4r//2OAIK1RrYv6n209KTTFMMwcnAa7DI8HaP8nljRa5/VhDhuKHdlVrYH/tI90v7UVBs0GDVNwK5V17Io0fMm3FUGZekSthTCqqno5wAGa9r6a6mMLtSaSmIFeIKi0+0d2ZwplRuhj/dtEYjjBBj+kK8g4nE= - secure: UG+b1tEgc8xv9x4r//2OAIK1RrYv6n209KTTFMMwcnAa7DI8HaP8nljRa5/VhDhuKHdlVrYH/tI90v7UVBs0GDVNwK5V17Io0fMm3FUGZekSthTCqqno5wAGa9r6a6mMLtSaSmIFeIKi0+0d2ZwplRuhj/dtEYjjBBj+kK8g4nE=
- secure: St/fecUDInFBCRriYqgp2F8PU9/SooorgxD9Mrs+b0EsC7AbtSsQXvdIv2Lp6xzdQ0VSXPcLIhULPOYrmBKnGQ/NjXTIZXxnroyQxxnI6xyEWIZwiHRY/bKRJDRbQTxD9NL32szKiDSwnw7pu6llF4D64UqQvziq4Gm6VohU75M= - secure: St/fecUDInFBCRriYqgp2F8PU9/SooorgxD9Mrs+b0EsC7AbtSsQXvdIv2Lp6xzdQ0VSXPcLIhULPOYrmBKnGQ/NjXTIZXxnroyQxxnI6xyEWIZwiHRY/bKRJDRbQTxD9NL32szKiDSwnw7pu6llF4D64UqQvziq4Gm6VohU75M=
- secure: bD15GVZWowiknbfLavh8CxSh0GsnF5kT4kZ6ggCuUDGyj0mzqf7dNRnchQIKkCG0WRYyTrFN4pEiygeywWsipEeAVv9Xhx3cuUZmzeQaR5KCWabSwJ8gK6jZd1YhcWmM9vrdPHobZr65MP0y/8mu/Fovgky9dY7KDf4G3SebNrM= - secure: bD15GVZWowiknbfLavh8CxSh0GsnF5kT4kZ6ggCuUDGyj0mzqf7dNRnchQIKkCG0WRYyTrFN4pEiygeywWsipEeAVv9Xhx3cuUZmzeQaR5KCWabSwJ8gK6jZd1YhcWmM9vrdPHobZr65MP0y/8mu/Fovgky9dY7KDf4G3SebNrM=
- PARABOT_VERSION=2.7 - PARABOT_VERSION=2.8
cache: cache:
directories: directories:
+1 -1
View File
@@ -3,7 +3,7 @@
# Parabot # Parabot
Parabot V2.7 Parabot V2.8
#### Links #### Links
+2 -2
View File
@@ -6,7 +6,7 @@
<groupId>org.parabot</groupId> <groupId>org.parabot</groupId>
<artifactId>client</artifactId> <artifactId>client</artifactId>
<version>2.7</version> <version>2.8</version>
<packaging>jar</packaging> <packaging>jar</packaging>
@@ -73,7 +73,7 @@
<dependency> <dependency>
<groupId>org.parabot</groupId> <groupId>org.parabot</groupId>
<artifactId>internal-api</artifactId> <artifactId>internal-api</artifactId>
<version>1.52.1</version> <version>1.53.1</version>
</dependency> </dependency>
</dependencies> </dependencies>
+15
View File
@@ -1,6 +1,7 @@
package org.parabot; package org.parabot;
import org.parabot.api.translations.TranslationHelper; import org.parabot.api.translations.TranslationHelper;
import org.parabot.core.Context;
import org.parabot.core.Core; import org.parabot.core.Core;
import org.parabot.core.Directories; import org.parabot.core.Directories;
import org.parabot.core.forum.AccountManager; import org.parabot.core.forum.AccountManager;
@@ -9,6 +10,7 @@ import org.parabot.core.network.proxy.ProxySocket;
import org.parabot.core.network.proxy.ProxyType; import org.parabot.core.network.proxy.ProxyType;
import org.parabot.core.ui.BotUI; import org.parabot.core.ui.BotUI;
import org.parabot.core.ui.ServerSelector; import org.parabot.core.ui.ServerSelector;
import org.parabot.core.ui.utils.UILog;
import javax.swing.*; import javax.swing.*;
import java.io.File; import java.io.File;
@@ -27,6 +29,16 @@ public final class Landing {
public static void main(String... args) throws IOException { public static void main(String... args) throws IOException {
if (Context.getJavaVersion() >= 9) {
UILog.log("Parabot", "Parabot doesn't support Java 9+ currently. Please downgrade to Java 8 to ensure Parabot is working correctly.");
System.exit(0);
}
if (!System.getProperty("os.arch").contains("64")) {
UILog.log("Parabot", "You are not running a 64-bit version of Java, this might cause the client to lag or crash unexpectedly.\r\n" +
"It's recommended to upgrade to a 64-bit version.");
}
parseArgs(args); parseArgs(args);
Directories.validate(); Directories.validate();
@@ -139,6 +151,9 @@ public final class Landing {
case "-uuid": case "-uuid":
Core.setQuickLaunchByUuid(Integer.parseInt(args[++i])); Core.setQuickLaunchByUuid(Integer.parseInt(args[++i]));
break; break;
default:
System.err.println(String.format("Unknown argument given: %s", arg.toLowerCase()));
break;
} }
} }
} }
@@ -11,17 +11,21 @@ public class Configuration extends org.parabot.api.Configuration {
public static final String LOGIN_SERVER = "http://bdn.parabot.org/api/v2/users/login"; 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_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_SCRIPT = "http://bdn.parabot.org/api/get.php?action=scripts_script&id=";
public static final String GET_SERVER_PROVIDER_TYPE = "http://v3.bdn.parabot.org/api/bot/server/type?server=%s";
public static final String GET_SERVER_PROVIDERS = "http://bdn.parabot.org/api/get.php?action=server_providers"; 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://v3.bdn.parabot.org/api/bot/download/provider?nightly=%s&server=%s"; public static final String GET_SERVER_PROVIDER = "http://v3.bdn.parabot.org/api/bot/download/provider?nightly=%s&server=%s";
public static final String SERVER_PROVIDER_INFO = "http://v3.bdn.parabot.org/api/bot/list/%s?latest=true";
public static final String GET_SERVER_PROVIDER_INFO = "http://bdn.parabot.org/api/get.php?action=server_information&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_SERVER_SETTINGS = "http://bdn.parabot.org/api/get.php?action=get_settings"; public static final String GET_SERVER_SETTINGS = "http://bdn.parabot.org/api/get.php?action=get_settings";
public static final String GET_BOT_VERSION = "http://bdn.parabot.org/api/v2/bot/version"; public static final String GET_BOT_VERSION = "http://bdn.parabot.org/api/v2/bot/version";
public static final String API_DOWNLOAD_BOT = "http://v3.bdn.parabot.org/api/bot/download/client"; public static final String API_DOWNLOAD_BOT = "http://v3.bdn.parabot.org/api/bot/download/client";
public static final String DOWNLOAD_BOT = "http://bdn.parabot.org/versions/"; public static final String DOWNLOAD_BOT = "http://bdn.parabot.org/versions/";
public static final String REGISTRATION_PAGE = "https://www.parabot.org/community/register/";
public static final String GET_RANDOMS = "http://v3.bdn.parabot.org/api/bot/download/randoms"; public static final String GET_RANDOMS = "http://v3.bdn.parabot.org/api/bot/download/randoms";
public static final String DATA_API = "http://bdn.parabot.org/api/v2/data/"; 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 ITEM_API = DATA_API + "items/";
public static final Version BOT_VERSION = ProjectProperties.getProjectVersion(); public static final Version BOT_VERSION = ProjectProperties.getProjectVersion();
public static final String COMMUNITY_PAGE = "https://www.parabot.org/community/";
public static final String REGISTRATION_PAGE = COMMUNITY_PAGE + "register/";
} }
@@ -70,6 +70,13 @@ public class Context {
this.defaultErr = System.err; this.defaultErr = System.err;
} }
public static double getJavaVersion() {
String version = System.getProperty("java.version");
int pos = version.indexOf('.');
pos = version.indexOf('.', pos + 1);
return Double.parseDouble(version.substring(0, pos));
}
/** /**
* Returns the instance of this class, based on a given ServerProvider * Returns the instance of this class, based on a given ServerProvider
* *
@@ -1,24 +1,29 @@
package org.parabot.core.asm.hooks; package org.parabot.core.asm.hooks;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.parsers.hooks.HookParser; import org.parabot.core.parsers.hooks.HookParser;
import org.parabot.core.parsers.hooks.JSONHookParser; import org.parabot.core.parsers.hooks.JSONHookParser;
import org.parabot.core.parsers.hooks.XMLHookParser; import org.parabot.core.parsers.hooks.XMLHookParser;
import org.parabot.environment.api.utils.WebUtil; import org.parabot.environment.api.utils.WebUtil;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
public class HookFile { public class HookFile {
public static final int TYPE_XML = 0; public static final int TYPE_XML = 0;
public static final int TYPE_JSON = 1; public static final int TYPE_JSON = 1;
private URL url; private URL url;
private int type; private int type;
private boolean isLocal;
public HookFile(File file, int type) throws MalformedURLException { public HookFile(File file, int type) throws MalformedURLException {
this(file.toURI().toURL(), type); this(file.toURI().toURL(), type);
this.isLocal = true;
} }
public HookFile(URL url, int type) { public HookFile(URL url, int type) {
@@ -26,17 +31,22 @@ public class HookFile {
this.url = url; 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() { public InputStream getInputStream() {
return WebUtil.getInputStream(url); return WebUtil.getInputStream(url);
} }
public InputStream getInputStream(AccountManager manager) {
if (isLocal) {
return this.getInputStream();
} else {
try {
return WebUtil.getConnection(url, "apikey=" + manager.getAccount().getApi()).getInputStream();
} catch (IOException e) {
return null;
}
}
}
public HookParser getParser() { public HookParser getParser() {
switch (type) { switch (type) {
case TYPE_XML: case TYPE_XML:
@@ -47,4 +57,11 @@ public class HookFile {
return null; return null;
} }
private void setType(int type) {
if (type < 0 || type > 1) {
throw new IllegalArgumentException("This type does not exist");
}
this.type = type;
}
} }
@@ -7,6 +7,7 @@ import org.parabot.environment.scripts.Script;
import java.io.InputStream; import java.io.InputStream;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.net.URL;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
@@ -58,6 +59,15 @@ public class ClassRedirect {
return Class.forName(name); return Class.forName(name);
} }
public static URL getResource(Class<?> c, String path) {
if(validStack() || validRequest(c)) {
return c.getResource(path);
}
System.err.println(c.getName() + "#getResource(" + path + ") Blocked.");
throw RedirectClassAdapter.createSecurityException();
}
public static ClassLoader getClassLoader(Class<?> c) { public static ClassLoader getClassLoader(Class<?> c) {
System.err.println(c.getName() + "#getClassLoader()" + " Blocked."); System.err.println(c.getName() + "#getClassLoader()" + " Blocked.");
throw RedirectClassAdapter.createSecurityException(); throw RedirectClassAdapter.createSecurityException();
@@ -31,7 +31,7 @@ public class RuntimeRedirect {
if (s.contains("ping")) { if (s.contains("ping")) {
System.out.println("Faked attempted command: " + s); System.out.println("Faked attempted command: " + s);
try { try {
return r.exec("ping 127.0.0.1"); return r.exec("ping 8.8.8.8");
} catch (IOException e) { } catch (IOException e) {
throw RedirectClassAdapter.createSecurityException(); throw RedirectClassAdapter.createSecurityException();
} }
@@ -61,4 +61,12 @@ public class ThreadRedirect {
public static void setUncaughtExceptionHandler(Thread t, Thread.UncaughtExceptionHandler handler) { public static void setUncaughtExceptionHandler(Thread t, Thread.UncaughtExceptionHandler handler) {
t.setUncaughtExceptionHandler(handler); t.setUncaughtExceptionHandler(handler);
} }
public static boolean isInterrupted(Thread thread) {
return thread.isInterrupted();
}
public static long getId(Thread thread) {
return thread.getId();
}
} }
@@ -49,4 +49,19 @@ public class Callback implements Injectable {
this.invokeMethod, this.desc, this.args, this.conditional); this.invokeMethod, this.desc, this.args, this.conditional);
} }
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Injectable type: Callback");
if(method != null) {
sb.append(", intercepts method: ").append(method.name);
}
sb.append(", calls class: ").append(invokeClass)
.append(", calls method: ").append(invokeMethod);
return sb.toString();
}
} }
@@ -38,7 +38,7 @@ public class Getter implements Injectable {
this.fieldLocation = ASMUtils.getClass(fieldLocation); this.fieldLocation = ASMUtils.getClass(fieldLocation);
this.fieldNode = ASMUtils.getField(ASMUtils.getClass(fieldLocation), fieldNode, fieldDesc); this.fieldNode = ASMUtils.getField(ASMUtils.getClass(fieldLocation), fieldNode, fieldDesc);
this.methodName = methodName; this.methodName = methodName;
this.returnDesc = returnDesc == null ? this.fieldNode.desc : returnDesc; this.returnDesc = (returnDesc == null && this.fieldNode != null) ? this.fieldNode.desc : returnDesc;
this.staticMethod = staticMethod; this.staticMethod = staticMethod;
this.multiplier = multiplier; this.multiplier = multiplier;
Core.verbose(methodName + "[" + fieldLocation + "." + fieldNode + "]"); Core.verbose(methodName + "[" + fieldLocation + "." + fieldNode + "]");
@@ -77,4 +77,21 @@ public class Getter implements Injectable {
return new AddGetterAdapter(into, fieldLocation, fieldNode, methodName, returnDesc, staticMethod, multiplier); return new AddGetterAdapter(into, fieldLocation, fieldNode, methodName, returnDesc, staticMethod, multiplier);
} }
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Injectable type: Getter");
if(fieldLocation.interfaces.size() > 0) {
sb.append(", accessor type: ").append(fieldLocation.interfaces.get(0).toString().replace('/', '.'));
}
if(fieldNode != null) {
sb.append(", field: ").append(fieldNode.name);
}
sb.append(", method name: ").append(methodName);
return sb.toString();
}
} }
@@ -79,4 +79,8 @@ public class Invoker implements Injectable {
this.argsDesc, this.returnDesc, this.methodName, this.isInterface, this.instanceCast, this.argsCheckCastDesc); this.argsDesc, this.returnDesc, this.methodName, this.isInterface, this.instanceCast, this.argsCheckCastDesc);
} }
@Override
public String toString() {
return String.format("Injectable type: Invoker, accessor: %s, method name: %s, invokes method: %s", methodLocation.name, methodName, mName);
}
} }
@@ -25,7 +25,7 @@ public class Setter implements Injectable {
this.into = ASMUtils.getClass(into); this.into = ASMUtils.getClass(into);
this.field = ASMUtils.getField(this.fieldLocation, fieldName, fieldDesc); this.field = ASMUtils.getField(this.fieldLocation, fieldName, fieldDesc);
this.name = methodName; this.name = methodName;
this.desc = (desc == null) ? this.field.desc : desc; this.desc = (desc == null && this.field != null) ? this.field.desc : desc;
this.methodStatic = methodStatic; this.methodStatic = methodStatic;
} }
@@ -52,4 +52,21 @@ public class Setter implements Injectable {
return new AddSetterAdapter(fieldLocation, into, field, name, desc, methodStatic); return new AddSetterAdapter(fieldLocation, into, field, name, desc, methodStatic);
} }
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Injectable type: Setter");
if(fieldLocation.interfaces.size() > 0) {
sb.append(", accessor type: ").append(fieldLocation.interfaces.get(0).toString().replace('/', '.'));
}
if(field != null) {
sb.append(", field: ").append(field.name);
}
sb.append(", method name: ").append(name);
return sb.toString();
}
} }
@@ -166,6 +166,7 @@ public class ServerProviderInfo {
/** /**
* Gets the URL to download the Randoms JAR from. * Gets the URL to download the Randoms JAR from.
*
* @return The provided URL in the server config JSON (denoted by 'randoms:') or, fallback to the default BDN URL. * @return The provided URL in the server config JSON (denoted by 'randoms:') or, fallback to the default BDN URL.
*/ */
public URL getRandoms() { public URL getRandoms() {
@@ -182,4 +183,19 @@ public class ServerProviderInfo {
// Will never return null, unless the BDN URL is changed. It shouldn't be. // Will never return null, unless the BDN URL is changed. It shouldn't be.
return null; return null;
} }
/**
* Gets the current provider version
*
* @return provider version
*/
public String getProviderVersion() {
String providerType = WebUtil.getJsonValue(String.format(Configuration.GET_SERVER_PROVIDER_TYPE , properties.getProperty("name")), "type");
if(providerType != null) {
String providerInfo = String.format(Configuration.SERVER_PROVIDER_INFO, providerType);
return WebUtil.getJsonValue(providerInfo, "version");
}
return null;
}
} }
@@ -4,6 +4,7 @@ import org.json.simple.JSONObject;
import org.parabot.core.Configuration; import org.parabot.core.Configuration;
import org.parabot.core.Context; import org.parabot.core.Context;
import org.parabot.core.Core; import org.parabot.core.Core;
import org.parabot.core.parsers.hooks.HookParser;
import org.parabot.core.parsers.scripts.BDNScripts; import org.parabot.core.parsers.scripts.BDNScripts;
import org.parabot.core.parsers.servers.PublicServers; import org.parabot.core.parsers.servers.PublicServers;
import org.parabot.core.ui.components.VerboseLoader; import org.parabot.core.ui.components.VerboseLoader;
@@ -48,6 +49,7 @@ public final class AccountManager {
accessors.add(PublicServers.MANAGER_FETCHER); accessors.add(PublicServers.MANAGER_FETCHER);
accessors.add(PublicServerExecuter.MANAGER_FETCHER); accessors.add(PublicServerExecuter.MANAGER_FETCHER);
accessors.add(PBPreferences.MANAGER_FETCHER); accessors.add(PBPreferences.MANAGER_FETCHER);
accessors.add(HookParser.MANAGER_FETCHER);
for (final AccountManagerAccess accessor : accessors) { for (final AccountManagerAccess accessor : accessors) {
accessor.setManager(instance); accessor.setManager(instance);
@@ -1,5 +1,6 @@
package org.parabot.core.network.proxy; package org.parabot.core.network.proxy;
import org.parabot.core.Core;
import org.parabot.core.ui.utils.UILog; import org.parabot.core.ui.utils.UILog;
import javax.swing.*; import javax.swing.*;
@@ -44,7 +45,7 @@ public class ProxySocket extends Socket {
socket.close(); socket.close();
value++; value++;
} catch (Exception e) { } catch (Exception e) {
Core.verbose("Error closing proxy connection: " + e.getMessage());
} }
} }
return value; return value;
@@ -3,25 +3,39 @@ package org.parabot.core.parsers.hooks;
import org.parabot.core.asm.hooks.HookFile; import org.parabot.core.asm.hooks.HookFile;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
import org.parabot.core.asm.wrappers.*; import org.parabot.core.asm.wrappers.*;
import org.parabot.core.forum.AccountManager;
import org.parabot.core.forum.AccountManagerAccess;
import org.parabot.environment.api.utils.PBPreferences;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
/** /**
* Parses an XML files which injects the hooks and other bytecode manipulation * Parses a structured format file which injects the hooks and other bytecode manipulation
* methods * methods
* *
* @author Everel * @author Everel, JKetelaar
*/ */
public abstract class HookParser { public abstract class HookParser {
protected static AccountManager manager;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override
public final void setManager(AccountManager manager) {
HookParser.manager = manager;
}
};
public HookParser(HookFile hookFile) { public HookParser(HookFile hookFile) {
} }
public abstract Interface[] getInterfaces(); public abstract Interface[] getInterfaces();
public abstract Map<String, String> getInterfaceMap();
public abstract Super[] getSupers(); public abstract Super[] getSupers();
public abstract Getter[] getGetters(); public abstract Getter[] getGetters();
@@ -12,7 +12,10 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author Dane * Parses a JSON file which injects the hooks and other bytecode manipulation
* methods
*
* @author Dane, JKetelaar
*/ */
public class JSONHookParser extends HookParser { public class JSONHookParser extends HookParser {
private JSONObject root; private JSONObject root;
@@ -71,6 +74,11 @@ public class JSONHookParser extends HookParser {
return null; return null;
} }
@Override
public Map<String, String> getInterfaceMap() {
return this.interfaces;
}
@Override @Override
public Super[] getSupers() { public Super[] getSupers() {
JSONArray a = (JSONArray) root.get("supers"); JSONArray a = (JSONArray) root.get("supers");
@@ -13,22 +13,29 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
/**
* Parses an XML file which injects the hooks and other bytecode manipulation
* methods
*
* @author JKetelaar
*/
public class XMLHookParser extends HookParser { public class XMLHookParser extends HookParser {
private Document doc; private Document doc;
private HashMap<String, String> interfaceMap; private HashMap<String, String> interfaceMap;
private HashMap<String, String> constants; private HashMap<String, String> constants;
private boolean parsedInterfaces; private boolean parsedInterfaces;
public XMLHookParser(HookFile hookFile) { public XMLHookParser(HookFile hookFile) {
super(hookFile); super(hookFile);
interfaceMap = new HashMap<String, String>(); interfaceMap = new HashMap<>();
constants = new HashMap<String, String>(); constants = new HashMap<>();
try { try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance(); .newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(hookFile.getInputStream()); doc = dBuilder.parse(hookFile.getInputStream(manager));
doc.getDocumentElement().normalize(); doc.getDocumentElement().normalize();
if (!doc.getDocumentElement().getNodeName().equals("injector")) { if (!doc.getDocumentElement().getNodeName().equals("injector")) {
throw new RuntimeException("Incorrect hook file."); throw new RuntimeException("Incorrect hook file.");
@@ -38,48 +45,6 @@ public class XMLHookParser extends HookParser {
} }
} }
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) {
if (element.getElementsByTagName(tag).item(0) == null) {
throw new NullPointerException("MISSING HOOK TAG: The '" + tag + "' xml tag is missing from one of the hooks of type: " + element.getParentNode().getNodeName());
}
NodeList nodes = element.getElementsByTagName(tag).item(0)
.getChildNodes();
if (nodes.getLength() == 0 || nodes.item(0) == null) {
if (Core.inVerboseMode()) {
System.err.println("WARNING: Invalid Hook " + tag + " subnode. Tag is missing or empty?");
}
return "";
}
Node node = (Node) nodes.item(0);
return node.getNodeValue();
}
@Override @Override
public Interface[] getInterfaces() { public Interface[] getInterfaces() {
parsedInterfaces = true; parsedInterfaces = true;
@@ -98,8 +63,8 @@ public class XMLHookParser extends HookParser {
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element interfaceRoot = (Element) node; final Element interfaceRoot = (Element) node;
final NodeList interfaces = interfaceRoot.getElementsByTagName("add"); final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
if (interfaces.getLength() == 0) { if (interfaces.getLength() == 0) {
return null; return null;
} }
@@ -109,9 +74,9 @@ public class XMLHookParser extends HookParser {
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addInterface = (Element) n; final Element addInterface = (Element) n;
final String className = getValue("classname", addInterface); final String className = getValue("classname", addInterface);
final String interfaceClass = getValue("interface", addInterface); final String interfaceClass = getValue("interface", addInterface);
interfaceMap.put(interfaceClass, className); interfaceMap.put(interfaceClass, className);
final Interface inf = new Interface(className, interfaceClass); final Interface inf = new Interface(className, interfaceClass);
interfaceList.add(inf); interfaceList.add(inf);
@@ -119,6 +84,11 @@ public class XMLHookParser extends HookParser {
return interfaceList.toArray(new Interface[interfaceList.size()]); return interfaceList.toArray(new Interface[interfaceList.size()]);
} }
@Override
public Map<String, String> getInterfaceMap() {
return this.interfaceMap;
}
@Override @Override
public Super[] getSupers() { public Super[] getSupers() {
final NodeList interfaceRootList = doc.getElementsByTagName("supers"); final NodeList interfaceRootList = doc.getElementsByTagName("supers");
@@ -135,8 +105,8 @@ public class XMLHookParser extends HookParser {
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element superRoot = (Element) node; final Element superRoot = (Element) node;
final NodeList supers = superRoot.getElementsByTagName("add"); final NodeList supers = superRoot.getElementsByTagName("add");
if (supers.getLength() == 0) { if (supers.getLength() == 0) {
return null; return null;
} }
@@ -146,10 +116,10 @@ public class XMLHookParser extends HookParser {
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addSuper = (Element) n; final Element addSuper = (Element) n;
final String className = getValue("classname", addSuper); final String className = getValue("classname", addSuper);
final String superClass = getValue("super", addSuper); final String superClass = getValue("super", addSuper);
final Super sup = new Super(className, superClass); final Super sup = new Super(className, superClass);
superList.add(sup); superList.add(sup);
} }
return superList.toArray(new Super[superList.size()]); return superList.toArray(new Super[superList.size()]);
@@ -171,8 +141,8 @@ public class XMLHookParser extends HookParser {
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element getterRoot = (Element) node; final Element getterRoot = (Element) node;
final NodeList getters = getterRoot.getElementsByTagName("add"); final NodeList getters = getterRoot.getElementsByTagName("add");
if (getters.getLength() == 0) { if (getters.getLength() == 0) {
return null; return null;
} }
@@ -196,9 +166,9 @@ public class XMLHookParser extends HookParser {
"accessor", addGetter)); "accessor", addGetter));
final String into = isSet("into", addGetter) ? getValue("into", final String into = isSet("into", addGetter) ? getValue("into",
addGetter) : className; addGetter) : className;
final long multiplier = isSet("multiplier", addGetter) ? Long.parseLong(getValue("multiplier", addGetter)) : 0L; final long multiplier = isSet("multiplier", addGetter) ? Long.parseLong(getValue("multiplier", addGetter)) : 0L;
final String fieldName = getValue("field", addGetter); final String fieldName = getValue("field", addGetter);
final String fieldDesc = isSet("descfield", addGetter) ? getValue("descfield", addGetter) : null; final String fieldDesc = isSet("descfield", addGetter) ? getValue("descfield", addGetter) : null;
final String methodName = getValue("methodname", addGetter); final String methodName = getValue("methodname", addGetter);
boolean staticMethod = isSet("methstatic", addGetter) ? (getValue( boolean staticMethod = isSet("methstatic", addGetter) ? (getValue(
"methstatic", addGetter).equals("true")) : false; "methstatic", addGetter).equals("true")) : false;
@@ -246,8 +216,8 @@ public class XMLHookParser extends HookParser {
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element setterRoot = (Element) node; final Element setterRoot = (Element) node;
final NodeList setters = setterRoot.getElementsByTagName("add"); final NodeList setters = setterRoot.getElementsByTagName("add");
if (setters.getLength() == 0) { if (setters.getLength() == 0) {
return null; return null;
} }
@@ -271,8 +241,8 @@ public class XMLHookParser extends HookParser {
"accessor", addSetter)); "accessor", addSetter));
final String into = isSet("into", addSetter) ? getValue("into", final String into = isSet("into", addSetter) ? getValue("into",
addSetter) : className; addSetter) : className;
final String fieldName = getValue("field", addSetter); final String fieldName = getValue("field", addSetter);
final String fieldDesc = isSet("descfield", addSetter) ? getValue("descfield", addSetter) : null; final String fieldDesc = isSet("descfield", addSetter) ? getValue("descfield", addSetter) : null;
final String methodName = getValue("methodname", addSetter); final String methodName = getValue("methodname", addSetter);
boolean staticMethod = isSet("methstatic", addSetter) ? (getValue( boolean staticMethod = isSet("methstatic", addSetter) ? (getValue(
"methstatic", addSetter).equals("true")) : false; "methstatic", addSetter).equals("true")) : false;
@@ -319,8 +289,8 @@ public class XMLHookParser extends HookParser {
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element invokerRoot = (Element) node; final Element invokerRoot = (Element) node;
final NodeList invokers = invokerRoot.getElementsByTagName("add"); final NodeList invokers = invokerRoot.getElementsByTagName("add");
if (invokers.getLength() == 0) { if (invokers.getLength() == 0) {
return null; return null;
} }
@@ -344,15 +314,15 @@ public class XMLHookParser extends HookParser {
"accessor", addInvoker)); "accessor", addInvoker));
final String into = isSet("into", addInvoker) ? getValue("into", final String into = isSet("into", addInvoker) ? getValue("into",
addInvoker) : className; addInvoker) : className;
final String methodName = getValue("methodname", addInvoker); final String methodName = getValue("methodname", addInvoker);
final String invMethodName = getValue("invokemethod", addInvoker); final String invMethodName = getValue("invokemethod", addInvoker);
final String argsDesc = getValue("argsdesc", addInvoker); final String argsDesc = getValue("argsdesc", addInvoker);
String returnDesc = isSet("desc", addInvoker) ? resolveDesc(getValue( String returnDesc = isSet("desc", addInvoker) ? resolveDesc(getValue(
"desc", addInvoker)) : null; "desc", addInvoker)) : null;
final boolean isInterface = isSet("interface", addInvoker) ? Boolean.parseBoolean(getValue("interface", addInvoker)) : false; final boolean isInterface = isSet("interface", addInvoker) ? Boolean.parseBoolean(getValue("interface", addInvoker)) : false;
final String instanceCast = isSet("instancecast", addInvoker) ? getValue("instancecast", addInvoker) : null; final String instanceCast = isSet("instancecast", addInvoker) ? getValue("instancecast", addInvoker) : null;
final String checkCastArgsDesc = isSet("castargs", addInvoker) ? getValue("castargs", addInvoker) : null; final String checkCastArgsDesc = isSet("castargs", addInvoker) ? getValue("castargs", addInvoker) : null;
final Invoker invoker = new Invoker(into, className, invMethodName, final Invoker invoker = new Invoker(into, className, invMethodName,
argsDesc, returnDesc, methodName, isInterface, instanceCast, checkCastArgsDesc); argsDesc, returnDesc, methodName, isInterface, instanceCast, checkCastArgsDesc);
@@ -381,7 +351,7 @@ public class XMLHookParser extends HookParser {
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element constantRoot = (Element) node; final Element constantRoot = (Element) node;
final NodeList constantsList = constantRoot.getElementsByTagName("add"); final NodeList constantsList = constantRoot.getElementsByTagName("add");
if (constantsList.getLength() == 0) { if (constantsList.getLength() == 0) {
// return empty hashmap // return empty hashmap
@@ -393,8 +363,8 @@ public class XMLHookParser extends HookParser {
continue; continue;
} }
final Element addConstant = (Element) n; final Element addConstant = (Element) n;
final String key = getValue("key", addConstant); final String key = getValue("key", addConstant);
final String value = getValue("value", addConstant); final String value = getValue("value", addConstant);
constants.put(key, value); constants.put(key, value);
} }
return constants; return constants;
@@ -416,8 +386,8 @@ public class XMLHookParser extends HookParser {
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element callbackRoot = (Element) node; final Element callbackRoot = (Element) node;
final NodeList callbacks = callbackRoot.getElementsByTagName("add"); final NodeList callbacks = callbackRoot.getElementsByTagName("add");
if (callbacks.getLength() == 0) { if (callbacks.getLength() == 0) {
return null; return null;
} }
@@ -441,12 +411,12 @@ public class XMLHookParser extends HookParser {
"classname", addCallback) : interfaceMap.get(getValue( "classname", addCallback) : interfaceMap.get(getValue(
"accessor", addCallback)); "accessor", addCallback));
final String methodName = getValue("methodname", addCallback); final String methodName = getValue("methodname", addCallback);
final String callClass = getValue("callclass", addCallback); final String callClass = getValue("callclass", addCallback);
final String callMethod = getValue("callmethod", addCallback); final String callMethod = getValue("callmethod", addCallback);
final String callDesc = getValue("calldesc", addCallback); final String callDesc = getValue("calldesc", addCallback);
final String callArgs = getValue("callargs", addCallback); final String callArgs = getValue("callargs", addCallback);
final String desc = getValue("desc", addCallback); final String desc = getValue("desc", addCallback);
final boolean conditional = isSet("conditional", addCallback); final boolean conditional = isSet("conditional", addCallback);
final Callback callback = new Callback(className, methodName, desc, final Callback callback = new Callback(className, methodName, desc,
@@ -456,4 +426,46 @@ public class XMLHookParser extends HookParser {
return callbackList.toArray(new Callback[callbackList.size()]); return callbackList.toArray(new Callback[callbackList.size()]);
} }
private static String resolveDesc(String returnDesc) {
String array = "";
if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder();
if (returnDesc.startsWith("[")) {
for (int i = 0; i < returnDesc.length(); i++) {
if (returnDesc.charAt(i) == '[') {
array += '[';
}
}
returnDesc = returnDesc.replaceAll("\\[", "");
}
str.append(array)
.append('L')
.append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage()))
.append(";");
returnDesc = str.toString();
}
return returnDesc;
}
private static final boolean isSet(String tag, Element element) {
return element.getElementsByTagName(tag).getLength() > 0;
}
private static final String getValue(String tag, Element element) {
if (element.getElementsByTagName(tag).item(0) == null) {
throw new NullPointerException("MISSING HOOK TAG: The '" + tag + "' xml tag is missing from one of the hooks of type: " + element.getParentNode().getNodeName());
}
NodeList nodes = element.getElementsByTagName(tag).item(0)
.getChildNodes();
if (nodes.getLength() == 0 || nodes.item(0) == null) {
if (Core.inVerboseMode()) {
System.err.println("WARNING: Invalid Hook " + tag + " subnode. Tag is missing or empty?");
}
return "";
}
Node node = (Node) nodes.item(0);
return node.getNodeValue();
}
} }
+1 -2
View File
@@ -1,6 +1,5 @@
package org.parabot.core.ui; package org.parabot.core.ui;
import javafx.application.Application;
import org.parabot.core.Configuration; import org.parabot.core.Configuration;
import org.parabot.core.Context; import org.parabot.core.Context;
import org.parabot.core.Directories; import org.parabot.core.Directories;
@@ -248,7 +247,7 @@ public class BotUI extends JFrame implements ActionListener, ComponentListener,
Directories.clearCache(); Directories.clearCache();
break; break;
case "Notifications": case "Notifications":
Application.launch(NotificationUI.class); NotificationUI.create();
break; break;
default: default:
System.out.println("Invalid command: " + command); System.out.println("Invalid command: " + command);
@@ -1,20 +1,56 @@
package org.parabot.core.ui.components.notifications; package org.parabot.core.ui.components.notifications;
import javafx.application.Application; import org.parabot.api.Configuration;
import javafx.fxml.FXMLLoader; import org.parabot.api.output.Verboser;
import javafx.scene.Scene; import org.parabot.api.ui.JavaFxUtil;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import org.parabot.core.Configuration;
public class NotificationUI extends Application { import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
/**
* A JavaFX Panel embedded into a Swing JFrame - handles notification settings
*
* @author Shadowrs
*/
public class NotificationUI extends JavaFxUtil {
final NotificationUI n;
private NotificationUI() throws URISyntaxException, MalformedURLException {
super(Configuration.class.getClass().getResource("/storage/ui/notifications.fxml").toURI().toURL(), NotificationUIController.class);
this.n = this;
}
public static void create() {
try {
new NotificationUI();
} catch (URISyntaxException | MalformedURLException e) {
e.printStackTrace();
}
}
@Override @Override
public void start(Stage stage) throws Exception { public WindowAdapter getWindowAdapter() {
//noinspection RedundantCast return new WindowAdapter() {
BorderPane root = (BorderPane) FXMLLoader.load(this.getClass().getResource("/storage/ui/notifications.fxml")); @Override
stage.setTitle(Configuration.BOT_TITLE); public void windowClosed(WindowEvent e) {
stage.setScene(new Scene(root)); Verboser.verbose("NotificationUI closed " + e);
stage.show(); }
@Override
public void windowClosing(WindowEvent e) {
// Anything here. JFrame hides on exit.
Verboser.verbose("NotificationUI closing " + e);
n.getFrame().dispose();
}
};
}
@Override
protected void onLaunched() {
n.getFrame().setTitle("Notifications");
} }
} }
@@ -30,4 +30,13 @@ public class UILog {
public static int alert(final String title, final String message, int optionType, int messageType) { public static int alert(final String title, final String message, int optionType, int messageType) {
return JOptionPane.showConfirmDialog(null, message, title, optionType, messageType); return JOptionPane.showConfirmDialog(null, message, title, optionType, messageType);
} }
public static int alert(final String title, final String message, Object[] options) {
return alert(title, message, options, JOptionPane.INFORMATION_MESSAGE);
}
public static int alert(final String title, final String message, Object[] options, int messageType) {
return JOptionPane.showOptionDialog(null, message, title,
JOptionPane.YES_NO_CANCEL_OPTION, messageType, null, options, null);
}
} }
@@ -33,7 +33,7 @@ public class Environment extends org.parabot.api.io.libraries.Environment {
loadLibrary(lib, true); loadLibrary(lib, true);
} }
Core.verbose("Loading server: " + desc.toString() + "..."); Core.verbose("[Environment] Loading server: " + desc.toString() + "...");
ServerParser.SERVER_CACHE.get(desc).run(); ServerParser.SERVER_CACHE.get(desc).run();
} }
@@ -1,10 +1,8 @@
package org.parabot.environment.api.utils; package org.parabot.environment.api.utils;
import java.io.File; import java.io.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@@ -88,4 +86,29 @@ public class FileUtil {
} }
destination.close(); destination.close();
} }
/**
* Reads the contents of a text file
*
* @param file file to get contents from
* @return file contents
* @throws IOException when anything goes wrong
*/
public static String getFileContents(File file) throws IOException {
return new String(Files.readAllBytes(file.toPath()));
}
/**
* Writes a string to a file overwriting the existing contents if present
*
* @param file file to write to
* @param contents contents to write to given file
* @throws IOException when anything goes wrong
*/
public static void writeFileContents(File file, String contents) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(file.getAbsolutePath()));
writer.write(contents);
writer.close();
}
} }
@@ -0,0 +1,118 @@
package org.parabot.environment.api.utils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.parabot.core.Directories;
import java.io.File;
import java.util.HashMap;
/**
* Manages preferences in a local file in JSON format in the Parabot settings folder
*
* @author AlexanderBielen
*/
public class PBLocalPreferences {
private static JSONParser parser = new JSONParser();
private File settingsFile;
public PBLocalPreferences(String fileName) {
settingsFile = new File(Directories.getSettingsPath() + "/" + secureFileName(fileName));
}
/**
* Gets all settings inside the file
*
* @return JSONObject or null if anything went wrong
*/
public JSONObject getSettings() {
try {
String stringContents = FileUtil.getFileContents(settingsFile);
return (JSONObject) parser.parse(stringContents);
} catch(Exception ex) {
return null;
}
}
/**
* Convert a HashMap to json and writes it to the file
*
* @param settings HashMap<String, String>
* @param append If true, append to existing settings in file
*/
public void writeSettings(HashMap<String, String> settings, boolean append) {
JSONObject existingSettings;
if(append && (existingSettings = getSettings()) != null) {
existingSettings.putAll(settings);
settings = existingSettings;
}
try {
if (!settingsFile.exists()) {
settingsFile.createNewFile();
}
FileUtil.writeFileContents(settingsFile, new JSONObject(settings).toJSONString());
} catch (Exception ignore) {
ignore.printStackTrace();
}
}
/**
* Adds a setting, or overwrites it if it exists
*
* @param key key of the setting
* @param value value of the setting
*/
public void addSetting(String key, String value) {
HashMap<String, String> pair = new HashMap<>();
pair.put(key, value);
writeSettings(pair, true);
}
/**
* Fetches a setting
*
* @param key key to get the value for
* @return value that belongs to given key or null if non-existent
*/
public String getSetting(String key) {
if(getSettings() == null) {
return null;
}
return getSettings().get(key).toString();
}
/**
* Adjusts an existing setting
*
* @param key key to adjust the value for
* @param value value for the key
*/
public void adjustSetting(String key, String value) {
addSetting(key, value);
}
/**
* Removes a setting
*
* @param key key to remove
*/
public void removeSetting(String key) {
JSONObject json = getSettings();
json.remove(key);
writeSettings(json, false);
}
/**
* Replaces all double dots to make sure the link does not leave the settings folder
*
* @param filePath path to secure
* @return secured string
*/
private static String secureFileName(String filePath) {
return filePath.replace("..", "");
}
}
@@ -53,6 +53,30 @@ public final class Time {
return true; return true;
} }
/**
* Sleeps until SleepCondition is valid, but with a minimum timeout.
*
* @param conn the condition.
* @param timeout the time in milliseconds before it stops sleeping.
* @param minimumTimeout the minimum time to sleep.
*
* @return whether it ran successfully without timing out.
*/
public static boolean sleep(SleepCondition conn, int timeout, int minimumTimeout) {
long start = System.currentTimeMillis();
if(!sleep(conn, timeout)) {
return false;
}
long t;
if((t = System.currentTimeMillis() - start) < minimumTimeout) {
Time.sleep((int)(minimumTimeout - t));
}
return true;
}
/** /**
* Gets current time in milliseconds * Gets current time in milliseconds
* *
@@ -105,7 +105,18 @@ public class Timer {
* @return hourly gains * @return hourly gains
*/ */
public int getPerHour(final int gained) { public int getPerHour(final int gained) {
return (int) ((gained) * 3600000D / (System.currentTimeMillis() - start)); return getPerHour(gained, 0);
}
/**
* Calculates hourly gains based on given variable, with variable start amount
*
* @param gained total gained amount
* @param startAmount start amount
* @return hourly gains
*/
public int getPerHour(final int gained, final int startAmount) {
return (int) (((gained - startAmount) * 3600000D) / (System.currentTimeMillis() - start));
} }
/** /**
@@ -1,5 +1,7 @@
package org.parabot.environment.api.utils; package org.parabot.environment.api.utils;
import org.json.simple.JSONObject;
/** /**
* A WebUtil class fetches data from an URL * A WebUtil class fetches data from an URL
* *
@@ -7,4 +9,27 @@ package org.parabot.environment.api.utils;
*/ */
public class WebUtil extends org.parabot.api.io.WebUtil { public class WebUtil extends org.parabot.api.io.WebUtil {
/**
* Fetches a single value from a JSON string at the given url
*
* @param url url to get the JSON string from
* @param key key to search for in the JSON string
* @return value that belongs to given key
*/
public static String getJsonValue(String url, String key) {
try {
String response = WebUtil.getContents(url);
if(response.length() > 0) {
JSONObject jsonObject = (JSONObject) WebUtil.getJsonParser().parse(response);
if (jsonObject.get(key) != null) {
return jsonObject.get(key).toString();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
} }
@@ -1,10 +1,12 @@
package org.parabot.environment.servers; package org.parabot.environment.servers;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.parabot.core.Configuration;
import org.parabot.core.Context; import org.parabot.core.Context;
import org.parabot.core.asm.hooks.HookFile; import org.parabot.core.asm.hooks.HookFile;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
import org.parabot.core.parsers.hooks.HookParser; import org.parabot.core.parsers.hooks.HookParser;
import org.parabot.core.ui.utils.UILog;
import org.parabot.environment.input.Keyboard; import org.parabot.environment.input.Keyboard;
import org.parabot.environment.input.Mouse; import org.parabot.environment.input.Mouse;
import org.parabot.environment.scripts.Script; import org.parabot.environment.scripts.Script;
@@ -13,6 +15,8 @@ import javax.swing.*;
import java.applet.Applet; import java.applet.Applet;
import java.applet.AppletStub; import java.applet.AppletStub;
import java.awt.*; import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URL; import java.net.URL;
/** /**
@@ -21,6 +25,7 @@ import java.net.URL;
* @author Everel * @author Everel
*/ */
public abstract class ServerProvider implements Opcodes { public abstract class ServerProvider implements Opcodes {
private boolean crashed = false;
/** /**
* Get the game/applet dimensions * Get the game/applet dimensions
@@ -74,12 +79,36 @@ public abstract class ServerProvider implements Opcodes {
HookParser parser = hookFile.getParser(); HookParser parser = hookFile.getParser();
Injectable[] injectables = parser.getInjectables(); Injectable[] injectables = parser.getInjectables();
if (injectables == null) { if (injectables == null) {
return; return;
} }
for (Injectable inj : injectables) {
inj.inject(); int index = 0;
try {
for (Injectable inj : injectables) {
inj.inject();
index++;
}
} catch (NullPointerException ex) {
if(!crashed) {
Injectable inj = injectables[index];
int resp = UILog.alert("Outdated client", "This server currently has outdated hooks, please report it to a member of the Parabot staff.\r\n\r\n" +
"Broken hook:\r\n"+inj, new Object[]{"Close", "Report here..."}, JOptionPane.ERROR_MESSAGE);
if(resp == 1) {
URI uri = URI.create(Configuration.COMMUNITY_PAGE + "forum/135-reports/");
try {
Desktop.getDesktop().browse(uri);
} catch (IOException ignore) {}
}
}
crashed = true;
throw ex;
} }
Context.getInstance().setHookParser(parser); Context.getInstance().setHookParser(parser);
} }
@@ -11,6 +11,7 @@ import org.parabot.core.forum.AccountManager;
import org.parabot.core.forum.AccountManagerAccess; import org.parabot.core.forum.AccountManagerAccess;
import org.parabot.core.ui.components.VerboseLoader; import org.parabot.core.ui.components.VerboseLoader;
import org.parabot.core.ui.utils.UILog; import org.parabot.core.ui.utils.UILog;
import org.parabot.environment.api.utils.PBLocalPreferences;
import org.parabot.environment.api.utils.WebUtil; import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.servers.ServerProvider; import org.parabot.environment.servers.ServerProvider;
import org.parabot.environment.servers.loader.ServerLoader; import org.parabot.environment.servers.loader.ServerLoader;
@@ -37,6 +38,9 @@ public class PublicServerExecuter extends ServerExecuter {
}; };
private String serverName; private String serverName;
private PBLocalPreferences settings;
private final String cacheVersionKey = "cachedProviderVersion";
public PublicServerExecuter(final String serverName) { public PublicServerExecuter(final String serverName) {
this.serverName = serverName; this.serverName = serverName;
} }
@@ -53,6 +57,24 @@ public class PublicServerExecuter extends ServerExecuter {
Core.verbose("Downloading: " + jarUrl + " ..."); Core.verbose("Downloading: " + jarUrl + " ...");
String providerVersion = serverProviderInfo.getProviderVersion();
if(providerVersion == null) {
providerVersion = "error";
}
settings = new PBLocalPreferences(serverProviderInfo.getClientCRC32()+".json");
if(settings.getSetting(cacheVersionKey) != null) {
Core.verbose(String.format("Latest provider version: %s, local provider version: %s", settings.getSetting(cacheVersionKey), providerVersion));
if(!settings.getSetting(cacheVersionKey).equals(providerVersion)) {
Core.verbose("Local provider outdated, clearing cache.");
Directories.clearCache();
}
} else {
Core.verbose("No local provider version in settings, adding to settings file");
}
settings.addSetting(cacheVersionKey, providerVersion);
if (destination.exists()) { if (destination.exists()) {
Core.verbose("Found cached server provider [CRC32: " + serverProviderInfo.getCRC32() + "]"); Core.verbose("Found cached server provider [CRC32: " + serverProviderInfo.getCRC32() + "]");
} else { } else {
@@ -4,8 +4,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="231.0" <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="231.0"
prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
fx:controller="org.parabot.core.ui.components.notifications.NotificationUIController">
<bottom> <bottom>
<Button mnemonicParsing="false" text="Save" BorderPane.alignment="CENTER" onAction="#save"> <Button mnemonicParsing="false" text="Save" BorderPane.alignment="CENTER" onAction="#save">
<BorderPane.margin> <BorderPane.margin>