Refactor /rs

This commit is contained in:
Scott Burns
2019-05-16 00:36:48 +02:00
parent 26cad57975
commit dee03d9508
8 changed files with 1021 additions and 828 deletions

View File

@@ -48,11 +48,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -62,20 +58,18 @@ import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import java.util.jar.Manifest; import java.util.jar.Manifest;
import java.util.logging.Logger; import java.util.logging.Logger;
import javassist.ClassPool;
import javassist.NotFoundException;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javassist.ClassPool;
import javassist.NotFoundException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLite;
import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO; import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO;
import static net.runelite.client.rs.ClientUpdateCheckMode.NONE; import static net.runelite.client.rs.ClientUpdateCheckMode.NONE;
import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA; import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA;
import net.runelite.client.RuneLite;
import net.runelite.client.rs.bytecode.ByteCodeUtils;
import net.runelite.client.rs.bytecode.ByteCodePatcher; import net.runelite.client.rs.bytecode.ByteCodePatcher;
import net.runelite.client.rs.bytecode.ByteCodeUtils;
import net.runelite.client.rs.bytecode.Hooks; import net.runelite.client.rs.bytecode.Hooks;
import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Request; import okhttp3.Request;
@@ -87,10 +81,9 @@ import org.xeustechnologies.jcl.JarClassLoader;
@Singleton @Singleton
public class ClientLoader public class ClientLoader
{ {
public static File hooksFile = new File(RuneLite.RUNELITE_DIR+"/hooks-"+ RuneLiteAPI.getVersion() +"-.json"); public static File hooksFile = new File(RuneLite.RUNELITE_DIR + "/hooks-" + RuneLiteAPI.getVersion() + "-.json");
private final ClientConfigLoader clientConfigLoader; private final ClientConfigLoader clientConfigLoader;
private ClientUpdateCheckMode updateCheckMode; private ClientUpdateCheckMode updateCheckMode;
private JarOutputStream target;
private static String[] preotectedStuffs; private static String[] preotectedStuffs;
private static int stepCount; private static int stepCount;
@@ -114,14 +107,13 @@ public class ClientLoader
{ {
File injectedClientFile = ByteCodeUtils.injectedClientFile; File injectedClientFile = ByteCodeUtils.injectedClientFile;
File hijackedClientFile = ByteCodeUtils.hijackedClientFile; File hijackedClientFile = ByteCodeUtils.hijackedClientFile;
Manifest manifest = new Manifest(); Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
target = new JarOutputStream(new FileOutputStream(injectedClientFile), manifest); JarOutputStream target = new JarOutputStream(new FileOutputStream(injectedClientFile), manifest);
RSConfig config = clientConfigLoader.fetch(); RSConfig config = clientConfigLoader.fetch();
Map<String, byte[]> zipFile = new HashMap<>(); Map<String, byte[]> zipFile = new HashMap<>();
{ {
Certificate[] jagexCertificateChain = getJagexCertificateChain();
String codebase = config.getCodeBase(); String codebase = config.getCodeBase();
String initialJar = config.getInitialJar(); String initialJar = config.getInitialJar();
URL url = new URL(codebase + initialJar); URL url = new URL(codebase + initialJar);
@@ -133,7 +125,7 @@ public class ClientLoader
{ {
JarInputStream jis; JarInputStream jis;
jis = new JarInputStream(response.body().byteStream()); jis = new JarInputStream(response.body().byteStream());
byte[] tmp = new byte[4096]; byte[] tmp = new byte[4096];
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024); ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
@@ -161,118 +153,131 @@ public class ClientLoader
} }
} }
if (updateCheckMode == AUTO) if (updateCheckMode == AUTO)
{
Map<String, String> hashes;
try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/hashes.json"))
{ {
Map<String, String> hashes; hashes = new Gson().fromJson(new InputStreamReader(is), new TypeToken<HashMap<String, String>>()
try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/hashes.json"))
{ {
hashes = new Gson().fromJson(new InputStreamReader(is), new TypeToken<HashMap<String, String>>() }.getType());
{ }
}.getType());
for (Map.Entry<String, String> file : hashes.entrySet())
{
byte[] bytes = zipFile.get(file.getKey());
String ourHash = null;
if (bytes != null)
{
ourHash = Hashing.sha512().hashBytes(bytes).toString();
} }
for (Map.Entry<String, String> file : hashes.entrySet()) if (!file.getValue().equals(ourHash))
{ {
byte[] bytes = zipFile.get(file.getKey()); if (hijackedClientFile.exists())
String ourHash = null;
if (bytes != null)
{ {
ourHash = Hashing.sha512().hashBytes(bytes).toString(); Logger.getAnonymousLogger().warning("[RuneLitePlus] Hash checking / Client patching skipped due to hijacked client.");
updateCheckMode = VANILLA;
break;
} }
else
if (!file.getValue().equals(ourHash))
{ {
if (hijackedClientFile.exists()) { log.info("{} had a hash mismatch; falling back to vanilla. {} != {}", file.getKey(), file.getValue(), ourHash);
Logger.getAnonymousLogger().warning("[RuneLitePlus] Hash checking / Client patching skipped due to hijacked client."); log.info("Client is outdated!");
updateCheckMode = VANILLA; updateCheckMode = VANILLA;
break; break;
} else {
log.info("{} had a hash mismatch; falling back to vanilla. {} != {}", file.getKey(), file.getValue(), ourHash);
log.info("Client is outdated!");
updateCheckMode = VANILLA;
break;
}
} }
} }
} }
}
if (updateCheckMode == AUTO) if (updateCheckMode == AUTO)
{
ByteArrayOutputStream patchOs = new ByteArrayOutputStream(756 * 1024);
int patchCount = 0;
for (Map.Entry<String, byte[]> file : zipFile.entrySet())
{ {
ByteArrayOutputStream patchOs = new ByteArrayOutputStream(756 * 1024); byte[] bytes;
int patchCount = 0; try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/" + file.getKey() + ".bs"))
for (Map.Entry<String, byte[]> file : zipFile.entrySet())
{ {
byte[] bytes; if (is == null)
try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/" + file.getKey() + ".bs"))
{ {
if (is == null) continue;
{
continue;
}
bytes = ByteStreams.toByteArray(is);
} }
patchOs.reset(); bytes = ByteStreams.toByteArray(is);
Patch.patch(file.getValue(), bytes, patchOs);
file.setValue(patchOs.toByteArray());
++patchCount;
if (!file.getKey().startsWith("META")) {
add(file.getValue(), file.getKey(), target);
}
} }
if (target!=null)
target.close();
log.info("Patched {} classes", patchCount); patchOs.reset();
Patch.patch(file.getValue(), bytes, patchOs);
file.setValue(patchOs.toByteArray());
++patchCount;
if (!file.getKey().startsWith("META"))
{
add(file.getValue(), file.getKey(), target);
}
} }
if (hooksFile.exists()) { target.close();
ByteCodePatcher.classPool = new ClassPool(true);
ByteCodePatcher.classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar");
Gson gson = new Gson();
Hooks hooks = gson.fromJson(new BufferedReader(new FileReader(hooksFile)), Hooks.class);
if (hooks.clientInstance.equals("")|| log.info("Patched {} classes", patchCount);
hooks.projectileClass.equals("") || }
hooks.actorClass.equals("") || if (hooksFile.exists())
hooks.playerClass.equals("")) { {
System.out.println("[RuneLitePlus] Bad hooks, re-scraping."); ByteCodePatcher.classPool = new ClassPool(true);
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath()); ByteCodePatcher.classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath()); Gson gson = new Gson();
ByteCodePatcher.findHooks(injectedClientFile.getPath()); Hooks hooks = gson.fromJson(new BufferedReader(new FileReader(hooksFile)), Hooks.class);
} else {
ByteCodePatcher.clientInstance = hooks.clientInstance;
ByteCodePatcher.applyHooks(ByteCodeUtils.injectedClientFile, hooks);
System.out.println("[RuneLitePlus] Loaded hooks");
}
} else { if (hooks.clientInstance.equals("") ||
System.out.println("[RuneLitePlus] Hooks file not found, scraping hooks."); hooks.projectileClass.equals("") ||
hooks.actorClass.equals("") ||
hooks.playerClass.equals(""))
{
System.out.println("[RuneLitePlus] Bad hooks, re-scraping.");
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath()); stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath()); ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.hooks.protectedStuff = preotectedStuffs;
ByteCodePatcher.findHooks(injectedClientFile.getPath()); ByteCodePatcher.findHooks(injectedClientFile.getPath());
} }
else
{
ByteCodePatcher.clientInstance = hooks.clientInstance;
ByteCodePatcher.applyHooks(ByteCodeUtils.injectedClientFile, hooks);
System.out.println("[RuneLitePlus] Loaded hooks");
}
}
else
{
System.out.println("[RuneLitePlus] Hooks file not found, scraping hooks.");
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.hooks.protectedStuff = preotectedStuffs;
ByteCodePatcher.findHooks(injectedClientFile.getPath());
}
Map<String, byte[]> zipFile2 = new HashMap<>(); Map<String, byte[]> zipFile2 = new HashMap<>();
JarInputStream jis = new JarInputStream(new FileInputStream(hijackedClientFile)); JarInputStream jis = new JarInputStream(new FileInputStream(hijackedClientFile));
byte[] tmp = new byte[4096]; byte[] tmp = new byte[4096];
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024); ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
for (; ; ) { for (; ; )
{
JarEntry metadata = jis.getNextJarEntry(); JarEntry metadata = jis.getNextJarEntry();
if (metadata == null) { if (metadata == null)
{
break; break;
} }
buffer.reset(); buffer.reset();
for (; ; ) { for (; ; )
{
int n = jis.read(tmp); int n = jis.read(tmp);
if (n <= -1) { if (n <= -1)
{
break; break;
} }
buffer.write(tmp, 0, n); buffer.write(tmp, 0, n);
@@ -306,7 +311,7 @@ public class ClientLoader
return rs; return rs;
} }
catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException
| CompressorException | InvalidHeaderException | CertificateException | SecurityException e) | CompressorException | InvalidHeaderException | SecurityException e)
{ {
if (e instanceof ClassNotFoundException) if (e instanceof ClassNotFoundException)
{ {
@@ -317,142 +322,175 @@ public class ClientLoader
log.error("Error loading RS!", e); log.error("Error loading RS!", e);
return null; return null;
} catch (NotFoundException e) { }
catch (NotFoundException e)
{
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }
private void add(byte[] bytes, String entryName ,JarOutputStream target) throws IOException { private void add(byte[] bytes, String entryName, JarOutputStream target) throws IOException
BufferedInputStream in = null;
try {
JarEntry entry = new JarEntry(entryName);
target.putNextEntry(entry);
target.write(bytes);
target.closeEntry();
} finally {
if (in != null)
in.close();
}
}
private static Certificate[] getJagexCertificateChain() throws CertificateException
{ {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); JarEntry entry = new JarEntry(entryName);
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt")); target.putNextEntry(entry);
return certificates.toArray(new Certificate[certificates.size()]); target.write(bytes);
target.closeEntry();
} }
public static int getStepCount(String jarFile) { private static int getStepCount(String jarFile)
{
int stepCount = 0; int stepCount = 0;
JarClassLoader jcl = new JarClassLoader(); JarClassLoader jcl = new JarClassLoader();
try { try
{
ClassPool classPool = new ClassPool(true); ClassPool classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar"); classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
} catch (NotFoundException e) { }
catch (NotFoundException e)
{
e.printStackTrace(); e.printStackTrace();
} }
try { try
{
jcl.add(new FileInputStream(jarFile)); jcl.add(new FileInputStream(jarFile));
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFile)))) { try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFile))))
{
JarEntry entry; JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) { while ((entry = in.getNextJarEntry()) != null)
if (entry.getName().endsWith(".class")) { {
if (entry.getName().endsWith(".class"))
{
stepCount++; stepCount++;
} }
} }
} }
} catch (Exception e) { }
catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} }
return stepCount; return stepCount;
} }
public static String initHookScrape(String jarFile) { private static String initHookScrape(String jarFile)
{
int currentStep = 0; int currentStep = 0;
RuneLite.splashScreen.setMessage("Analyzing injected client"); RuneLite.splashScreen.setMessage("Analyzing injected client");
List protectedStuff = new ArrayList<String>(); List<String> protectedStuff = new ArrayList<>();
String clientInstance = ""; String clientInstance = "";
JarClassLoader jcl = new JarClassLoader(); JarClassLoader jcl = new JarClassLoader();
try { try
ClassPool classPool = new ClassPool(true); {
classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar"); ClassPool classPool = new ClassPool(true);
} catch (NotFoundException e) { classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
e.printStackTrace(); }
} catch (NotFoundException e)
{
e.printStackTrace();
}
try { try
jcl.add(new FileInputStream(jarFile)); {
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFile)))) { jcl.add(new FileInputStream(jarFile));
JarEntry entry; try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFile))))
while ((entry = in.getNextJarEntry()) != null) { {
if (entry.getName().endsWith(".class")) { JarEntry entry;
File temp = new File(jarFile); while ((entry = in.getNextJarEntry()) != null)
ClassLoader cl = ClassLoader.getSystemClassLoader(); {
try { if (entry.getName().endsWith(".class"))
URLClassLoader child = new URLClassLoader( {
new URL[] {temp.toURI().toURL()}, File temp = new File(jarFile);
cl ClassLoader cl = ClassLoader.getSystemClassLoader();
); try
try { {
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child); URLClassLoader child = new URLClassLoader(
RuneLite.splashScreen.setSubMessage(entry.getName()); new URL[]{temp.toURI().toURL()},
currentStep++; cl
RuneLite.splashScreen.setProgress(currentStep, stepCount); );
JarClassLoader jcl2 = new JarClassLoader(); try
try { {
jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile)); Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
Field[] fields = classToLoad.getDeclaredFields(); RuneLite.splashScreen.setSubMessage(entry.getName());
Method[] methods = classToLoad.getDeclaredMethods(); currentStep++;
for (Field f : fields) { RuneLite.splashScreen.setProgress(currentStep, stepCount);
try { JarClassLoader jcl2 = new JarClassLoader();
if (f.getName().contains("$")) { try
System.out.println(classToLoad.getName()+"."+f.getName()); {
protectedStuff.add(classToLoad.getName()+"."+f.getName()); jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile));
Field[] fields = classToLoad.getDeclaredFields();
Method[] methods = classToLoad.getDeclaredMethods();
for (Field f : fields)
{
try
{
if (f.getName().contains("$"))
{
System.out.println(classToLoad.getName() + "." + f.getName());
protectedStuff.add(classToLoad.getName() + "." + f.getName());
} }
if (f.getType().getName()=="client") { if (f.getType().getName().equals("client"))
ByteCodePatcher.hooks.clientInstance = classToLoad.getName()+"."+f.getName(); {
clientInstance = classToLoad.getName()+"."+f.getName(); ByteCodePatcher.hooks.clientInstance = classToLoad.getName() + "." + f.getName();
} clientInstance = classToLoad.getName() + "." + f.getName();
} catch (Exception e) { }
e.printStackTrace(); }
} catch (Exception e)
} {
for (Method m : methods) { e.printStackTrace();
RuneLite.splashScreen.setSubMessage("Checked "+m.getName());
if (m.getName().contains("$")) {
protectedStuff.add(classToLoad.getName()+"."+m.getName());
} }
} }
RuneLite.splashScreen.setProgress(currentStep, stepCount); for (Method m : methods)
} catch (FileNotFoundException e) { {
e.printStackTrace(); RuneLite.splashScreen.setSubMessage("Checked " + m.getName());
} if (m.getName().contains("$"))
} catch (Exception e) { {
e.printStackTrace(); protectedStuff.add(classToLoad.getName() + "." + m.getName());
} }
}
RuneLite.splashScreen.setProgress(currentStep, stepCount);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
catch (Exception e)
{
e.printStackTrace();
}
RuneLite.splashScreen.setProgress(2, 5); RuneLite.splashScreen.setProgress(2, 5);
} catch (Exception e) { }
e.printStackTrace(); catch (Exception e)
System.out.println("Class not found: "+entry.getName()); {
} e.printStackTrace();
} System.out.println("Class not found: " + entry.getName());
} }
} }
} catch (Exception e) { }
e.printStackTrace(); }
} }
int i = 0; catch (Exception e)
for (Object o : protectedStuff) { {
e.printStackTrace();
}
int i = 0;
for (String ignored : protectedStuff)
{
i++; i++;
} }
preotectedStuffs = new String[i];
i = 0; preotectedStuffs = new String[i];
for (Object o : protectedStuff) { i = 0;
preotectedStuffs[i] = (String) o;
for (String o : protectedStuff)
{
preotectedStuffs[i] = o;
i++; i++;
} }
return clientInstance;
} return clientInstance;
}
} }

