mirror of
https://github.com/2006-Scape/Parabot.git
synced 2026-07-02 16:49:10 +00:00
Merge pull request #304 from Parabot/development
[RELEASE] Release of V2.8
This commit is contained in:
+1
-1
@@ -34,7 +34,7 @@ env:
|
||||
- secure: UG+b1tEgc8xv9x4r//2OAIK1RrYv6n209KTTFMMwcnAa7DI8HaP8nljRa5/VhDhuKHdlVrYH/tI90v7UVBs0GDVNwK5V17Io0fMm3FUGZekSthTCqqno5wAGa9r6a6mMLtSaSmIFeIKi0+0d2ZwplRuhj/dtEYjjBBj+kK8g4nE=
|
||||
- secure: St/fecUDInFBCRriYqgp2F8PU9/SooorgxD9Mrs+b0EsC7AbtSsQXvdIv2Lp6xzdQ0VSXPcLIhULPOYrmBKnGQ/NjXTIZXxnroyQxxnI6xyEWIZwiHRY/bKRJDRbQTxD9NL32szKiDSwnw7pu6llF4D64UqQvziq4Gm6VohU75M=
|
||||
- secure: bD15GVZWowiknbfLavh8CxSh0GsnF5kT4kZ6ggCuUDGyj0mzqf7dNRnchQIKkCG0WRYyTrFN4pEiygeywWsipEeAVv9Xhx3cuUZmzeQaR5KCWabSwJ8gK6jZd1YhcWmM9vrdPHobZr65MP0y/8mu/Fovgky9dY7KDf4G3SebNrM=
|
||||
- PARABOT_VERSION=2.7
|
||||
- PARABOT_VERSION=2.8
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.parabot</groupId>
|
||||
<artifactId>client</artifactId>
|
||||
<version>2.7</version>
|
||||
<version>2.8</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<dependency>
|
||||
<groupId>org.parabot</groupId>
|
||||
<artifactId>internal-api</artifactId>
|
||||
<version>1.52.1</version>
|
||||
<version>1.53.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.parabot;
|
||||
|
||||
import org.parabot.api.translations.TranslationHelper;
|
||||
import org.parabot.core.Context;
|
||||
import org.parabot.core.Core;
|
||||
import org.parabot.core.Directories;
|
||||
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.ui.BotUI;
|
||||
import org.parabot.core.ui.ServerSelector;
|
||||
import org.parabot.core.ui.utils.UILog;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
@@ -27,6 +29,16 @@ public final class Landing {
|
||||
|
||||
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);
|
||||
|
||||
Directories.validate();
|
||||
@@ -139,6 +151,9 @@ public final class Landing {
|
||||
case "-uuid":
|
||||
Core.setQuickLaunchByUuid(Integer.parseInt(args[++i]));
|
||||
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 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_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_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_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 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 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 DATA_API = "http://bdn.parabot.org/api/v2/data/";
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
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.JSONHookParser;
|
||||
import org.parabot.core.parsers.hooks.XMLHookParser;
|
||||
import org.parabot.environment.api.utils.WebUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
public class HookFile {
|
||||
public static final int TYPE_XML = 0;
|
||||
public static final int TYPE_XML = 0;
|
||||
public static final int TYPE_JSON = 1;
|
||||
|
||||
private URL url;
|
||||
private int type;
|
||||
|
||||
private boolean isLocal;
|
||||
|
||||
public HookFile(File file, int type) throws MalformedURLException {
|
||||
this(file.toURI().toURL(), type);
|
||||
this.isLocal = true;
|
||||
}
|
||||
|
||||
public HookFile(URL url, int type) {
|
||||
@@ -26,17 +31,22 @@ public class HookFile {
|
||||
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 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() {
|
||||
switch (type) {
|
||||
case TYPE_XML:
|
||||
@@ -47,4 +57,11 @@ public class HookFile {
|
||||
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.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
@@ -58,6 +59,15 @@ public class ClassRedirect {
|
||||
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) {
|
||||
System.err.println(c.getName() + "#getClassLoader()" + " Blocked.");
|
||||
throw RedirectClassAdapter.createSecurityException();
|
||||
|
||||
@@ -31,7 +31,7 @@ public class RuntimeRedirect {
|
||||
if (s.contains("ping")) {
|
||||
System.out.println("Faked attempted command: " + s);
|
||||
try {
|
||||
return r.exec("ping 127.0.0.1");
|
||||
return r.exec("ping 8.8.8.8");
|
||||
} catch (IOException e) {
|
||||
throw RedirectClassAdapter.createSecurityException();
|
||||
}
|
||||
|
||||
@@ -61,4 +61,12 @@ public class ThreadRedirect {
|
||||
public static void setUncaughtExceptionHandler(Thread t, Thread.UncaughtExceptionHandler 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);
|
||||
}
|
||||
|
||||
@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.fieldNode = ASMUtils.getField(ASMUtils.getClass(fieldLocation), fieldNode, fieldDesc);
|
||||
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.multiplier = multiplier;
|
||||
Core.verbose(methodName + "[" + fieldLocation + "." + fieldNode + "]");
|
||||
@@ -77,4 +77,21 @@ public class Getter implements Injectable {
|
||||
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);
|
||||
}
|
||||
|
||||
@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.field = ASMUtils.getField(this.fieldLocation, fieldName, fieldDesc);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -52,4 +52,21 @@ public class Setter implements Injectable {
|
||||
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.
|
||||
*
|
||||
* @return The provided URL in the server config JSON (denoted by 'randoms:') or, fallback to the default BDN URL.
|
||||
*/
|
||||
public URL getRandoms() {
|
||||
@@ -182,4 +183,19 @@ public class ServerProviderInfo {
|
||||
// Will never return null, unless the BDN URL is changed. It shouldn't be.
|
||||
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.Context;
|
||||
import org.parabot.core.Core;
|
||||
import org.parabot.core.parsers.hooks.HookParser;
|
||||
import org.parabot.core.parsers.scripts.BDNScripts;
|
||||
import org.parabot.core.parsers.servers.PublicServers;
|
||||
import org.parabot.core.ui.components.VerboseLoader;
|
||||
@@ -48,6 +49,7 @@ public final class AccountManager {
|
||||
accessors.add(PublicServers.MANAGER_FETCHER);
|
||||
accessors.add(PublicServerExecuter.MANAGER_FETCHER);
|
||||
accessors.add(PBPreferences.MANAGER_FETCHER);
|
||||
accessors.add(HookParser.MANAGER_FETCHER);
|
||||
|
||||
for (final AccountManagerAccess accessor : accessors) {
|
||||
accessor.setManager(instance);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.parabot.core.network.proxy;
|
||||
|
||||
import org.parabot.core.Core;
|
||||
import org.parabot.core.ui.utils.UILog;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -44,7 +45,7 @@ public class ProxySocket extends Socket {
|
||||
socket.close();
|
||||
value++;
|
||||
} catch (Exception e) {
|
||||
|
||||
Core.verbose("Error closing proxy connection: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -3,25 +3,39 @@ 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 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.Collections;
|
||||
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
|
||||
*
|
||||
* @author Everel
|
||||
* @author Everel, JKetelaar
|
||||
*/
|
||||
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 abstract Interface[] getInterfaces();
|
||||
|
||||
public abstract Map<String, String> getInterfaceMap();
|
||||
|
||||
public abstract Super[] getSupers();
|
||||
|
||||
public abstract Getter[] getGetters();
|
||||
|
||||
@@ -12,7 +12,10 @@ import java.util.HashMap;
|
||||
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 {
|
||||
private JSONObject root;
|
||||
@@ -71,6 +74,11 @@ public class JSONHookParser extends HookParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getInterfaceMap() {
|
||||
return this.interfaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Super[] getSupers() {
|
||||
JSONArray a = (JSONArray) root.get("supers");
|
||||
|
||||
@@ -13,22 +13,29 @@ import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.util.ArrayList;
|
||||
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 {
|
||||
private Document doc;
|
||||
private Document doc;
|
||||
private HashMap<String, String> interfaceMap;
|
||||
private HashMap<String, String> constants;
|
||||
private boolean parsedInterfaces;
|
||||
private boolean parsedInterfaces;
|
||||
|
||||
public XMLHookParser(HookFile hookFile) {
|
||||
super(hookFile);
|
||||
interfaceMap = new HashMap<String, String>();
|
||||
constants = new HashMap<String, String>();
|
||||
interfaceMap = new HashMap<>();
|
||||
constants = new HashMap<>();
|
||||
try {
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
|
||||
.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
doc = dBuilder.parse(hookFile.getInputStream());
|
||||
doc = dBuilder.parse(hookFile.getInputStream(manager));
|
||||
doc.getDocumentElement().normalize();
|
||||
if (!doc.getDocumentElement().getNodeName().equals("injector")) {
|
||||
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
|
||||
public Interface[] getInterfaces() {
|
||||
parsedInterfaces = true;
|
||||
@@ -98,8 +63,8 @@ public class XMLHookParser extends HookParser {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element interfaceRoot = (Element) node;
|
||||
final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
|
||||
final Element interfaceRoot = (Element) node;
|
||||
final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
|
||||
if (interfaces.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -109,9 +74,9 @@ public class XMLHookParser extends HookParser {
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addInterface = (Element) n;
|
||||
final String className = getValue("classname", addInterface);
|
||||
final String interfaceClass = getValue("interface", addInterface);
|
||||
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);
|
||||
@@ -119,6 +84,11 @@ public class XMLHookParser extends HookParser {
|
||||
return interfaceList.toArray(new Interface[interfaceList.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getInterfaceMap() {
|
||||
return this.interfaceMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Super[] getSupers() {
|
||||
final NodeList interfaceRootList = doc.getElementsByTagName("supers");
|
||||
@@ -135,8 +105,8 @@ public class XMLHookParser extends HookParser {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element superRoot = (Element) node;
|
||||
final NodeList supers = superRoot.getElementsByTagName("add");
|
||||
final Element superRoot = (Element) node;
|
||||
final NodeList supers = superRoot.getElementsByTagName("add");
|
||||
if (supers.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -146,10 +116,10 @@ public class XMLHookParser extends HookParser {
|
||||
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);
|
||||
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()]);
|
||||
@@ -171,8 +141,8 @@ public class XMLHookParser extends HookParser {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element getterRoot = (Element) node;
|
||||
final NodeList getters = getterRoot.getElementsByTagName("add");
|
||||
final Element getterRoot = (Element) node;
|
||||
final NodeList getters = getterRoot.getElementsByTagName("add");
|
||||
if (getters.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -196,9 +166,9 @@ public class XMLHookParser extends HookParser {
|
||||
"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 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;
|
||||
@@ -246,8 +216,8 @@ public class XMLHookParser extends HookParser {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element setterRoot = (Element) node;
|
||||
final NodeList setters = setterRoot.getElementsByTagName("add");
|
||||
final Element setterRoot = (Element) node;
|
||||
final NodeList setters = setterRoot.getElementsByTagName("add");
|
||||
if (setters.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -271,8 +241,8 @@ public class XMLHookParser extends HookParser {
|
||||
"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 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;
|
||||
@@ -319,8 +289,8 @@ public class XMLHookParser extends HookParser {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element invokerRoot = (Element) node;
|
||||
final NodeList invokers = invokerRoot.getElementsByTagName("add");
|
||||
final Element invokerRoot = (Element) node;
|
||||
final NodeList invokers = invokerRoot.getElementsByTagName("add");
|
||||
if (invokers.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -344,15 +314,15 @@ public class XMLHookParser extends HookParser {
|
||||
"accessor", addInvoker));
|
||||
final String into = isSet("into", addInvoker) ? getValue("into",
|
||||
addInvoker) : className;
|
||||
final String methodName = getValue("methodname", addInvoker);
|
||||
final String methodName = getValue("methodname", 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(
|
||||
"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 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);
|
||||
@@ -381,7 +351,7 @@ public class XMLHookParser extends HookParser {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element constantRoot = (Element) node;
|
||||
final Element constantRoot = (Element) node;
|
||||
final NodeList constantsList = constantRoot.getElementsByTagName("add");
|
||||
if (constantsList.getLength() == 0) {
|
||||
// return empty hashmap
|
||||
@@ -393,8 +363,8 @@ public class XMLHookParser extends HookParser {
|
||||
continue;
|
||||
}
|
||||
final Element addConstant = (Element) n;
|
||||
final String key = getValue("key", addConstant);
|
||||
final String value = getValue("value", addConstant);
|
||||
final String key = getValue("key", addConstant);
|
||||
final String value = getValue("value", addConstant);
|
||||
constants.put(key, value);
|
||||
}
|
||||
return constants;
|
||||
@@ -416,8 +386,8 @@ public class XMLHookParser extends HookParser {
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element callbackRoot = (Element) node;
|
||||
final NodeList callbacks = callbackRoot.getElementsByTagName("add");
|
||||
final Element callbackRoot = (Element) node;
|
||||
final NodeList callbacks = callbackRoot.getElementsByTagName("add");
|
||||
if (callbacks.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -441,12 +411,12 @@ public class XMLHookParser extends HookParser {
|
||||
"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 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,
|
||||
@@ -456,4 +426,46 @@ public class XMLHookParser extends HookParser {
|
||||
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,6 +1,5 @@
|
||||
package org.parabot.core.ui;
|
||||
|
||||
import javafx.application.Application;
|
||||
import org.parabot.core.Configuration;
|
||||
import org.parabot.core.Context;
|
||||
import org.parabot.core.Directories;
|
||||
@@ -248,7 +247,7 @@ public class BotUI extends JFrame implements ActionListener, ComponentListener,
|
||||
Directories.clearCache();
|
||||
break;
|
||||
case "Notifications":
|
||||
Application.launch(NotificationUI.class);
|
||||
NotificationUI.create();
|
||||
break;
|
||||
default:
|
||||
System.out.println("Invalid command: " + command);
|
||||
|
||||
@@ -1,20 +1,56 @@
|
||||
package org.parabot.core.ui.components.notifications;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.stage.Stage;
|
||||
import org.parabot.core.Configuration;
|
||||
import org.parabot.api.Configuration;
|
||||
import org.parabot.api.output.Verboser;
|
||||
import org.parabot.api.ui.JavaFxUtil;
|
||||
|
||||
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
|
||||
public void start(Stage stage) throws Exception {
|
||||
//noinspection RedundantCast
|
||||
BorderPane root = (BorderPane) FXMLLoader.load(this.getClass().getResource("/storage/ui/notifications.fxml"));
|
||||
stage.setTitle(Configuration.BOT_TITLE);
|
||||
stage.setScene(new Scene(root));
|
||||
stage.show();
|
||||
public WindowAdapter getWindowAdapter() {
|
||||
return new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
Verboser.verbose("NotificationUI closed " + e);
|
||||
}
|
||||
|
||||
@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) {
|
||||
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);
|
||||
}
|
||||
|
||||
Core.verbose("Loading server: " + desc.toString() + "...");
|
||||
Core.verbose("[Environment] Loading server: " + desc.toString() + "...");
|
||||
|
||||
ServerParser.SERVER_CACHE.get(desc).run();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package org.parabot.environment.api.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@@ -88,4 +86,29 @@ public class FileUtil {
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
||||
@@ -105,7 +105,18 @@ public class Timer {
|
||||
* @return hourly gains
|
||||
*/
|
||||
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;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.parabot.core.Configuration;
|
||||
import org.parabot.core.Context;
|
||||
import org.parabot.core.asm.hooks.HookFile;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
import org.parabot.core.parsers.hooks.HookParser;
|
||||
import org.parabot.core.ui.utils.UILog;
|
||||
import org.parabot.environment.input.Keyboard;
|
||||
import org.parabot.environment.input.Mouse;
|
||||
import org.parabot.environment.scripts.Script;
|
||||
@@ -13,6 +15,8 @@ import javax.swing.*;
|
||||
import java.applet.Applet;
|
||||
import java.applet.AppletStub;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
@@ -21,6 +25,7 @@ import java.net.URL;
|
||||
* @author Everel
|
||||
*/
|
||||
public abstract class ServerProvider implements Opcodes {
|
||||
private boolean crashed = false;
|
||||
|
||||
/**
|
||||
* Get the game/applet dimensions
|
||||
@@ -74,12 +79,36 @@ public abstract class ServerProvider implements Opcodes {
|
||||
|
||||
HookParser parser = hookFile.getParser();
|
||||
Injectable[] injectables = parser.getInjectables();
|
||||
|
||||
if (injectables == null) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.parabot.core.forum.AccountManager;
|
||||
import org.parabot.core.forum.AccountManagerAccess;
|
||||
import org.parabot.core.ui.components.VerboseLoader;
|
||||
import org.parabot.core.ui.utils.UILog;
|
||||
import org.parabot.environment.api.utils.PBLocalPreferences;
|
||||
import org.parabot.environment.api.utils.WebUtil;
|
||||
import org.parabot.environment.servers.ServerProvider;
|
||||
import org.parabot.environment.servers.loader.ServerLoader;
|
||||
@@ -37,6 +38,9 @@ public class PublicServerExecuter extends ServerExecuter {
|
||||
};
|
||||
private String serverName;
|
||||
|
||||
private PBLocalPreferences settings;
|
||||
private final String cacheVersionKey = "cachedProviderVersion";
|
||||
|
||||
public PublicServerExecuter(final String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
@@ -53,6 +57,24 @@ public class PublicServerExecuter extends ServerExecuter {
|
||||
|
||||
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()) {
|
||||
Core.verbose("Found cached server provider [CRC32: " + serverProviderInfo.getCRC32() + "]");
|
||||
} else {
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="231.0"
|
||||
prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="org.parabot.core.ui.components.notifications.NotificationUIController">
|
||||
prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<bottom>
|
||||
<Button mnemonicParsing="false" text="Save" BorderPane.alignment="CENTER" onAction="#save">
|
||||
<BorderPane.margin>
|
||||
|
||||
Reference in New Issue
Block a user