mirror of
https://github.com/2006-Scape/Parabot.git
synced 2026-07-03 16:49:10 +00:00
Updated HookParser
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package org.parabot.core.asm.hooks;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.parabot.core.parsers.HookParser;
|
||||
import org.parabot.core.parsers.JSONHookParser;
|
||||
import org.parabot.core.parsers.XMLHookParser;
|
||||
import org.parabot.environment.api.utils.WebUtil;
|
||||
|
||||
public class HookFile {
|
||||
public static final int TYPE_XML = 0;
|
||||
public static final int TYPE_JSON = 1;
|
||||
|
||||
private URL url;
|
||||
private int type;
|
||||
|
||||
public HookFile(File file, int type) throws MalformedURLException {
|
||||
this(file.toURI().toURL(), type);
|
||||
}
|
||||
|
||||
public HookFile(URL url, int type) {
|
||||
setType(type);
|
||||
this.url = url;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private void setType(int type) {
|
||||
if(type < 0 || type > 1) {
|
||||
throw new IllegalArgumentException("This type does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return WebUtil.getInputStream(url);
|
||||
}
|
||||
|
||||
public HookParser getParser() {
|
||||
switch(type) {
|
||||
case TYPE_XML:
|
||||
return new XMLHookParser(this);
|
||||
case TYPE_JSON:
|
||||
return new JSONHookParser(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +1,8 @@
|
||||
package org.parabot.core.parsers;
|
||||
|
||||
import org.parabot.core.asm.adapters.AddInterfaceAdapter;
|
||||
import org.parabot.core.asm.hooks.HookFile;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
import org.parabot.core.asm.wrappers.*;
|
||||
import org.parabot.environment.api.utils.WebUtil;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -21,171 +12,26 @@ import java.util.HashMap;
|
||||
*
|
||||
* @author Everel
|
||||
*/
|
||||
public class HookParser {
|
||||
private Document doc = null;
|
||||
private boolean parsedInterfaces = false;
|
||||
private HashMap<String, String> interfaceMap = new HashMap<String, String>();
|
||||
public abstract class HookParser {
|
||||
|
||||
private HashMap<String, String> constants = new HashMap<String, String>();
|
||||
|
||||
public HookParser(URL url) {
|
||||
try {
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
|
||||
.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
doc = dBuilder.parse(WebUtil.getInputStream(url));
|
||||
doc.getDocumentElement().normalize();
|
||||
if (!doc.getDocumentElement().getNodeName().equals("injector")) {
|
||||
throw new RuntimeException("Incorrect hook file.");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Unable to parse hooks " + t);
|
||||
}
|
||||
public HookParser(HookFile hookFile) {
|
||||
|
||||
}
|
||||
|
||||
public final Interface[] getInterfaces() {
|
||||
parsedInterfaces = true;
|
||||
final NodeList interfaceRootList = doc
|
||||
.getElementsByTagName("interfaces");
|
||||
switch (interfaceRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <interfaces> tags ");
|
||||
}
|
||||
final Node node = interfaceRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element interfaceRoot = (Element) node;
|
||||
final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
|
||||
if (interfaces.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Interface> interfaceList = new ArrayList<Interface>();
|
||||
for (int x = 0; x < interfaces.getLength(); x++) {
|
||||
final Node n = interfaces.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addInterface = (Element) n;
|
||||
final String className = getValue("classname", addInterface);
|
||||
final String interfaceClass = getValue("interface", addInterface);
|
||||
interfaceMap.put(interfaceClass, className);
|
||||
final Interface inf = new Interface(className, interfaceClass);
|
||||
interfaceList.add(inf);
|
||||
}
|
||||
return interfaceList.toArray(new Interface[interfaceList.size()]);
|
||||
}
|
||||
public abstract Interface[] getInterfaces();
|
||||
|
||||
public final Super[] getSupers() {
|
||||
final NodeList interfaceRootList = doc.getElementsByTagName("supers");
|
||||
switch (interfaceRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <supers> tags ");
|
||||
}
|
||||
final Node node = interfaceRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element superRoot = (Element) node;
|
||||
final NodeList supers = superRoot.getElementsByTagName("add");
|
||||
if (supers.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Super> superList = new ArrayList<Super>();
|
||||
for (int x = 0; x < supers.getLength(); x++) {
|
||||
final Node n = supers.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addSuper = (Element) n;
|
||||
final String className = getValue("classname", addSuper);
|
||||
final String superClass = getValue("super", addSuper);
|
||||
final Super sup = new Super(className, superClass);
|
||||
superList.add(sup);
|
||||
}
|
||||
return superList.toArray(new Super[superList.size()]);
|
||||
}
|
||||
public abstract Super[] getSupers();
|
||||
|
||||
public final Getter[] getGetters() {
|
||||
final NodeList getterRootList = doc.getElementsByTagName("getters");
|
||||
switch (getterRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <getters> tags ");
|
||||
}
|
||||
final Node node = getterRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element getterRoot = (Element) node;
|
||||
final NodeList getters = getterRoot.getElementsByTagName("add");
|
||||
if (getters.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Getter> getterList = new ArrayList<Getter>();
|
||||
for (int x = 0; x < getters.getLength(); x++) {
|
||||
final Node n = getters.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addGetter = (Element) n;
|
||||
if (isSet("classname", addGetter) && isSet("accessor", addGetter)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addGetter) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addGetter) ? getValue(
|
||||
"classname", addGetter) : interfaceMap.get(getValue(
|
||||
"accessor", addGetter));
|
||||
final String into = isSet("into", addGetter) ? getValue("into",
|
||||
addGetter) : className;
|
||||
final String fieldName = getValue("field", addGetter);
|
||||
final String methodName = getValue("methodname", addGetter);
|
||||
boolean staticMethod = isSet("methstatic", addGetter) ? (getValue(
|
||||
"methstatic", addGetter).equals("true")) : false;
|
||||
String returnDesc = isSet("desc", addGetter) ? getValue("desc",
|
||||
addGetter) : null;
|
||||
String array = "";
|
||||
if (returnDesc != null && returnDesc.contains("%s")) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (returnDesc.startsWith("[")) {
|
||||
for (int i = 0; i < returnDesc.length(); i++) {
|
||||
if (returnDesc.charAt(i) == '[') {
|
||||
array += '[';
|
||||
}
|
||||
}
|
||||
returnDesc = returnDesc.replaceAll("\\[", "");
|
||||
}
|
||||
str.append(array)
|
||||
.append('L')
|
||||
.append(String.format(returnDesc,
|
||||
AddInterfaceAdapter.getAccessorPackage()))
|
||||
.append(";");
|
||||
returnDesc = str.toString();
|
||||
}
|
||||
final Getter get = new Getter(into, className, fieldName,
|
||||
methodName, returnDesc, staticMethod);
|
||||
getterList.add(get);
|
||||
}
|
||||
return getterList.toArray(new Getter[getterList.size()]);
|
||||
}
|
||||
public abstract Getter[] getGetters();
|
||||
|
||||
public abstract Setter[] getSetters();
|
||||
|
||||
public abstract Invoker[] getInvokers();
|
||||
|
||||
public abstract Callback[] getCallbacks();
|
||||
|
||||
public abstract HashMap<String, String> getConstants();
|
||||
|
||||
public Injectable[] getInjectables() {
|
||||
ArrayList<Injectable> injectables = new ArrayList<Injectable>();
|
||||
@@ -228,253 +74,4 @@ public class HookParser {
|
||||
return injectables.toArray(new Injectable[injectables.size()]);
|
||||
}
|
||||
|
||||
public final Setter[] getSetters() {
|
||||
final NodeList setterRootList = doc.getElementsByTagName("setters");
|
||||
switch (setterRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <setters> tags ");
|
||||
}
|
||||
final Node node = setterRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element setterRoot = (Element) node;
|
||||
final NodeList setters = setterRoot.getElementsByTagName("add");
|
||||
if (setters.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Setter> setterList = new ArrayList<Setter>();
|
||||
for (int x = 0; x < setters.getLength(); x++) {
|
||||
final Node n = setters.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addSetter = (Element) n;
|
||||
if (isSet("classname", addSetter) && isSet("accessor", addSetter)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addSetter) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addSetter) ? getValue(
|
||||
"classname", addSetter) : interfaceMap.get(getValue(
|
||||
"accessor", addSetter));
|
||||
final String into = isSet("into", addSetter) ? getValue("into",
|
||||
addSetter) : className;
|
||||
final String fieldName = getValue("field", addSetter);
|
||||
final String methodName = getValue("methodname", addSetter);
|
||||
boolean staticMethod = isSet("methstatic", addSetter) ? (getValue(
|
||||
"methstatic", addSetter).equals("true")) : false;
|
||||
String returnDesc = isSet("desc", addSetter) ? getValue("desc",
|
||||
addSetter) : null;
|
||||
String array = "";
|
||||
if (returnDesc != null && returnDesc.contains("%s")) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (returnDesc.startsWith("[")) {
|
||||
for (int i = 0; i < returnDesc.length(); i++) {
|
||||
if (returnDesc.charAt(i) == '[') {
|
||||
array += '[';
|
||||
}
|
||||
}
|
||||
returnDesc = returnDesc.replaceAll("\\[", "");
|
||||
}
|
||||
str.append(array)
|
||||
.append('L')
|
||||
.append(String.format(returnDesc,
|
||||
AddInterfaceAdapter.getAccessorPackage()))
|
||||
.append(";");
|
||||
returnDesc = str.toString();
|
||||
}
|
||||
final Setter get = new Setter(className, into, fieldName,
|
||||
methodName, returnDesc, staticMethod);
|
||||
setterList.add(get);
|
||||
}
|
||||
return setterList.toArray(new Setter[setterList.size()]);
|
||||
}
|
||||
|
||||
public final Invoker[] getInvokers() {
|
||||
final NodeList invokerRootList = doc.getElementsByTagName("invokers");
|
||||
switch (invokerRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <invokers> tags ");
|
||||
}
|
||||
final Node node = invokerRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element invokerRoot = (Element) node;
|
||||
final NodeList invokers = invokerRoot.getElementsByTagName("add");
|
||||
if (invokers.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Invoker> invokerList = new ArrayList<Invoker>();
|
||||
for (int x = 0; x < invokers.getLength(); x++) {
|
||||
final Node n = invokers.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addInvoker = (Element) n;
|
||||
if (isSet("classname", addInvoker) && isSet("accessor", addInvoker)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addInvoker) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addInvoker) ? getValue(
|
||||
"classname", addInvoker) : interfaceMap.get(getValue(
|
||||
"accessor", addInvoker));
|
||||
final String into = isSet("into", addInvoker) ? getValue("into",
|
||||
addInvoker) : className;
|
||||
final String methodName = getValue("methodname", addInvoker);
|
||||
final String invMethodName = getValue("invokemethod", addInvoker);
|
||||
final String argsDesc = getValue("argsdesc", addInvoker);
|
||||
String returnDesc = isSet("desc", addInvoker) ? resolveDesc(getValue(
|
||||
"desc", addInvoker)) : null;
|
||||
|
||||
final Invoker invoker = new Invoker(into, className, invMethodName,
|
||||
argsDesc, returnDesc, methodName);
|
||||
invokerList.add(invoker);
|
||||
}
|
||||
return invokerList.toArray(new Invoker[invokerList.size()]);
|
||||
}
|
||||
|
||||
public final Callback[] getCallbacks() {
|
||||
final NodeList callbackRootList = doc.getElementsByTagName("callbacks");
|
||||
switch (callbackRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <callbacks> tags ");
|
||||
}
|
||||
final Node node = callbackRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element callbackRoot = (Element) node;
|
||||
final NodeList callbacks = callbackRoot.getElementsByTagName("add");
|
||||
if (callbacks.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Callback> callbackList = new ArrayList<Callback>();
|
||||
for (int x = 0; x < callbacks.getLength(); x++) {
|
||||
final Node n = callbacks.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addCallback = (Element) n;
|
||||
if (isSet("classname", addCallback)
|
||||
&& isSet("accessor", addCallback)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addCallback) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addCallback) ? getValue(
|
||||
"classname", addCallback) : interfaceMap.get(getValue(
|
||||
"accessor", addCallback));
|
||||
|
||||
final String methodName = getValue("methodname", addCallback);
|
||||
final String callClass = getValue("callclass", addCallback);
|
||||
final String callMethod = getValue("callmethod", addCallback);
|
||||
final String callDesc = getValue("calldesc", addCallback);
|
||||
final String callArgs = getValue("callargs", addCallback);
|
||||
final String desc = getValue("desc", addCallback);
|
||||
|
||||
final Callback callback = new Callback(className, methodName, desc,
|
||||
callClass, callMethod, callDesc, callArgs);
|
||||
callbackList.add(callback);
|
||||
}
|
||||
return callbackList.toArray(new Callback[callbackList.size()]);
|
||||
}
|
||||
|
||||
private static String resolveDesc(String returnDesc) {
|
||||
String array = "";
|
||||
if (returnDesc != null && returnDesc.contains("%s")) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (returnDesc.startsWith("[")) {
|
||||
for (int i = 0; i < returnDesc.length(); i++) {
|
||||
if (returnDesc.charAt(i) == '[') {
|
||||
array += '[';
|
||||
}
|
||||
}
|
||||
returnDesc = returnDesc.replaceAll("\\[", "");
|
||||
}
|
||||
str.append(array)
|
||||
.append('L')
|
||||
.append(String.format(returnDesc,
|
||||
AddInterfaceAdapter.getAccessorPackage()))
|
||||
.append(";");
|
||||
returnDesc = str.toString();
|
||||
}
|
||||
return returnDesc;
|
||||
}
|
||||
|
||||
private static final boolean isSet(String tag, Element element) {
|
||||
return element.getElementsByTagName(tag).getLength() > 0;
|
||||
}
|
||||
|
||||
private static final String getValue(String tag, Element element) {
|
||||
NodeList nodes = element.getElementsByTagName(tag).item(0)
|
||||
.getChildNodes();
|
||||
Node node = (Node) nodes.item(0);
|
||||
return node.getNodeValue();
|
||||
}
|
||||
|
||||
public final HashMap<String, String> getConstants() {
|
||||
if (!constants.isEmpty()) {
|
||||
return constants;
|
||||
}
|
||||
final NodeList constantsRootList = doc
|
||||
.getElementsByTagName("constants");
|
||||
switch (constantsRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <constants> tags ");
|
||||
}
|
||||
final Node node = constantsRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element constantRoot = (Element) node;
|
||||
final NodeList constantsList = constantRoot.getElementsByTagName("add");
|
||||
if (constantsList.getLength() == 0) {
|
||||
// return empty hashmap
|
||||
return constants;
|
||||
}
|
||||
for (int x = 0; x < constantsList.getLength(); x++) {
|
||||
final Node n = constantsList.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addConstant = (Element) n;
|
||||
final String key = getValue("key", addConstant);
|
||||
final String value = getValue("value", addConstant);
|
||||
constants.put(key, value);
|
||||
}
|
||||
return constants;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.parabot.core.parsers;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.parabot.core.asm.hooks.HookFile;
|
||||
import org.parabot.core.asm.wrappers.Callback;
|
||||
import org.parabot.core.asm.wrappers.Getter;
|
||||
import org.parabot.core.asm.wrappers.Interface;
|
||||
import org.parabot.core.asm.wrappers.Invoker;
|
||||
import org.parabot.core.asm.wrappers.Setter;
|
||||
import org.parabot.core.asm.wrappers.Super;
|
||||
|
||||
public class JSONHookParser extends HookParser {
|
||||
|
||||
public JSONHookParser(HookFile hookFile) {
|
||||
super(hookFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interface[] getInterfaces() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Super[] getSupers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Getter[] getGetters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Setter[] getSetters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Invoker[] getInvokers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callback[] getCallbacks() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, String> getConstants() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
package org.parabot.core.parsers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.parabot.core.asm.adapters.AddInterfaceAdapter;
|
||||
import org.parabot.core.asm.hooks.HookFile;
|
||||
import org.parabot.core.asm.wrappers.Callback;
|
||||
import org.parabot.core.asm.wrappers.Getter;
|
||||
import org.parabot.core.asm.wrappers.Interface;
|
||||
import org.parabot.core.asm.wrappers.Invoker;
|
||||
import org.parabot.core.asm.wrappers.Setter;
|
||||
import org.parabot.core.asm.wrappers.Super;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class XMLHookParser extends HookParser {
|
||||
private boolean parsedInterfaces;
|
||||
private Document doc;
|
||||
private HashMap<String, String> interfaceMap;
|
||||
private HashMap<String, String> constants;
|
||||
|
||||
public XMLHookParser(HookFile hookFile) {
|
||||
super(hookFile);
|
||||
interfaceMap = new HashMap<String, String>();
|
||||
constants = new HashMap<String, String>();
|
||||
try {
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
|
||||
.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
doc = dBuilder.parse(hookFile.getInputStream());
|
||||
doc.getDocumentElement().normalize();
|
||||
if (!doc.getDocumentElement().getNodeName().equals("injector")) {
|
||||
throw new RuntimeException("Incorrect hook file.");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Unable to parse hooks " + t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interface[] getInterfaces() {
|
||||
parsedInterfaces = true;
|
||||
final NodeList interfaceRootList = doc
|
||||
.getElementsByTagName("interfaces");
|
||||
switch (interfaceRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <interfaces> tags ");
|
||||
}
|
||||
final Node node = interfaceRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element interfaceRoot = (Element) node;
|
||||
final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
|
||||
if (interfaces.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Interface> interfaceList = new ArrayList<Interface>();
|
||||
for (int x = 0; x < interfaces.getLength(); x++) {
|
||||
final Node n = interfaces.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addInterface = (Element) n;
|
||||
final String className = getValue("classname", addInterface);
|
||||
final String interfaceClass = getValue("interface", addInterface);
|
||||
interfaceMap.put(interfaceClass, className);
|
||||
final Interface inf = new Interface(className, interfaceClass);
|
||||
interfaceList.add(inf);
|
||||
}
|
||||
return interfaceList.toArray(new Interface[interfaceList.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Super[] getSupers() {
|
||||
final NodeList interfaceRootList = doc.getElementsByTagName("supers");
|
||||
switch (interfaceRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <supers> tags ");
|
||||
}
|
||||
final Node node = interfaceRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element superRoot = (Element) node;
|
||||
final NodeList supers = superRoot.getElementsByTagName("add");
|
||||
if (supers.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Super> superList = new ArrayList<Super>();
|
||||
for (int x = 0; x < supers.getLength(); x++) {
|
||||
final Node n = supers.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addSuper = (Element) n;
|
||||
final String className = getValue("classname", addSuper);
|
||||
final String superClass = getValue("super", addSuper);
|
||||
final Super sup = new Super(className, superClass);
|
||||
superList.add(sup);
|
||||
}
|
||||
return superList.toArray(new Super[superList.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Getter[] getGetters() {
|
||||
final NodeList getterRootList = doc.getElementsByTagName("getters");
|
||||
switch (getterRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <getters> tags ");
|
||||
}
|
||||
final Node node = getterRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element getterRoot = (Element) node;
|
||||
final NodeList getters = getterRoot.getElementsByTagName("add");
|
||||
if (getters.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Getter> getterList = new ArrayList<Getter>();
|
||||
for (int x = 0; x < getters.getLength(); x++) {
|
||||
final Node n = getters.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addGetter = (Element) n;
|
||||
if (isSet("classname", addGetter) && isSet("accessor", addGetter)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addGetter) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addGetter) ? getValue(
|
||||
"classname", addGetter) : interfaceMap.get(getValue(
|
||||
"accessor", addGetter));
|
||||
final String into = isSet("into", addGetter) ? getValue("into",
|
||||
addGetter) : className;
|
||||
final String fieldName = getValue("field", addGetter);
|
||||
final String methodName = getValue("methodname", addGetter);
|
||||
boolean staticMethod = isSet("methstatic", addGetter) ? (getValue(
|
||||
"methstatic", addGetter).equals("true")) : false;
|
||||
String returnDesc = isSet("desc", addGetter) ? getValue("desc",
|
||||
addGetter) : null;
|
||||
String array = "";
|
||||
if (returnDesc != null && returnDesc.contains("%s")) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (returnDesc.startsWith("[")) {
|
||||
for (int i = 0; i < returnDesc.length(); i++) {
|
||||
if (returnDesc.charAt(i) == '[') {
|
||||
array += '[';
|
||||
}
|
||||
}
|
||||
returnDesc = returnDesc.replaceAll("\\[", "");
|
||||
}
|
||||
str.append(array)
|
||||
.append('L')
|
||||
.append(String.format(returnDesc,
|
||||
AddInterfaceAdapter.getAccessorPackage()))
|
||||
.append(";");
|
||||
returnDesc = str.toString();
|
||||
}
|
||||
final Getter get = new Getter(into, className, fieldName,
|
||||
methodName, returnDesc, staticMethod);
|
||||
getterList.add(get);
|
||||
}
|
||||
return getterList.toArray(new Getter[getterList.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Setter[] getSetters() {
|
||||
final NodeList setterRootList = doc.getElementsByTagName("setters");
|
||||
switch (setterRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <setters> tags ");
|
||||
}
|
||||
final Node node = setterRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element setterRoot = (Element) node;
|
||||
final NodeList setters = setterRoot.getElementsByTagName("add");
|
||||
if (setters.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Setter> setterList = new ArrayList<Setter>();
|
||||
for (int x = 0; x < setters.getLength(); x++) {
|
||||
final Node n = setters.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addSetter = (Element) n;
|
||||
if (isSet("classname", addSetter) && isSet("accessor", addSetter)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addSetter) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addSetter) ? getValue(
|
||||
"classname", addSetter) : interfaceMap.get(getValue(
|
||||
"accessor", addSetter));
|
||||
final String into = isSet("into", addSetter) ? getValue("into",
|
||||
addSetter) : className;
|
||||
final String fieldName = getValue("field", addSetter);
|
||||
final String methodName = getValue("methodname", addSetter);
|
||||
boolean staticMethod = isSet("methstatic", addSetter) ? (getValue(
|
||||
"methstatic", addSetter).equals("true")) : false;
|
||||
String returnDesc = isSet("desc", addSetter) ? getValue("desc",
|
||||
addSetter) : null;
|
||||
String array = "";
|
||||
if (returnDesc != null && returnDesc.contains("%s")) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (returnDesc.startsWith("[")) {
|
||||
for (int i = 0; i < returnDesc.length(); i++) {
|
||||
if (returnDesc.charAt(i) == '[') {
|
||||
array += '[';
|
||||
}
|
||||
}
|
||||
returnDesc = returnDesc.replaceAll("\\[", "");
|
||||
}
|
||||
str.append(array)
|
||||
.append('L')
|
||||
.append(String.format(returnDesc,
|
||||
AddInterfaceAdapter.getAccessorPackage()))
|
||||
.append(";");
|
||||
returnDesc = str.toString();
|
||||
}
|
||||
final Setter get = new Setter(className, into, fieldName,
|
||||
methodName, returnDesc, staticMethod);
|
||||
setterList.add(get);
|
||||
}
|
||||
return setterList.toArray(new Setter[setterList.size()]);
|
||||
}
|
||||
|
||||
|
||||
private static String resolveDesc(String returnDesc) {
|
||||
String array = "";
|
||||
if (returnDesc != null && returnDesc.contains("%s")) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (returnDesc.startsWith("[")) {
|
||||
for (int i = 0; i < returnDesc.length(); i++) {
|
||||
if (returnDesc.charAt(i) == '[') {
|
||||
array += '[';
|
||||
}
|
||||
}
|
||||
returnDesc = returnDesc.replaceAll("\\[", "");
|
||||
}
|
||||
str.append(array)
|
||||
.append('L')
|
||||
.append(String.format(returnDesc,
|
||||
AddInterfaceAdapter.getAccessorPackage()))
|
||||
.append(";");
|
||||
returnDesc = str.toString();
|
||||
}
|
||||
return returnDesc;
|
||||
}
|
||||
|
||||
private static final boolean isSet(String tag, Element element) {
|
||||
return element.getElementsByTagName(tag).getLength() > 0;
|
||||
}
|
||||
|
||||
private static final String getValue(String tag, Element element) {
|
||||
NodeList nodes = element.getElementsByTagName(tag).item(0)
|
||||
.getChildNodes();
|
||||
Node node = (Node) nodes.item(0);
|
||||
return node.getNodeValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Invoker[] getInvokers() {
|
||||
final NodeList invokerRootList = doc.getElementsByTagName("invokers");
|
||||
switch (invokerRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <invokers> tags ");
|
||||
}
|
||||
final Node node = invokerRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element invokerRoot = (Element) node;
|
||||
final NodeList invokers = invokerRoot.getElementsByTagName("add");
|
||||
if (invokers.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Invoker> invokerList = new ArrayList<Invoker>();
|
||||
for (int x = 0; x < invokers.getLength(); x++) {
|
||||
final Node n = invokers.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addInvoker = (Element) n;
|
||||
if (isSet("classname", addInvoker) && isSet("accessor", addInvoker)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addInvoker) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addInvoker) ? getValue(
|
||||
"classname", addInvoker) : interfaceMap.get(getValue(
|
||||
"accessor", addInvoker));
|
||||
final String into = isSet("into", addInvoker) ? getValue("into",
|
||||
addInvoker) : className;
|
||||
final String methodName = getValue("methodname", addInvoker);
|
||||
final String invMethodName = getValue("invokemethod", addInvoker);
|
||||
final String argsDesc = getValue("argsdesc", addInvoker);
|
||||
String returnDesc = isSet("desc", addInvoker) ? resolveDesc(getValue(
|
||||
"desc", addInvoker)) : null;
|
||||
|
||||
final Invoker invoker = new Invoker(into, className, invMethodName,
|
||||
argsDesc, returnDesc, methodName);
|
||||
invokerList.add(invoker);
|
||||
}
|
||||
return invokerList.toArray(new Invoker[invokerList.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, String> getConstants() {
|
||||
if (!constants.isEmpty()) {
|
||||
return constants;
|
||||
}
|
||||
final NodeList constantsRootList = doc
|
||||
.getElementsByTagName("constants");
|
||||
switch (constantsRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <constants> tags ");
|
||||
}
|
||||
final Node node = constantsRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element constantRoot = (Element) node;
|
||||
final NodeList constantsList = constantRoot.getElementsByTagName("add");
|
||||
if (constantsList.getLength() == 0) {
|
||||
// return empty hashmap
|
||||
return constants;
|
||||
}
|
||||
for (int x = 0; x < constantsList.getLength(); x++) {
|
||||
final Node n = constantsList.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addConstant = (Element) n;
|
||||
final String key = getValue("key", addConstant);
|
||||
final String value = getValue("value", addConstant);
|
||||
constants.put(key, value);
|
||||
}
|
||||
return constants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Callback[] getCallbacks() {
|
||||
final NodeList callbackRootList = doc.getElementsByTagName("callbacks");
|
||||
switch (callbackRootList.getLength()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Hook file may not contains multiple <callbacks> tags ");
|
||||
}
|
||||
final Node node = callbackRootList.item(0);
|
||||
if (node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
final Element callbackRoot = (Element) node;
|
||||
final NodeList callbacks = callbackRoot.getElementsByTagName("add");
|
||||
if (callbacks.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
final ArrayList<Callback> callbackList = new ArrayList<Callback>();
|
||||
for (int x = 0; x < callbacks.getLength(); x++) {
|
||||
final Node n = callbacks.item(x);
|
||||
if (n.getNodeType() != Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
final Element addCallback = (Element) n;
|
||||
if (isSet("classname", addCallback)
|
||||
&& isSet("accessor", addCallback)) {
|
||||
throw new RuntimeException(
|
||||
"Can't set classname and accessor tag together.");
|
||||
}
|
||||
if (isSet("accessor", addCallback) && !parsedInterfaces) {
|
||||
throw new RuntimeException(
|
||||
"You'll need to parse interfaces first.");
|
||||
}
|
||||
final String className = isSet("classname", addCallback) ? getValue(
|
||||
"classname", addCallback) : interfaceMap.get(getValue(
|
||||
"accessor", addCallback));
|
||||
|
||||
final String methodName = getValue("methodname", addCallback);
|
||||
final String callClass = getValue("callclass", addCallback);
|
||||
final String callMethod = getValue("callmethod", addCallback);
|
||||
final String callDesc = getValue("calldesc", addCallback);
|
||||
final String callArgs = getValue("callargs", addCallback);
|
||||
final String desc = getValue("desc", addCallback);
|
||||
|
||||
final Callback callback = new Callback(className, methodName, desc,
|
||||
callClass, callMethod, callDesc, callArgs);
|
||||
callbackList.add(callback);
|
||||
}
|
||||
return callbackList.toArray(new Callback[callbackList.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.parabot.environment.servers;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.parabot.core.Context;
|
||||
import org.parabot.core.asm.hooks.HookFile;
|
||||
import org.parabot.core.asm.interfaces.Injectable;
|
||||
import org.parabot.core.parsers.HookParser;
|
||||
import org.parabot.environment.input.Keyboard;
|
||||
@@ -25,12 +26,21 @@ public abstract class ServerProvider implements Opcodes {
|
||||
/**
|
||||
* Hooks to parse
|
||||
*
|
||||
* @deprecated use getHookFile() now
|
||||
* @return URL to hooks file
|
||||
*/
|
||||
@Deprecated
|
||||
public URL getHooks() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hook file to parse
|
||||
* @return hook file
|
||||
*/
|
||||
public HookFile getHookFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Jar to parse
|
||||
@@ -46,11 +56,13 @@ public abstract class ServerProvider implements Opcodes {
|
||||
}
|
||||
|
||||
public void injectHooks() {
|
||||
URL hooksFile = getHooks();
|
||||
if (hooksFile == null) {
|
||||
HookFile hookFile = fetchHookFile();
|
||||
|
||||
if(hookFile == null) {
|
||||
return;
|
||||
}
|
||||
HookParser parser = new HookParser(hooksFile);
|
||||
|
||||
HookParser parser = hookFile.getParser();
|
||||
Injectable[] injectables = parser.getInjectables();
|
||||
if (injectables == null) {
|
||||
return;
|
||||
@@ -60,6 +72,20 @@ public abstract class ServerProvider implements Opcodes {
|
||||
}
|
||||
Context.resolve().setHookParser(parser);
|
||||
}
|
||||
|
||||
private HookFile fetchHookFile() {
|
||||
HookFile hookFile = getHookFile();
|
||||
if(hookFile != null) {
|
||||
return hookFile;
|
||||
}
|
||||
|
||||
URL hookLocation = getHooks();
|
||||
if(hookLocation == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HookFile(hookLocation, HookFile.TYPE_XML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom items to the bot menu bar
|
||||
|
||||
Reference in New Issue
Block a user