View File

@@ -2,20 +2,6 @@ package net.runelite.client.rs.bytecode;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import net.runelite.client.RuneLite;
import net.runelite.client.rs.ClientLoader;
import net.runelite.client.rs.bytecode.transformers.ActorTransform;
import net.runelite.client.rs.bytecode.transformers.ClientTransform;
import net.runelite.client.rs.bytecode.transformers.ErrorTransform;
import net.runelite.client.rs.bytecode.transformers.PlayerTransform;
import net.runelite.client.rs.bytecode.transformers.ProjectileTransform;
import net.runelite.http.api.RuneLiteAPI;
import org.xeustechnologies.jcl.JarClassLoader;
import javax.swing.*;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -29,26 +15,42 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarInputStream; import java.util.jar.JarInputStream;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import net.runelite.client.RuneLite;
import net.runelite.client.rs.ClientLoader;
import net.runelite.client.rs.bytecode.transformers.ActorTransform;
import net.runelite.client.rs.bytecode.transformers.ClientTransform;
import net.runelite.client.rs.bytecode.transformers.ErrorTransform;
import net.runelite.client.rs.bytecode.transformers.PlayerTransform;
import net.runelite.client.rs.bytecode.transformers.ProjectileTransform;
import net.runelite.http.api.RuneLiteAPI;
import org.xeustechnologies.jcl.JarClassLoader;
public class ByteCodePatcher { public class ByteCodePatcher
{
public static List<CtClass> modifiedClasses = new ArrayList<>(); public static List<CtClass> modifiedClasses = new ArrayList<>();
public static Hooks hooks = new Hooks(); public static Hooks hooks = new Hooks();
public static String clientInstance; public static String clientInstance;
public static JarClassLoader jcl = new JarClassLoader(); private static JarClassLoader jcl = new JarClassLoader();
public static ClassPool classPool = null; public static ClassPool classPool = null;
public static ClassLoader cl = ClassLoader.getSystemClassLoader(); private static ClassLoader cl = ClassLoader.getSystemClassLoader();
public static int classCount = 0; private static int classCount = 0;
public static void applyHooks(File jf, Hooks hooks) { public static void applyHooks(File jf, Hooks hooks)
{
RuneLite.splashScreen.setProgress(0, 5); RuneLite.splashScreen.setProgress(0, 5);
RuneLite.splashScreen.setMessage("Applying cached bytecode patches..."); RuneLite.splashScreen.setMessage("Applying cached bytecode patches...");
try { try
{
URLClassLoader child = new URLClassLoader( URLClassLoader child = new URLClassLoader(
new URL[] {jf.toURI().toURL()}, new URL[]{jf.toURI().toURL()},
cl cl
); );
try { try
{
RuneLite.splashScreen.setSubMessage("Transforming Actor"); RuneLite.splashScreen.setSubMessage("Transforming Actor");
Class actorClass = Class.forName(hooks.actorClass, false, child); Class actorClass = Class.forName(hooks.actorClass, false, child);
transformActor(actorClass); transformActor(actorClass);
@@ -69,157 +71,196 @@ public class ByteCodePatcher {
transformClient(clientClass); transformClient(clientClass);
RuneLite.splashScreen.setProgress(4, 5); RuneLite.splashScreen.setProgress(4, 5);
//Odds and ends // Odds and ends
RuneLite.splashScreen.setSubMessage("Transforming Error method"); RuneLite.splashScreen.setSubMessage("Transforming Error method");
ErrorTransform et = new ErrorTransform(); ErrorTransform et = new ErrorTransform();
et.modify(null); et.modify(null);
RuneLite.splashScreen.setProgress(5, 5); RuneLite.splashScreen.setProgress(5, 5);
RuneLite.splashScreen.setSubMessage(""); RuneLite.splashScreen.setSubMessage("");
ByteCodeUtils.updateHijackedJar(); ByteCodeUtils.updateHijackedJar();
} catch (Exception e) { }
catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} }
} catch (Exception e) { }
catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void findHooks(String jf) { public static void findHooks(String jf)
{
RuneLite.splashScreen.setMessage("Hijacking Classes"); RuneLite.splashScreen.setMessage("Hijacking Classes");
try { try
{
classPool = new ClassPool(true); classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar"); classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
} catch (NotFoundException e) { }
catch (NotFoundException e)
{
e.printStackTrace(); e.printStackTrace();
} }
try { try
{
jcl.add(new FileInputStream(jf)); jcl.add(new FileInputStream(jf));
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf)))) { try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf))))
{
JarEntry entry; JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) { while ((entry = in.getNextJarEntry()) != null)
if (entry.getName().endsWith(".class")) { {
if (entry.getName().endsWith(".class"))
{
classCount++; classCount++;
} }
} }
} }
int i = 0; int i = 0;
jcl.add(new FileInputStream(jf)); jcl.add(new FileInputStream(jf));
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf)))) { try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf))))
{
JarEntry entry; JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) { while ((entry = in.getNextJarEntry()) != null)
if (entry.getName().endsWith(".class")) { {
if (entry.getName().endsWith(".class"))
{
RuneLite.splashScreen.setProgress(i, classCount); RuneLite.splashScreen.setProgress(i, classCount);
RuneLite.splashScreen.setSubMessage("Checking "+entry.getName()); RuneLite.splashScreen.setSubMessage("Checking " + entry.getName());
checkClasses(new File(jf), entry); checkClasses(new File(jf), entry);
i++; i++;
} }
} }
} }
} catch (Exception e) { }
catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} }
Gson gson = new GsonBuilder().setPrettyPrinting().create(); Gson gson = new GsonBuilder().setPrettyPrinting().create();
try { try
{
Writer writer = new FileWriter(ClientLoader.hooksFile); Writer writer = new FileWriter(ClientLoader.hooksFile);
gson.toJson(hooks, writer); gson.toJson(hooks, writer);
writer.flush(); writer.flush();
writer.close(); writer.close();
} catch (IOException e) { }
catch (IOException e)
{
e.printStackTrace(); e.printStackTrace();
} }
ByteCodeUtils.updateHijackedJar(); ByteCodeUtils.updateHijackedJar();
} }
public static void checkClasses(File jf, JarEntry entry) { private static void checkClasses(File jf, JarEntry entry)
try { {
try
{
URLClassLoader child = new URLClassLoader( URLClassLoader child = new URLClassLoader(
new URL[] {jf.toURI().toURL()}, new URL[]{jf.toURI().toURL()},
cl cl
); );
try { try
{
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child); Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
checkActor(classToLoad); checkActor(classToLoad);
checkProjectile(classToLoad); checkProjectile(classToLoad);
checkPlayer(classToLoad); checkPlayer(classToLoad);
} catch (Exception e) { }
catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} }
} catch (Exception e) { }
catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
System.out.println("Class not found: "+entry.getName()); System.out.println("Class not found: " + entry.getName());
} }
} }
public static void checkActor(Class current) { private static void checkActor(Class current)
try { {
Method method = current.getDeclaredMethod("setCombatInfo", new Class[] { int.class, int.class, int.class, int.class, int.class, int.class }); try
if (method!=null) { {
Method method = current.getDeclaredMethod("setCombatInfo", new Class[]{int.class, int.class, int.class, int.class, int.class, int.class});
if (method != null)
{
hooks.actorClass = current.getName(); hooks.actorClass = current.getName();
System.out.println("[RuneLitePlus] Transforming Actor at class: "+current.getName()); System.out.println("[RuneLitePlus] Transforming Actor at class: " + current.getName());
ActorTransform at = new ActorTransform(); ActorTransform at = new ActorTransform();
at.modify(current); at.modify(current);
} }
} catch (NoSuchMethodException e) { }
//e.printStackTrace(); catch (NoSuchMethodException | NoClassDefFoundError e) {
} catch (NoClassDefFoundError e) { e.printStackTrace();
//e.printStackTrace();
} }
} }
public static void transformActor(Class actor) { private static void transformActor(Class actor)
System.out.println("[RuneLitePlus] Transforming Actor at class: "+actor.getName()); {
System.out.println("[RuneLitePlus] Transforming Actor at class: " + actor.getName());
ActorTransform at = new ActorTransform(); ActorTransform at = new ActorTransform();
at.modify(actor); at.modify(actor);
} }
public static void checkProjectile(Class current) { private static void checkProjectile(Class current)
try { {
Method method = current.getDeclaredMethod("projectileMoved", new Class[] { int.class, int.class, int.class, int.class}); try
if (method!=null) { {
Method method = current.getDeclaredMethod("projectileMoved", new Class[]{int.class, int.class, int.class, int.class});
if (method != null)
{
hooks.projectileClass = current.getName(); hooks.projectileClass = current.getName();
System.out.println("[RuneLitePlus] Transforming Projectile at class: "+current.getName()); System.out.println("[RuneLitePlus] Transforming Projectile at class: " + current.getName());
ProjectileTransform pt = new ProjectileTransform(); ProjectileTransform pt = new ProjectileTransform();
pt.modify(current); pt.modify(current);
} }
} catch (NoSuchMethodException e) { }
//e.printStackTrace(); catch (NoSuchMethodException | NoClassDefFoundError e)
} catch (NoClassDefFoundError e) { {
//e.printStackTrace(); e.printStackTrace();
} }
} }
public static void transformProjectile(Class projectile) { private static void transformProjectile(Class projectile)
System.out.println("[RuneLitePlus] Transforming Projectile at class: "+projectile.getName()); {
System.out.println("[RuneLitePlus] Transforming Projectile at class: " + projectile.getName());
ProjectileTransform pt = new ProjectileTransform(); ProjectileTransform pt = new ProjectileTransform();
pt.modify(projectile); pt.modify(projectile);
} }
public static void checkPlayer(Class current) { private static void checkPlayer(Class current)
try { {
try
{
Method method = current.getDeclaredMethod("getSkullIcon"); Method method = current.getDeclaredMethod("getSkullIcon");
if (method!=null) { if (method != null)
{
hooks.playerClass = current.getName(); hooks.playerClass = current.getName();
System.out.println("[RuneLitePlus] Transforming Player at class: "+current.getName()); System.out.println("[RuneLitePlus] Transforming Player at class: " + current.getName());
PlayerTransform pt = new PlayerTransform(); PlayerTransform pt = new PlayerTransform();
pt.modify(current); pt.modify(current);
} }
} catch (NoSuchMethodException e) { }
//e.printStackTrace(); catch (NoSuchMethodException | NoClassDefFoundError e)
} catch (NoClassDefFoundError e) { {
//e.printStackTrace(); e.printStackTrace();
} }
} }
public static void transformPlayer(Class player) { private static void transformPlayer(Class player)
System.out.println("[RuneLitePlus] Transforming Player at class: "+player.getName()); {
System.out.println("[RuneLitePlus] Transforming Player at class: " + player.getName());
PlayerTransform pt = new PlayerTransform(); PlayerTransform pt = new PlayerTransform();
pt.modify(player); pt.modify(player);
} }
public static void transformClient(Class clazz) { private static void transformClient(Class clazz)
{
System.out.println("[RuneLitePlus] Transforming Client"); System.out.println("[RuneLitePlus] Transforming Client");
ClientTransform bt = new ClientTransform(); ClientTransform bt = new ClientTransform();
bt.modify(clazz); bt.modify(clazz);

View File

@@ -1,9 +1,5 @@
package net.runelite.client.rs.bytecode; package net.runelite.client.rs.bytecode;
import javassist.CtClass;
import net.runelite.client.RuneLite;
import net.runelite.http.api.RuneLiteAPI;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@@ -19,99 +15,127 @@ import java.util.jar.JarOutputStream;
import java.util.jar.Manifest; import java.util.jar.Manifest;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import javassist.CtClass;
import net.runelite.client.RuneLite;
import net.runelite.http.api.RuneLiteAPI;
public class ByteCodeUtils { public class ByteCodeUtils
//TODO: Write method to delete old revision injected clients. {
public static File injectedClientFile = new File(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar"); //TODO: Write method to delete old revision injected clients.
public static File hijackedClientFile = new File(RuneLite.RUNELITE_DIR+"/hijackedClient-"+ RuneLiteAPI.getVersion() +"-.jar"); public static File injectedClientFile = new File(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
public static File hijackedClientFile = new File(RuneLite.RUNELITE_DIR + "/hijackedClient-" + RuneLiteAPI.getVersion() + "-.jar");
public static JarOutputStream target; public static JarOutputStream target;
public static void updateHijackedJar() { static void updateHijackedJar()
Manifest manifest = new Manifest(); {
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); Manifest manifest = new Manifest();
try { manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
target = new JarOutputStream(new FileOutputStream(hijackedClientFile), manifest); try
} catch (IOException e) { {
e.printStackTrace(); target = new JarOutputStream(new FileOutputStream(hijackedClientFile), manifest);
} }
try { catch (IOException e)
List<String> classesToSkip = new ArrayList<>(); {
for (CtClass ct : ByteCodePatcher.modifiedClasses) { e.printStackTrace();
classesToSkip.add(ct.getName()); }
} try
{
JarFile original = new JarFile(injectedClientFile);
Enumeration<JarEntry> entries = original.entries();
while (entries.hasMoreElements())
{
JarEntry entry = entries.nextElement();
boolean skip = false;
for (CtClass ct : ByteCodePatcher.modifiedClasses)
{
if ((ct.getName() + ".class").equals(entry.getName()))
{
skip = true;
}
}
if (!skip)
{
add(entry);
}
}
JarFile original = new JarFile(injectedClientFile); for (CtClass ct : ByteCodePatcher.modifiedClasses)
Enumeration<JarEntry> entries = original.entries(); {
while (entries.hasMoreElements()) { add(ct);
JarEntry entry = entries.nextElement(); }
boolean skip = false;
for (CtClass ct : ByteCodePatcher.modifiedClasses) {
if ((ct.getName()+".class").equals(entry.getName())) {
skip = true;
}
}
if (!skip)
add(entry);
}
for (CtClass ct : ByteCodePatcher.modifiedClasses) { target.close();
add(ct); }
} catch (Exception e)
{
e.printStackTrace();
}
}
target.close(); private static void add(CtClass ct)
} catch (Exception e) { {
e.printStackTrace(); try
} {
} JarEntry newEntry = new JarEntry(ct.getName() + ".class");
target.putNextEntry(newEntry);
target.write(ct.toBytecode());
target.closeEntry();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void add(CtClass ct) { private static void add(JarEntry entry) throws IOException
try { {
JarEntry newEntry = new JarEntry(ct.getName()+".class"); try
target.putNextEntry(newEntry); {
target.write(ct.toBytecode()); if (!entry.getName().startsWith("META") && !entry.getName().equals(""))
target.closeEntry(); {
} catch (Exception e) { target.putNextEntry(entry);
e.printStackTrace(); target.write(getBytesFromZipFile(entry.getName()));
} target.closeEntry();
} }
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void add(JarEntry entry) throws IOException { private static byte[] getBytesFromZipFile(String entryName)
try { {
if (!entry.getName().startsWith("META")&&!entry.getName().equals("")) { ZipFile zipFile;
target.putNextEntry(entry); try
target.write(getBytesFromZipFile(entry.getName())); {
target.closeEntry(); zipFile = new ZipFile(injectedClientFile);
} Enumeration<? extends ZipEntry> entries = zipFile.entries();
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] getBytesFromZipFile(String entryName) { while (entries.hasMoreElements())
ZipFile zipFile; {
try { ZipEntry entry = entries.nextElement();
zipFile = new ZipFile(injectedClientFile); if (entry.getName().equals(entryName))
Enumeration<? extends ZipEntry> entries = zipFile.entries(); {
InputStream stream = zipFile.getInputStream(entry);
while(entries.hasMoreElements()){ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ZipEntry entry = entries.nextElement(); int nRead;
if (entry.getName().equals(entryName)) { byte[] data = new byte[1024];
InputStream stream = zipFile.getInputStream(entry); while ((nRead = stream.read(data, 0, data.length)) != -1)
{
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); buffer.write(data, 0, nRead);
int nRead; }
byte[] data = new byte[1024]; buffer.flush();
while ((nRead = stream.read(data, 0, data.length)) != -1) { return buffer.toByteArray();
buffer.write(data, 0, nRead); }
} }
buffer.flush(); }
return buffer.toByteArray(); catch (IOException e)
} {
} e.printStackTrace();
} catch (IOException e) { }
e.printStackTrace(); return null;
} }
return null;
}
} }

View File

@@ -7,64 +7,77 @@ import javassist.CtNewMethod;
import javassist.NotFoundException; import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher; import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class ActorTransform implements Transform { public class ActorTransform implements Transform
private CtClass ct; {
private CtClass ct;
@Override @Override
public void modify(Class actor) { public void modify(Class actor)
try {
ct = ByteCodePatcher.classPool.get(actor.getName());
transformGetAnimation();
transformAnimationChanged();
transformGraphicChanged();
ByteCodePatcher.modifiedClasses.add(ct);
} catch (CannotCompileException | NotFoundException e) {
e.printStackTrace();
}
}
private void transformGetAnimation() throws CannotCompileException, NotFoundException
{ {
CtMethod protectedAnimation = ct.getDeclaredMethod("1protect$getRsAnimation"); try
ct.removeMethod(protectedAnimation); {
ct = ByteCodePatcher.classPool.get(actor.getName());
protectedAnimation.setName("getRsAnimation"); transformGetAnimation();
ct.addMethod(protectedAnimation); transformAnimationChanged();
transformGraphicChanged();
CtMethod getAnimation = ct.getDeclaredMethod("getAnimation"); ByteCodePatcher.modifiedClasses.add(ct);
ct.removeMethod(getAnimation); }
catch (CannotCompileException | NotFoundException e)
{
e.printStackTrace();
}
}
getAnimation = CtNewMethod.make("public int getAnimation() { return this.getRsAnimation(); }",ct); private void transformGetAnimation() throws CannotCompileException, NotFoundException
ct.addMethod(getAnimation);
}
private void transformAnimationChanged() throws CannotCompileException, NotFoundException
{ {
CtMethod getAnimationChanged = ct.getDeclaredMethod("animationChanged", new CtClass[]{CtClass.intType}); CtMethod protectedAnimation = ct.getDeclaredMethod("1protect$getRsAnimation");
ct.removeMethod(getAnimationChanged); ct.removeMethod(protectedAnimation);
getAnimationChanged = CtNewMethod.make( protectedAnimation.setName("getRsAnimation");
"public void animationChanged(int n) { " + ct.addMethod(protectedAnimation);
"net.runelite.api.events.AnimationChanged animationChanged = new net.runelite.api.events.AnimationChanged();" +
"animationChanged.setActor((net.runelite.api.Actor)this);" +
ByteCodePatcher.clientInstance + ".getCallbacks().post((java.lang.Object)animationChanged); }", ct);
ct.addMethod(getAnimationChanged);
}
private void transformGraphicChanged() throws CannotCompileException, NotFoundException CtMethod getAnimation = ct.getDeclaredMethod("getAnimation");
ct.removeMethod(getAnimation);
getAnimation = CtNewMethod.make(
"public int getAnimation()" +
"{" +
" return this.getRsAnimation();" +
"}", ct);
ct.addMethod(getAnimation);
}
private void transformAnimationChanged() throws CannotCompileException, NotFoundException
{
CtMethod getAnimationChanged = ct.getDeclaredMethod("animationChanged", new CtClass[]{CtClass.intType});
ct.removeMethod(getAnimationChanged);
getAnimationChanged = CtNewMethod.make(
"public void animationChanged(int n)" +
"{" +
" net.runelite.api.events.AnimationChanged animationChanged = new net.runelite.api.events.AnimationChanged();" +
" animationChanged.setActor((net.runelite.api.Actor) this);" +
ByteCodePatcher.clientInstance + ".getCallbacks().post((java.lang.Object)animationChanged);" +
"}", ct);
ct.addMethod(getAnimationChanged);
}
private void transformGraphicChanged() throws CannotCompileException, NotFoundException
{ {
CtMethod graphicChanged = ct.getDeclaredMethod("graphicChanged", new CtClass[]{CtClass.intType}); CtMethod graphicChanged = ct.getDeclaredMethod("graphicChanged", new CtClass[]{CtClass.intType});
ct.removeMethod(graphicChanged); ct.removeMethod(graphicChanged);
graphicChanged = CtNewMethod.make( graphicChanged = CtNewMethod.make(
"public void graphicChanged(int paramInt){" + "public void graphicChanged(int paramInt)" +
"net.runelite.api.events.GraphicChanged localGraphicChanged = new net.runelite.api.events.GraphicChanged();" + "{" +
"localGraphicChanged.setActor(this);" + " net.runelite.api.events.GraphicChanged localGraphicChanged = new net.runelite.api.events.GraphicChanged();" +
ByteCodePatcher.clientInstance+".getCallbacks().post(localGraphicChanged);}",ct); " localGraphicChanged.setActor(this);" +
ByteCodePatcher.clientInstance + ".getCallbacks().post(localGraphicChanged);" +
"}", ct);
ct.addMethod(graphicChanged); ct.addMethod(graphicChanged);
} }
} }

View File

@@ -10,13 +10,16 @@ import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool; import javassist.bytecode.ConstPool;
import net.runelite.client.rs.bytecode.ByteCodePatcher; import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class ClientTransform implements Transform { public class ClientTransform implements Transform
{
private CtClass ct; private CtClass ct;
@Override @Override
public void modify(Class clazz) { public void modify(Class clazz)
try { {
try
{
ct = ByteCodePatcher.classPool.get(clazz.getName()); ct = ByteCodePatcher.classPool.get(clazz.getName());
transformProtectedGetMenuOptions(); transformProtectedGetMenuOptions();
@@ -28,15 +31,17 @@ public class ClientTransform implements Transform {
transformGetMenuEntries(); transformGetMenuEntries();
transformSetMenuEntries(); transformSetMenuEntries();
transformOnMenuOptionsChanged(); transformOnMenuOptionsChanged();
transformGetProjectiles(); transformGetProjectiles();
transformGetCollisionMaps(); transformGetCollisionMaps();
transformDraw2010Menu(); transformDraw2010Menu();
transformRenderSelf(); transformRenderSelf();
transformboundingBoxCheck(); transformboundingBoxCheck();
transformcheckClickBox(); transformcheckClickBox();
ByteCodePatcher.modifiedClasses.add(ct); ByteCodePatcher.modifiedClasses.add(ct);
} catch (Exception e) { }
catch (Exception e)
{
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -52,38 +57,38 @@ public class ClientTransform implements Transform {
ct.addMethod(protectedGetMenuOptions); ct.addMethod(protectedGetMenuOptions);
} }
private void transformGetProjectiles() throws CannotCompileException, NotFoundException private void transformGetProjectiles() throws CannotCompileException, NotFoundException
{ {
CtMethod getProjectiles; CtMethod getProjectiles;
CtMethod getProjectilesDeque = ct.getDeclaredMethod("1protect$getProjectilesDeque"); CtMethod getProjectilesDeque = ct.getDeclaredMethod("1protect$getProjectilesDeque");
ct.removeMethod(getProjectilesDeque); ct.removeMethod(getProjectilesDeque);
getProjectilesDeque.setName("getProjectilesDeque"); getProjectilesDeque.setName("getProjectilesDeque");
ct.addMethod(getProjectilesDeque); ct.addMethod(getProjectilesDeque);
getProjectiles = ct.getDeclaredMethod("getProjectiles"); getProjectiles = ct.getDeclaredMethod("getProjectiles");
ct.removeMethod(getProjectiles); ct.removeMethod(getProjectiles);
getProjectiles = CtNewMethod.make( getProjectiles = CtNewMethod.make(
"public java.util.List getProjectiles() { " + "public java.util.List getProjectiles() { " +
"java.util.ArrayList localArrayList = new java.util.ArrayList();" + "java.util.ArrayList localArrayList = new java.util.ArrayList();" +
"net.runelite.rs.api.RSDeque localRSDeque = getProjectilesDeque();" + "net.runelite.rs.api.RSDeque localRSDeque = getProjectilesDeque();" +
"net.runelite.rs.api.RSNode localRSNode = localRSDeque.getHead();" + "net.runelite.rs.api.RSNode localRSNode = localRSDeque.getHead();" +
"for (net.runelite.api.Node localNode = localRSNode.getNext(); localNode != localRSNode; localNode = localNode.getNext()) {" + "for (net.runelite.api.Node localNode = localRSNode.getNext(); localNode != localRSNode; localNode = localNode.getNext()) {" +
"net.runelite.api.Projectile localProjectile = (net.runelite.api.Projectile)localNode;" + "net.runelite.api.Projectile localProjectile = (net.runelite.api.Projectile)localNode;" +
"localArrayList.add(localProjectile); }" + "localArrayList.add(localProjectile); }" +
"return localArrayList; }", ct); "return localArrayList; }", ct);
ct.addMethod(getProjectiles); ct.addMethod(getProjectiles);
ClassFile classFile = ct.getClassFile(); ClassFile classFile = ct.getClassFile();
ConstPool constPool = classFile.getConstPool(); ConstPool constPool = classFile.getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag); AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation("Override", constPool); javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation("Override", constPool);
attr.setAnnotation(annotation); attr.setAnnotation(annotation);
getProjectiles.getMethodInfo().addAttribute(attr); getProjectiles.getMethodInfo().addAttribute(attr);
System.out.println("Added override annotation for getprojectiles"); System.out.println("Added override annotation for getprojectiles");
} }
private void transformProtectedGetMenuTargets() throws CannotCompileException, NotFoundException private void transformProtectedGetMenuTargets() throws CannotCompileException, NotFoundException
{ {
@@ -96,22 +101,22 @@ public class ClientTransform implements Transform {
ct.addMethod(protectedGetMenuTargets); ct.addMethod(protectedGetMenuTargets);
} }
private void transformGetCollisionMaps() throws CannotCompileException, NotFoundException private void transformGetCollisionMaps() throws CannotCompileException, NotFoundException
{ {
CtMethod getCollisionMaps; CtMethod getCollisionMaps;
CtMethod protectedMaps = ct.getDeclaredMethod("1protect$getRsCollisionMaps"); CtMethod protectedMaps = ct.getDeclaredMethod("1protect$getRsCollisionMaps");
ct.removeMethod(protectedMaps); ct.removeMethod(protectedMaps);
protectedMaps.setName("getRsCollisionMaps"); protectedMaps.setName("getRsCollisionMaps");
ct.addMethod(protectedMaps); ct.addMethod(protectedMaps);
getCollisionMaps = ct.getDeclaredMethod("getCollisionMaps"); getCollisionMaps = ct.getDeclaredMethod("getCollisionMaps");
ct.removeMethod(getCollisionMaps); ct.removeMethod(getCollisionMaps);
getCollisionMaps = CtMethod.make("public net.runelite.rs.api.RSCollisionData[] getCollisionMaps() { return getRsCollisionMaps(); }", ct); getCollisionMaps = CtMethod.make("public net.runelite.rs.api.RSCollisionData[] getCollisionMaps() { return getRsCollisionMaps(); }", ct);
ct.addMethod(getCollisionMaps); ct.addMethod(getCollisionMaps);
} }
private void transformProtectedGetMenuIdentifiers() throws CannotCompileException, NotFoundException private void transformProtectedGetMenuIdentifiers() throws CannotCompileException, NotFoundException
{ {
@@ -130,7 +135,7 @@ public class ClientTransform implements Transform {
protectedGetMenuTypes = ct.getDeclaredMethod("1protect$getMenuTypes"); protectedGetMenuTypes = ct.getDeclaredMethod("1protect$getMenuTypes");
// Don't remove as this is referenced elsewhere in client // Don't remove as this is referenced elsewhere in client
//ct.removeMethod(protectedGetMenuTypes); // ct.removeMethod(protectedGetMenuTypes);
CtMethod newProtectedGetMenuTypes = CtNewMethod.copy(protectedGetMenuTypes, ct, null); CtMethod newProtectedGetMenuTypes = CtNewMethod.copy(protectedGetMenuTypes, ct, null);
newProtectedGetMenuTypes.setName("getMenuTypes"); newProtectedGetMenuTypes.setName("getMenuTypes");
@@ -167,71 +172,79 @@ public class ClientTransform implements Transform {
ct.removeMethod(getMenuEntries); ct.removeMethod(getMenuEntries);
getMenuEntries = CtMethod.make( getMenuEntries = CtMethod.make(
"public net.runelite.api.MenuEntry[] getMenuEntries() {" + "public net.runelite.api.MenuEntry[] getMenuEntries()" +
"int n2 = this.getMenuOptionCount();"+ "{" +
"String[] arrstring = this.getMenuOptions();"+ " int n2 = this.getMenuOptionCount();" +
"String[] arrstring2 = this.getMenuTargets();"+ " String[] arrstring = this.getMenuOptions();" +
"int[] arrn = this.getMenuIdentifiers();"+ " String[] arrstring2 = this.getMenuTargets();" +
"int[] arrn2 = this.getMenuTypes();"+ " int[] arrn = this.getMenuIdentifiers();" +
"int[] arrn3 = this.getMenuActionParams0();"+ " int[] arrn2 = this.getMenuTypes();" +
"int[] arrn4 = this.getMenuActionParams1();"+ " int[] arrn3 = this.getMenuActionParams0();" +
"boolean[] arrbl = this.getMenuForceLeftClick();"+ " int[] arrn4 = this.getMenuActionParams1();" +
"net.runelite.api.MenuEntry[] arrmenuEntry = new net.runelite.api.MenuEntry[n2];"+ " boolean[] arrbl = this.getMenuForceLeftClick();" +
"int n3 = 0;"+ " net.runelite.api.MenuEntry[] arrmenuEntry = new net.runelite.api.MenuEntry[n2];" +
"while (n3 < n2) {"+ " int n3 = 0;" +
"net.runelite.api.MenuEntry menuEntry = arrmenuEntry[n3] = new net.runelite.api.MenuEntry();"+ " while (n3 < n2) " +
"menuEntry.setOption(arrstring[n3]);"+ " {" +
"menuEntry.setTarget(arrstring2[n3]);"+ " net.runelite.api.MenuEntry menuEntry = arrmenuEntry[n3] = new net.runelite.api.MenuEntry();" +
"menuEntry.setIdentifier(arrn[n3]);"+ " menuEntry.setOption(arrstring[n3]);" +
"menuEntry.setType(arrn2[n3]);"+ " menuEntry.setTarget(arrstring2[n3]);" +
"menuEntry.setParam0(arrn3[n3]);"+ " menuEntry.setIdentifier(arrn[n3]);" +
"menuEntry.setParam1(arrn4[n3]);"+ " menuEntry.setType(arrn2[n3]);" +
"menuEntry.setForceLeftClick(arrbl[n3]);"+ " menuEntry.setParam0(arrn3[n3]);" +
"++n3; }"+ " menuEntry.setParam1(arrn4[n3]);" +
"return arrmenuEntry; }", ct); " menuEntry.setForceLeftClick(arrbl[n3]);" +
" ++n3;" +
" }" +
" return arrmenuEntry;" +
"}", ct);
ct.addMethod(getMenuEntries); ct.addMethod(getMenuEntries);
} }
private void transformSetMenuEntries() throws CannotCompileException, NotFoundException { private void transformSetMenuEntries() throws CannotCompileException, NotFoundException
{
CtMethod setMenuEntries; CtMethod setMenuEntries;
setMenuEntries = ct.getDeclaredMethod("setMenuEntries"); setMenuEntries = ct.getDeclaredMethod("setMenuEntries");
ct.removeMethod(setMenuEntries); ct.removeMethod(setMenuEntries);
setMenuEntries = CtNewMethod.make( setMenuEntries = CtNewMethod.make(
"public void setMenuEntries(net.runelite.api.MenuEntry[] arrmenuEntry) {" + "public void setMenuEntries(net.runelite.api.MenuEntry[] arrmenuEntry)" +
"int n2 = 0;" + "{" +
"String[] arrstring = this.getMenuOptions();" + " int n2 = 0;" +
"String[] arrstring2 = this.getMenuTargets();" + " String[] arrstring = this.getMenuOptions();" +
"int[] arrn = this.getMenuIdentifiers();" + " String[] arrstring2 = this.getMenuTargets();" +
"int[] arrn2 = this.getMenuTypes();" + " int[] arrn = this.getMenuIdentifiers();" +
"int[] arrn3 = this.getMenuActionParams0();" + " int[] arrn2 = this.getMenuTypes();" +
"int[] arrn4 = this.getMenuActionParams1();" + " int[] arrn3 = this.getMenuActionParams0();" +
"boolean[] arrbl = getMenuForceLeftClick();" + " int[] arrn4 = this.getMenuActionParams1();" +
"net.runelite.api.MenuEntry[] arrmenuEntry2 = arrmenuEntry;" + " boolean[] arrbl = getMenuForceLeftClick();" +
"int n3 = arrmenuEntry2.length;" + " net.runelite.api.MenuEntry[] arrmenuEntry2 = arrmenuEntry;" +
"int n4 = 0;" + " int n3 = arrmenuEntry2.length;" +
"do {" + " int n4 = 0;" +
"String string;" + " do" +
"if (n4 >= n3) {" + " {" +
"this.setMenuOptionCount(n2);" + " String string;" +
"oldMenuEntryCount = n2;" + " if (n4 >= n3)" +
"return;" + " {" +
"}" + " this.setMenuOptionCount(n2);" +
"net.runelite.api.MenuEntry menuEntry = arrmenuEntry2[n4];" + " oldMenuEntryCount = n2;" +
"int n5 = menuEntry.getType();" + " return;" +
"arrstring[n2] = menuEntry.getOption();" + " }" +
"arrstring2[n2] = menuEntry.getTarget();" + " net.runelite.api.MenuEntry menuEntry = arrmenuEntry2[n4];" +
"arrn[n2] = menuEntry.getIdentifier();" + " int n5 = menuEntry.getType();" +
"arrn2[n2] = n5;" + " arrstring[n2] = menuEntry.getOption();" +
"arrn3[n2] = menuEntry.getParam0();" + " arrstring2[n2] = menuEntry.getTarget();" +
"arrn4[n2] = menuEntry.getParam1();" + " arrn[n2] = menuEntry.getIdentifier();" +
"arrbl[n2] = menuEntry.isForceLeftClick();" + " arrn2[n2] = n5;" +
"++n2;" + " arrn3[n2] = menuEntry.getParam0();" +
"++n4;" + " arrn4[n2] = menuEntry.getParam1();" +
"} while (true);" + " arrbl[n2] = menuEntry.isForceLeftClick();" +
"}" " ++n2;" +
, ct); " ++n4;" +
ct.addMethod(setMenuEntries); " } while (true);" +
"}"
, ct);
ct.addMethod(setMenuEntries);
} }
private void transformOnMenuOptionsChanged() throws CannotCompileException, NotFoundException private void transformOnMenuOptionsChanged() throws CannotCompileException, NotFoundException
@@ -242,23 +255,24 @@ public class ClientTransform implements Transform {
ct.removeMethod(onMenuOptionsChanged); ct.removeMethod(onMenuOptionsChanged);
onMenuOptionsChanged = CtMethod.make( onMenuOptionsChanged = CtMethod.make(
"public static void onMenuOptionsChanged(int n2) {"+ "public static void onMenuOptionsChanged(int n2)" +
"int n3;" + "{" +
"int n4 = oldMenuEntryCount;"+ " int n3;" +
"oldMenuEntryCount = n3 = "+ByteCodePatcher.clientInstance+".getMenuOptionCount();"+ " int n4 = oldMenuEntryCount;" +
"if (n3 != n4 + 1) return;"+ " oldMenuEntryCount = n3 = " + ByteCodePatcher.clientInstance + ".getMenuOptionCount();" +
"net.runelite.api.events.MenuEntryAdded menuEntryAdded = new net.runelite.api.events.MenuEntryAdded("+ " if (n3 != n4 + 1) return;" +
ByteCodePatcher.clientInstance+".getMenuOptions()[n3 - 1],"+ " net.runelite.api.events.MenuEntryAdded menuEntryAdded = new net.runelite.api.events.MenuEntryAdded(" +
ByteCodePatcher.clientInstance+".getMenuTargets()[n3 - 1],"+ ByteCodePatcher.clientInstance + ".getMenuOptions()[n3 - 1]," +
ByteCodePatcher.clientInstance+".getMenuTypes()[n3 - 1],"+ ByteCodePatcher.clientInstance + ".getMenuTargets()[n3 - 1]," +
ByteCodePatcher.clientInstance+".getMenuIdentifiers()[n3 - 1],"+ ByteCodePatcher.clientInstance + ".getMenuTypes()[n3 - 1]," +
ByteCodePatcher.clientInstance+".getMenuActionParams0()[n3 - 1],"+ ByteCodePatcher.clientInstance + ".getMenuIdentifiers()[n3 - 1]," +
ByteCodePatcher.clientInstance+".getMenuActionParams1()[n3 - 1]);"+ ByteCodePatcher.clientInstance + ".getMenuActionParams0()[n3 - 1]," +
ByteCodePatcher.clientInstance+".getCallbacks().post((Object)menuEntryAdded);"+ ByteCodePatcher.clientInstance + ".getMenuActionParams1()[n3 - 1]);" +
ByteCodePatcher.clientInstance + ".getCallbacks().post((Object)menuEntryAdded);" +
"}" "}"
, ct); , ct);
ct.addMethod(onMenuOptionsChanged); ct.addMethod(onMenuOptionsChanged);
} }
private void transformRenderSelf() throws CannotCompileException private void transformRenderSelf() throws CannotCompileException
@@ -285,48 +299,54 @@ public class ClientTransform implements Transform {
ct.removeMethod(draw2010Menu); ct.removeMethod(draw2010Menu);
draw2010Menu = CtNewMethod.make( draw2010Menu = CtNewMethod.make(
"public void draw2010Menu() {" + "public void draw2010Menu()" +
"int n2 = this.getMenuX();" + "{" +
"int n3 = this.getMenuY();" + " int n2 = this.getMenuX();" +
"int n4 = this.getMenuWidth();" + " int n3 = this.getMenuY();" +
"int n5 = this.getMenuHeight();" + " int n4 = this.getMenuWidth();" +
"this.RasterizerDrawHorizontalLine(n2 + 2, n3, n4 - 4, 7170651);" + " int n5 = this.getMenuHeight();" +
"this.RasterizerDrawHorizontalLine(n2 + 2, n3 + n5 - 1, n4 - 4, 7170651);" + " this.RasterizerDrawHorizontalLine(n2 + 2, n3, n4 - 4, 7170651);" +
"this.RasterizerDrawVerticalLine(n2, n3 + 2, n5 - 4, 7170651);" + " this.RasterizerDrawHorizontalLine(n2 + 2, n3 + n5 - 1, n4 - 4, 7170651);" +
"this.RasterizerDrawVerticalLine(n2 + n4 - 1, n3 + 2, n5 - 4, 7170651);" + " this.RasterizerDrawVerticalLine(n2, n3 + 2, n5 - 4, 7170651);" +
"this.RasterizerDrawRectangle(n2 + 1, n3 + 5, n4 - 2, n5 - 6, 2827810);" + " this.RasterizerDrawVerticalLine(n2 + n4 - 1, n3 + 2, n5 - 4, 7170651);" +
"this.RasterizerDrawHorizontalLine(n2 + 1, n3 + 17, n4 - 2, 2827810);" + " this.RasterizerDrawRectangle(n2 + 1, n3 + 5, n4 - 2, n5 - 6, 2827810);" +
"this.RasterizerDrawCircle(n2 + 2, n3 + n5 - 3, 0, 2827810);" + " this.RasterizerDrawHorizontalLine(n2 + 1, n3 + 17, n4 - 2, 2827810);" +
"this.RasterizerDrawCircle(n2 + n4 - 3, n3 + n5 - 3, 0, 2827810);" + " this.RasterizerDrawCircle(n2 + 2, n3 + n5 - 3, 0, 2827810);" +
"this.RasterizerDrawGradient(n2 + 2, n3 + 1, n4 - 4, 16, 3288610, 592388);" + " this.RasterizerDrawCircle(n2 + n4 - 3, n3 + n5 - 3, 0, 2827810);" +
"this.RasterizerFillRectangle(n2 + 1, n3 + 1, 2, 4, 2827810);" + " this.RasterizerDrawGradient(n2 + 2, n3 + 1, n4 - 4, 16, 3288610, 592388);" +
"this.RasterizerFillRectangle(n2 + n4 - 3, n3 + 1, 2, 4, 2827810);" + " this.RasterizerFillRectangle(n2 + 1, n3 + 1, 2, 4, 2827810);" +
"this.RasterizerDrawHorizontalLine(n2 + 2, n3 + 18, n4 - 4, 5392957);" + " this.RasterizerFillRectangle(n2 + n4 - 3, n3 + 1, 2, 4, 2827810);" +
"this.RasterizerDrawHorizontalLine(n2 + 3, n3 + n5 - 3, n4 - 6, 5392957);" + " this.RasterizerDrawHorizontalLine(n2 + 2, n3 + 18, n4 - 4, 5392957);" +
"this.RasterizerDrawVerticalLine(n2 + 2, n3 + 18, n5 - 21, 5392957);" + " this.RasterizerDrawHorizontalLine(n2 + 3, n3 + n5 - 3, n4 - 6, 5392957);" +
"this.RasterizerDrawVerticalLine(n2 + n4 - 3, n3 + 18, n5 - 21, 5392957);" + " this.RasterizerDrawVerticalLine(n2 + 2, n3 + 18, n5 - 21, 5392957);" +
"this.RasterizerFillRectangle(n2 + 3, n3 + 19, n4 - 6, n5 - 22, 2828060);" + " this.RasterizerDrawVerticalLine(n2 + n4 - 3, n3 + 18, n5 - 21, 5392957);" +
"this.RasterizerDrawCircle(n2 + 1, n3 + 1, 0, 7170651);" + " this.RasterizerFillRectangle(n2 + 3, n3 + 19, n4 - 6, n5 - 22, 2828060);" +
"this.RasterizerDrawCircle(n2 + n4 - 2, n3 + 1, 0, 7170651);" + " this.RasterizerDrawCircle(n2 + 1, n3 + 1, 0, 7170651);" +
"this.RasterizerDrawCircle(n2 + 1, n3 + n5 - 2, 0, 7170651);" + " this.RasterizerDrawCircle(n2 + n4 - 2, n3 + 1, 0, 7170651);" +
"this.RasterizerDrawCircle(n2 + n4 - 2, n3 + n5 - 2, 0, 7170651);" + " this.RasterizerDrawCircle(n2 + 1, n3 + n5 - 2, 0, 7170651);" +
"net.runelite.rs.api.RSFont rSFont = this.getFontBold12();" + " this.RasterizerDrawCircle(n2 + n4 - 2, n3 + n5 - 2, 0, 7170651);" +
"rSFont.drawTextLeftAligned(\"Choose Option\", n2 + 3, n3 + 14, 13023381, -1);" + " net.runelite.rs.api.RSFont rSFont = this.getFontBold12();" +
"int n6 = this.getMouseX();" + " rSFont.drawTextLeftAligned(\"Choose Option\", n2 + 3, n3 + 14, 13023381, -1);" +
"int n7 = this.getMouseY();" + " int n6 = this.getMouseX();" +
"int n8 = this.getMenuOptionCount();" + " int n7 = this.getMouseY();" +
"String[] arrstring = this.getMenuTargets();" + " int n8 = this.getMenuOptionCount();" +
"String[] arrstring2 = this.getMenuOptions();" + " String[] arrstring = this.getMenuTargets();" +
"for (int i = 0; i < n8; ++i) {" + " String[] arrstring2 = this.getMenuOptions();" +
"int n9 = n3 + (n8 - 1 - i) * 15 + 31;" + " for (int i = 0; i < n8; ++i)" +
"String string = arrstring2[i];" + " {" +
"if (!arrstring[i].isEmpty()) {" + " int n9 = n3 + (n8 - 1 - i) * 15 + 31;" +
"string = string + \" \" + arrstring[i];" + " String string = arrstring2[i];" +
"}" + " if (!arrstring[i].isEmpty())" +
"rSFont.drawTextLeftAligned(string, n2 + 3, n9, 13023381, -1);" + " {" +
"if (n6 <= n2 || n6 >= n4 + n2 || n7 <= n9 - 13 || n7 >= n9 + 3) continue;" + " string = string + \" \" + arrstring[i];" +
"this.RasterizerFillRectangleAlpha(n2 + 3, n9 - 12, n4 - 6, 15, 16777215, 80);" + " }" +
"}" + " rSFont.drawTextLeftAligned(string, n2 + 3, n9, 13023381, -1);" +
" if (n6 <= n2 || n6 >= n4 + n2 || n7 <= n9 - 13 || n7 >= n9 + 3)" +
" {" +
" continue;" +
" }" +
" this.RasterizerFillRectangleAlpha(n2 + 3, n9 - 12, n4 - 6, 15, 16777215, 80);" +
" }" +
"}" "}"
, ct); , ct);
ct.addMethod(draw2010Menu); ct.addMethod(draw2010Menu);
@@ -338,69 +358,78 @@ public class ClientTransform implements Transform {
CtMethod boundingboxCheck2; CtMethod boundingboxCheck2;
boundingboxCheck2 = CtMethod.make( boundingboxCheck2 = CtMethod.make(
"public boolean boundingboxCheck2(net.runelite.api.Model model, int n2, int n3, int n4) {" + "public boolean boundingboxCheck2(net.runelite.api.Model model, int n2, int n3, int n4)" +
"int n5 = "+ByteCodePatcher.clientInstance+".getCameraPitch();" + "{" +
"int n6 = "+ByteCodePatcher.clientInstance+".getCameraYaw();" + " int n5 = " + ByteCodePatcher.clientInstance + ".getCameraPitch();" +
"int n7 = net.runelite.api.Perspective.SINE[n5];" + " int n6 = " + ByteCodePatcher.clientInstance + ".getCameraYaw();" +
"int n8 = net.runelite.api.Perspective.COSINE[n5];" + " int n7 = net.runelite.api.Perspective.SINE[n5];" +
"int n9 = net.runelite.api.Perspective.SINE[n6];" + " int n8 = net.runelite.api.Perspective.COSINE[n5];" +
"int n10 = net.runelite.api.Perspective.COSINE[n6];" + " int n9 = net.runelite.api.Perspective.SINE[n6];" +
"int n11 = "+ByteCodePatcher.clientInstance+".getCenterX();" + " int n10 = net.runelite.api.Perspective.COSINE[n6];" +
"int n12 = "+ByteCodePatcher.clientInstance+".getCenterY();" + " int n11 = " + ByteCodePatcher.clientInstance + ".getCenterX();" +
"int n13 = "+ByteCodePatcher.clientInstance+".getViewportMouseX();" + " int n12 = " + ByteCodePatcher.clientInstance + ".getCenterY();" +
"int n14 = "+ByteCodePatcher.clientInstance+".getViewportMouseY();" + " int n13 = " + ByteCodePatcher.clientInstance + ".getViewportMouseX();" +
"int n15 = "+ByteCodePatcher.clientInstance+".get3dZoom();" + " int n14 = " + ByteCodePatcher.clientInstance + ".getViewportMouseY();" +
"int n16 = (n13 - n11) * 50 / n15;" + " int n15 = " + ByteCodePatcher.clientInstance + ".get3dZoom();" +
"int n17 = (n14 - n12) * 50 / n15;" + " int n16 = (n13 - n11) * 50 / n15;" +
"int n18 = (n13 - n11) * 10000 / n15;" + " int n17 = (n14 - n12) * 50 / n15;" +
"int n19 = (n14 - n12) * 10000 / n15;" + " int n18 = (n13 - n11) * 10000 / n15;" +
"int n20 = client.rl$rot1(n17, 50, n8, n7);" + " int n19 = (n14 - n12) * 10000 / n15;" +
"int n21 = client.rl$rot2(n17, 50, n8, n7);" + " int n20 = client.rl$rot1(n17, 50, n8, n7);" +
"n17 = n20;" + " int n21 = client.rl$rot2(n17, 50, n8, n7);" +
"n20 = client.rl$rot1(n19, 10000, n8, n7);" + " n17 = n20;" +
"int n22 = client.rl$rot2(n19, 10000, n8, n7);" + " n20 = client.rl$rot1(n19, 10000, n8, n7);" +
"n19 = n20;" + " int n22 = client.rl$rot2(n19, 10000, n8, n7);" +
"n20 = client.rl$rot3(n16, n21, n10, n9);" + " n19 = n20;" +
"n21 = client.rl$rot4(n16, n21, n10, n9);" + " n20 = client.rl$rot3(n16, n21, n10, n9);" +
"n16 = n20;" + " n21 = client.rl$rot4(n16, n21, n10, n9);" +
"n20 = client.rl$rot3(n18, n22, n10, n9);" + " n16 = n20;" +
"n22 = client.rl$rot4(n18, n22, n10, n9);" + " n20 = client.rl$rot3(n18, n22, n10, n9);" +
"int n23 = (n20 - n16) / 2;" + " n22 = client.rl$rot4(n18, n22, n10, n9);" +
"int n24 = (n19 - n17) / 2;" + " int n23 = (n20 - n16) / 2;" +
"int n25 = (n22 - n21) / 2;" + " int n24 = (n19 - n17) / 2;" +
"int n26 = Math.abs(n23);" + " int n25 = (n22 - n21) / 2;" +
"int n27 = Math.abs(n24);" + " int n26 = Math.abs(n23);" +
"int n28 = Math.abs(n25);" + " int n27 = Math.abs(n24);" +
"int n29 = n2 + model.getCenterX();" + " int n28 = Math.abs(n25);" +
"int n30 = n3 + model.getCenterY();" + " int n29 = n2 + model.getCenterX();" +
"int n31 = n4 + model.getCenterZ();" + " int n30 = n3 + model.getCenterY();" +
"int n32 = model.getExtremeX();" + " int n31 = n4 + model.getCenterZ();" +
"int n33 = model.getExtremeY();" + " int n32 = model.getExtremeX();" +
"int n34 = model.getExtremeZ();" + " int n33 = model.getExtremeY();" +
"int n35 = (n16 + n20) / 2;" + " int n34 = model.getExtremeZ();" +
"int n36 = (n17 + n19) / 2;" + " int n35 = (n16 + n20) / 2;" +
"int n37 = (n22 + n21) / 2;" + " int n36 = (n17 + n19) / 2;" +
"int n38 = n35 - n29;" + " int n37 = (n22 + n21) / 2;" +
"int n39 = n36 - n30;" + " int n38 = n35 - n29;" +
"int n40 = n37 - n31;" + " int n39 = n36 - n30;" +
"if (Math.abs(n38) > n32 + n26) {" + " int n40 = n37 - n31;" +
"return false;" + " if (Math.abs(n38) > n32 + n26)" +
"}" + " {" +
"if (Math.abs(n39) > n33 + n27) {" + " return false;" +
"return false;" + " }" +
"}" + " if (Math.abs(n39) > n33 + n27)" +
"if (Math.abs(n40) > n34 + n28) {" + " {" +
"return false;" + " return false;" +
"}" + " }" +
"if (Math.abs(n40 * n24 - n39 * n25) > n33 * n28 + n34 * n27) {" + " if (Math.abs(n40) > n34 + n28)" +
"return false;" + " {" +
"}" + " return false;" +
"if (Math.abs(n38 * n25 - n40 * n23) > n34 * n26 + n32 * n28) {" + " }" +
"return false;" + " if (Math.abs(n40 * n24 - n39 * n25) > n33 * n28 + n34 * n27)" +
"}" + " {" +
"if (Math.abs(n39 * n23 - n38 * n24) <= n33 * n26 + n32 * n27) return true;" + " return false;" +
"return false;" + " }" +
"}", ct); " if (Math.abs(n38 * n25 - n40 * n23) > n34 * n26 + n32 * n28)" +
" {" +
" return false;" +
" }" +
" if (Math.abs(n39 * n23 - n38 * n24) <= n33 * n26 + n32 * n27)" +
" {" +
" return true;" +
" }" +
" return false;" +
"}", ct);
ct.addMethod(boundingboxCheck2); ct.addMethod(boundingboxCheck2);
} }
@@ -412,88 +441,103 @@ public class ClientTransform implements Transform {
ct.removeMethod(checkClickBox); ct.removeMethod(checkClickBox);
checkClickBox = CtMethod.make( checkClickBox = CtMethod.make(
"public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2) {"+ "public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2) {" +
"int n10;" + " int n10;" +
"int n11;" + " int n11;" +
"int n12;" + " int n12;" +
"int n13;" + " int n13;" +
"int n14;" + " int n14;" +
"net.runelite.rs.api.RSModel rSModel = (net.runelite.rs.api.RSModel)model;" + " net.runelite.rs.api.RSModel rSModel = (net.runelite.rs.api.RSModel)model;" +
"boolean bl2 = l2 != 0L && (int)(l2 >>> 16 & 1L) != 1;" + " boolean bl2 = l2 != 0L && (int)(l2 >>> 16 & 1L) != 1;" +
"boolean bl3 = "+ByteCodePatcher.clientInstance+".getViewportContainsMouse();" + " boolean bl3 = " + ByteCodePatcher.clientInstance + ".getViewportContainsMouse();" +
"if (!bl2) return;" + " if (!bl2)" +
"if (!bl3) return;" + " {" +
"boolean bl4 = this.boundingboxCheck2((net.runelite.api.Model)rSModel, n7, n8, n9);" + " return;" +
"if (!bl4) {" + " }" +
"return;" + " if (!bl3)" +
"}" + " {" +
"if (rSModel.isClickable()) {" + " return;" +
"this.addHashAtMouse(l2);" + " }" +
"return;" + " boolean bl4 = this.boundingboxCheck2((net.runelite.api.Model)rSModel, n7, n8, n9);" +
"}" + " if (!bl4)" +
"int n15 = rSModel.getVerticesCount();" + " {" +
"int n16 = rSModel.getTrianglesCount();" + " return;" +
"int[] arrn = rSModel.getVerticesX();" + " }" +
"int[] arrn2 = rSModel.getVerticesY();" + " if (rSModel.isClickable())" +
"int[] arrn3 = rSModel.getVerticesZ();" + " {" +
"int[] arrn4 = rSModel.getTrianglesX();" + " this.addHashAtMouse(l2);" +
"int[] arrn5 = rSModel.getTrianglesY();" + " return;" +
"int[] arrn6 = rSModel.getTrianglesZ();" + " }" +
"int[] arrn7 = rSModel.getFaceColors3();" + " int n15 = rSModel.getVerticesCount();" +
"int n17 = "+ByteCodePatcher.clientInstance+".get3dZoom();" + " int n16 = rSModel.getTrianglesCount();" +
"int n18 = "+ByteCodePatcher.clientInstance+".getCenterX();" + " int[] arrn = rSModel.getVerticesX();" +
"int n19 = "+ByteCodePatcher.clientInstance+".getCenterY();" + " int[] arrn2 = rSModel.getVerticesY();" +
"int n20 = 0;" + " int[] arrn3 = rSModel.getVerticesZ();" +
"int n21 = 0;" + " int[] arrn4 = rSModel.getTrianglesX();" +
"if (n2 != 0) {" + " int[] arrn5 = rSModel.getTrianglesY();" +
"n20 = net.runelite.api.Perspective.SINE[n2];" + " int[] arrn6 = rSModel.getTrianglesZ();" +
"n21 = net.runelite.api.Perspective.COSINE[n2];" + " int[] arrn7 = rSModel.getFaceColors3();" +
"}" + " int n17 = " + ByteCodePatcher.clientInstance + ".get3dZoom();" +
"for (n14 = 0; n14 < n15; ++n14) {" + " int n18 = " + ByteCodePatcher.clientInstance + ".getCenterX();" +
"n11 = arrn[n14];" + " int n19 = " + ByteCodePatcher.clientInstance + ".getCenterY();" +
"n13 = arrn2[n14];" + " int n20 = 0;" +
"n12 = arrn3[n14];" + " int n21 = 0;" +
"if (n2 != 0) {" + " if (n2 != 0)" +
"n10 = n12 * n20 + n11 * n21 >> 16;" + " {" +
"n12 = n12 * n21 - n11 * n20 >> 16;" + " n20 = net.runelite.api.Perspective.SINE[n2];" +
"n11 = n10;" + " n21 = net.runelite.api.Perspective.COSINE[n2];" +
"}" + " }" +
"n10 = (n12 += n9) * n5 + n6 * (n11 += n7) >> 16;" + " for (n14 = 0; n14 < n15; ++n14)" +
"n12 = n6 * n12 - n11 * n5 >> 16;" + " {" +
"n11 = n10;" + " n11 = arrn[n14];" +
"n10 = n4 * (n13 += n8) - n12 * n3 >> 16;" + " n13 = arrn2[n14];" +
"if ((n12 = n13 * n3 + n4 * n12 >> 16) >= 50) {" + " n12 = arrn3[n14];" +
"client.rl$modelViewportYs[n14] = n11 * n17 / n12 + n18;" + " if (n2 != 0)" +
"client.rl$modelViewportXs[n14] = n10 * n17 / n12 + n19;" + " {" +
"continue;" + " n10 = n12 * n20 + n11 * n21 >> 16;" +
"}" + " n12 = n12 * n21 - n11 * n20 >> 16;" +
"client.rl$modelViewportYs[n14] = -5000;" + " n11 = n10;" +
"}" + " }" +
"n14 = "+ByteCodePatcher.clientInstance+".getViewportMouseX();" + " n10 = (n12 += n9) * n5 + n6 * (n11 += n7) >> 16;" +
"n11 = "+ByteCodePatcher.clientInstance+".getViewportMouseY();" + " n12 = n6 * n12 - n11 * n5 >> 16;" +
"n13 = 0;" + " n11 = n10;" +
"while (n13 < n16) {" + " n10 = n4 * (n13 += n8) - n12 * n3 >> 16;" +
"if (arrn7[n13] != -2) {" + " if ((n12 = n13 * n3 + n4 * n12 >> 16) >= 50)" +
"int n22;" + " {" +
"boolean bl5;" + " client.rl$modelViewportYs[n14] = n11 * n17 / n12 + n18;" +
"int n23;" + " client.rl$modelViewportXs[n14] = n10 * n17 / n12 + n19;" +
"n12 = arrn4[n13];" + " continue;" +
"n10 = arrn5[n13];" + " }" +
"int n24 = arrn6[n13];" + " client.rl$modelViewportYs[n14] = -5000;" +
"int n25 = rl$modelViewportYs[n12];" + " }" +
"int n26 = rl$modelViewportYs[n10];" + " n14 = " + ByteCodePatcher.clientInstance + ".getViewportMouseX();" +
"int n27 = rl$modelViewportYs[n24];" + " n11 = " + ByteCodePatcher.clientInstance + ".getViewportMouseY();" +
"int n28 = rl$modelViewportXs[n12];" + " n13 = 0;" +
"int n29 = rl$modelViewportXs[n10];" + " while (n13 < n16)" +
"int n30 = rl$modelViewportXs[n24];" + " {" +
"if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = (n23 = (n22 = rSModel.isClickable() ? 20 : 5) + n11) < n28 && n23 < n29 && n23 < n30 ? false : ((n23 = n11 - n22) > n28 && n23 > n29 && n23 > n30 ? false : ((n23 = n22 + n14) < n25 && n23 < n26 && n23 < n27 ? false : (n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27)))) {" + " if (arrn7[n13] != -2)" +
"this.addHashAtMouse(l2);" + " {" +
"return;" + " int n22;" +
"}" + " boolean bl5;" +
"}" + " int n23;" +
"++n13;" + " n12 = arrn4[n13];" +
"}" + " n10 = arrn5[n13];" +
"}", ct); " int n24 = arrn6[n13];" +
ct.addMethod(checkClickBox); " int n25 = rl$modelViewportYs[n12];" +
" int n26 = rl$modelViewportYs[n10];" +
" int n27 = rl$modelViewportYs[n24];" +
" int n28 = rl$modelViewportXs[n12];" +
" int n29 = rl$modelViewportXs[n10];" +
" int n30 = rl$modelViewportXs[n24];" +
" if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = (n23 = (n22 = rSModel.isClickable() ? 20 : 5) + n11) < n28 && n23 < n29 && n23 < n30 ? false : ((n23 = n11 - n22) > n28 && n23 > n29 && n23 > n30 ? false : ((n23 = n22 + n14) < n25 && n23 < n26 && n23 < n27 ? false : (n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27))))" +
" {" +
" this.addHashAtMouse(l2);" +
" return;" +
" }" +
" }" +
" ++n13;" +
" }" +
"}", ct);
ct.addMethod(checkClickBox);
} }
} }

View File

@@ -6,38 +6,45 @@ import javassist.CtMethod;
import javassist.NotFoundException; import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher; import net.runelite.client.rs.bytecode.ByteCodePatcher;
//This prevents the client from sending stack traces to Jagex at all, even classes outside of runelite. // This prevents the client from sending stack traces to Jagex at all, even classes outside of runelite.
public class ErrorTransform implements Transform { public class ErrorTransform implements Transform
{
private CtClass ct; private CtClass ct;
//Where Runelites error interceptor is located, not auto-scraped. // Where Runelites error interceptor is located, not auto-scraped.
private static final String ERROR_INSTANCE_CLASS = "dp"; private static final String ERROR_INSTANCE_CLASS = "dp";
private static final String ERROR_INSTANCE_METHOD = "a"; private static final String ERROR_INSTANCE_METHOD = "a";
//private static final String ERROR_WARNING = "Tried to send a warning"; // private static final String ERROR_WARNING = "Tried to send a warning";
@Override @Override
public void modify(Class clazz) { public void modify(Class clazz)
try { {
System.out.println("[RuneLitePlus] Transforming error method at class: "+ERROR_INSTANCE_CLASS); try
{
System.out.println("[RuneLitePlus] Transforming error method at class: " + ERROR_INSTANCE_CLASS);
ct = ByteCodePatcher.classPool.get(ERROR_INSTANCE_CLASS); ct = ByteCodePatcher.classPool.get(ERROR_INSTANCE_CLASS);
transformError(); transformError();
ByteCodePatcher.modifiedClasses.add(ct); ByteCodePatcher.modifiedClasses.add(ct);
} catch (CannotCompileException | NotFoundException e) { }
e.printStackTrace(); catch (CannotCompileException | NotFoundException e)
} {
} e.printStackTrace();
}
}
private void transformError() throws CannotCompileException, NotFoundException private void transformError() throws CannotCompileException, NotFoundException
{ {
CtMethod error = ct.getDeclaredMethod(ERROR_INSTANCE_METHOD); CtMethod error = ct.getDeclaredMethod(ERROR_INSTANCE_METHOD);
ct.removeMethod(error); ct.removeMethod(error);
error = CtMethod.make( error = CtMethod.make(
"public static void a(String string, Throwable throwable, byte by) {"+ "public static void a(String string, Throwable throwable, byte by)" +
"throwable.printStackTrace();"+ "{" +
"System.out.println(\"[RuneLitePlus] Prevented preceeding stack trace from being sent to Jagex\");}", ct); " throwable.printStackTrace();" +
" System.out.println(\"[RuneLitePlus] Prevented preceeding stack trace from being sent to Jagex\");" +
"}", ct);
ct.addMethod(error); ct.addMethod(error);
} }
} }

View File

@@ -7,57 +7,67 @@ import javassist.CtNewMethod;
import javassist.NotFoundException; import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher; import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class PlayerTransform implements Transform { public class PlayerTransform implements Transform
{
private CtClass ct; private CtClass ct;
@Override @Override
public void modify(Class player) { public void modify(Class player)
try {
ct = ByteCodePatcher.classPool.get(player.getName());
transformProtectedGetSkullIcon();
transformGetSkullIcon();
ByteCodePatcher.modifiedClasses.add(ct);
} catch (CannotCompileException | NotFoundException e) {
e.printStackTrace();
}
}
private void transformProtectedGetSkullIcon() throws CannotCompileException, NotFoundException {
CtMethod protectedGetSkullIcon;
protectedGetSkullIcon = ct.getDeclaredMethod("1protect$getRsSkullIcon");
ct.removeMethod(protectedGetSkullIcon);
protectedGetSkullIcon.setName("getRsSkullIcon");
ct.addMethod(protectedGetSkullIcon);
}
private void transformGetSkullIcon() throws CannotCompileException, NotFoundException
{ {
CtMethod getSkullIcon; try
{
ct = ByteCodePatcher.classPool.get(player.getName());
transformProtectedGetSkullIcon();
transformGetSkullIcon();
ByteCodePatcher.modifiedClasses.add(ct);
}
catch (CannotCompileException | NotFoundException e)
{
e.printStackTrace();
}
}
String SkullIcon = "net.runelite.api.SkullIcon"; private void transformProtectedGetSkullIcon() throws CannotCompileException, NotFoundException
getSkullIcon = ct.getDeclaredMethod("getSkullIcon"); {
ct.removeMethod(getSkullIcon); CtMethod protectedGetSkullIcon;
getSkullIcon = CtNewMethod.make( protectedGetSkullIcon = ct.getDeclaredMethod("1protect$getRsSkullIcon");
"public "+SkullIcon+" getSkullIcon() {" + ct.removeMethod(protectedGetSkullIcon);
"switch (this.getRsSkullIcon()) {" + protectedGetSkullIcon.setName("getRsSkullIcon");
"case 0: {" +
"return " + SkullIcon + ".SKULL; }" + ct.addMethod(protectedGetSkullIcon);
"case 1: {" + }
"return " + SkullIcon + ".SKULL_FIGHT_PIT; }" +
"case 8: {" + private void transformGetSkullIcon() throws CannotCompileException, NotFoundException
"return " + SkullIcon + ".DEAD_MAN_FIVE; }" + {
"case 9: {" + CtMethod getSkullIcon;
"return " + SkullIcon + ".DEAD_MAN_FOUR; }" +
"case 10: {" + String SkullIcon = "net.runelite.api.SkullIcon";
"return " + SkullIcon + ".DEAD_MAN_THREE; }" + getSkullIcon = ct.getDeclaredMethod("getSkullIcon");
"case 11: {" + ct.removeMethod(getSkullIcon);
"return " + SkullIcon + ".DEAD_MAN_TWO; }" +
"case 12: {" + getSkullIcon = CtNewMethod.make(
"return " + SkullIcon + ".DEAD_MAN_ONE; } }" + "public " + SkullIcon + " getSkullIcon()" +
"return null; }", ct); "{" +
ct.addMethod(getSkullIcon); "switch (this.getRsSkullIcon())" +
"{" +
"case 0:" +
"return " + SkullIcon + ".SKULL;" +
"case 1:" +
"return " + SkullIcon + ".SKULL_FIGHT_PIT;" +
"case 8:" +
"return " + SkullIcon + ".DEAD_MAN_FIVE;" +
"case 9:" +
"return " + SkullIcon + ".DEAD_MAN_FOUR;" +
"case 10:" +
"return " + SkullIcon + ".DEAD_MAN_THREE;" +
"case 11:" +
"return " + SkullIcon + ".DEAD_MAN_TWO;" +
"case 12:" +
"return " + SkullIcon + ".DEAD_MAN_ONE;" +
"}" +
"return null;" +
"}", ct);
ct.addMethod(getSkullIcon);
} }
} }

View File

@@ -7,49 +7,51 @@ import javassist.CtNewMethod;
import javassist.NotFoundException; import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher; import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class ProjectileTransform implements Transform { public class ProjectileTransform implements Transform
{
private CtClass ct; private CtClass ct;
// Next variable is manually added, and will break on rev update // Next variable is manually added, and will break on rev update
private static final String interactingIntvalue = "-1655053057"; private static final String interactingIntvalue = "-1655053057";
@Override @Override
public void modify(Class projectile) { public void modify(Class projectile)
try {
try
{ {
ct = ByteCodePatcher.classPool.get(projectile.getName()); ct = ByteCodePatcher.classPool.get(projectile.getName());
transformGetAnimation();
transformGetAnimation(); transformInteracting();
ByteCodePatcher.modifiedClasses.add(ct);
transformInteracting(); }
catch (CannotCompileException | NotFoundException e)
ByteCodePatcher.modifiedClasses.add(ct); {
} e.printStackTrace();
catch (CannotCompileException | NotFoundException e) { }
e.printStackTrace(); }
}
}
private void transformGetAnimation() throws CannotCompileException, NotFoundException private void transformGetAnimation() throws CannotCompileException, NotFoundException
{ {
CtMethod getAnimation; CtMethod getAnimation;
getAnimation = ct.getDeclaredMethod("projectileMoved", new CtClass[]{CtClass.intType, CtClass.intType, CtClass.intType, CtClass.intType}); getAnimation = ct.getDeclaredMethod("projectileMoved", new CtClass[]{CtClass.intType, CtClass.intType, CtClass.intType, CtClass.intType});
ct.removeMethod(getAnimation); ct.removeMethod(getAnimation);
getAnimation = CtNewMethod.make( getAnimation = CtNewMethod.make(
"public void projectileMoved(int n, int n2, int n3, int n4) { " + "public void projectileMoved(int n, int n2, int n3, int n4)" +
"int n5 = this.getId();" + "{ " +
"net.runelite.api.coords.LocalPoint localPoint = new net.runelite.api.coords.LocalPoint(n, n2);" + " int n5 = this.getId();" +
"net.runelite.api.events.ProjectileMoved projectileMoved = new net.runelite.api.events.ProjectileMoved();" + " net.runelite.api.coords.LocalPoint localPoint = new net.runelite.api.coords.LocalPoint(n, n2);" +
"projectileMoved.setProjectile(this);" + " net.runelite.api.events.ProjectileMoved projectileMoved = new net.runelite.api.events.ProjectileMoved();" +
"projectileMoved.setPosition(localPoint);" + " projectileMoved.setProjectile(this);" +
"projectileMoved.setZ(n3);" + " projectileMoved.setPosition(localPoint);" +
ByteCodePatcher.clientInstance + ".getCallbacks().post(projectileMoved); }", ct); " projectileMoved.setZ(n3);" +
ct.addMethod(getAnimation); ByteCodePatcher.clientInstance + ".getCallbacks().post(projectileMoved);" +
} "}", ct);
ct.addMethod(getAnimation);
}
private void transformInteracting() throws CannotCompileException private void transformInteracting() throws CannotCompileException
{ {
CtMethod getRsInteracting; CtMethod getRsInteracting;
CtMethod getInteracting; CtMethod getInteracting;
@@ -58,23 +60,37 @@ public class ProjectileTransform implements Transform {
ct.addMethod(getRsInteracting); ct.addMethod(getRsInteracting);
getInteracting = CtNewMethod.make( getInteracting = CtNewMethod.make(
"public net.runelite.api.Actor getInteracting() {" + "public net.runelite.api.Actor getInteracting()" +
"int var1 = this.getRsInteracting();" + "{" +
"if (var1 == 0) {" + " int var1 = this.getRsInteracting();" +
"return null;" + " if (var1 == 0)" +
"} else {" + " {" +
"int var2;" + " return null;" +
"if (var1 > 0) {" + " }" +
"var2 = var1 - 1;" + " else" +
"net.runelite.rs.api.RSNPC[] var4 = " + ByteCodePatcher.clientInstance + ".getCachedNPCs();" + " {" +
"return var4[var2];" + " int var2;" +
"} else {" + " if (var1 > 0)" +
"var2 = -var1 - 1;" + " {" +
"if (var2 == " + ByteCodePatcher.clientInstance + ".getLocalInteractingIndex()) {" + " var2 = var1 - 1;" +
"return " + ByteCodePatcher.clientInstance + ".getLocalPlayer();" + " net.runelite.rs.api.RSNPC[] var4 = " + ByteCodePatcher.clientInstance + ".getCachedNPCs();" +
"} else {" + " return var4[var2];" +
"net.runelite.rs.api.RSPlayer[] var3 = " + ByteCodePatcher.clientInstance + ".getCachedPlayers();" + " }" +
"return var3[var2]; }}}}", ct); " else" +
" {" +
" var2 = -var1 - 1;" +
" if (var2 == " + ByteCodePatcher.clientInstance + ".getLocalInteractingIndex())" +
" {" +
" return " + ByteCodePatcher.clientInstance + ".getLocalPlayer();" +
" }" +
" else" +
" {" +
" net.runelite.rs.api.RSPlayer[] var3 = " + ByteCodePatcher.clientInstance + ".getCachedPlayers();" +
" return var3[var2];" +
" }" +
" }" +
" }" +
"}", ct);
ct.addMethod(getInteracting); ct.addMethod(getInteracting);
} }
} }