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.net.URL;
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.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -62,20 +58,18 @@ import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.logging.Logger;
import javassist.ClassPool;
import javassist.NotFoundException;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javassist.ClassPool;
import javassist.NotFoundException;
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.NONE;
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.ByteCodeUtils;
import net.runelite.client.rs.bytecode.Hooks;
import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Request;
@@ -90,7 +84,6 @@ public class ClientLoader
public static File hooksFile = new File(RuneLite.RUNELITE_DIR + "/hooks-" + RuneLiteAPI.getVersion() + "-.json");
private final ClientConfigLoader clientConfigLoader;
private ClientUpdateCheckMode updateCheckMode;
private JarOutputStream target;
private static String[] preotectedStuffs;
private static int stepCount;
@@ -116,12 +109,11 @@ public class ClientLoader
File hijackedClientFile = ByteCodeUtils.hijackedClientFile;
Manifest manifest = new Manifest();
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();
Map<String, byte[]> zipFile = new HashMap<>();
{
Certificate[] jagexCertificateChain = getJagexCertificateChain();
String codebase = config.getCodeBase();
String initialJar = config.getInitialJar();
URL url = new URL(codebase + initialJar);
@@ -183,11 +175,14 @@ public class ClientLoader
if (!file.getValue().equals(ourHash))
{
if (hijackedClientFile.exists()) {
if (hijackedClientFile.exists())
{
Logger.getAnonymousLogger().warning("[RuneLitePlus] Hash checking / Client patching skipped due to hijacked client.");
updateCheckMode = VANILLA;
break;
} else {
}
else
{
log.info("{} had a hash mismatch; falling back to vanilla. {} != {}", file.getKey(), file.getValue(), ourHash);
log.info("Client is outdated!");
updateCheckMode = VANILLA;
@@ -221,16 +216,17 @@ public class ClientLoader
++patchCount;
if (!file.getKey().startsWith("META")) {
if (!file.getKey().startsWith("META"))
{
add(file.getValue(), file.getKey(), target);
}
}
if (target!=null)
target.close();
log.info("Patched {} classes", patchCount);
}
if (hooksFile.exists()) {
if (hooksFile.exists())
{
ByteCodePatcher.classPool = new ClassPool(true);
ByteCodePatcher.classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
Gson gson = new Gson();
@@ -239,18 +235,23 @@ public class ClientLoader
if (hooks.clientInstance.equals("") ||
hooks.projectileClass.equals("") ||
hooks.actorClass.equals("") ||
hooks.playerClass.equals("")) {
hooks.playerClass.equals(""))
{
System.out.println("[RuneLitePlus] Bad hooks, re-scraping.");
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.findHooks(injectedClientFile.getPath());
} else {
}
else
{
ByteCodePatcher.clientInstance = hooks.clientInstance;
ByteCodePatcher.applyHooks(ByteCodeUtils.injectedClientFile, hooks);
System.out.println("[RuneLitePlus] Loaded hooks");
}
} else {
}
else
{
System.out.println("[RuneLitePlus] Hooks file not found, scraping hooks.");
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
@@ -263,16 +264,20 @@ public class ClientLoader
byte[] tmp = new byte[4096];
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
for (; ; ) {
for (; ; )
{
JarEntry metadata = jis.getNextJarEntry();
if (metadata == null) {
if (metadata == null)
{
break;
}
buffer.reset();
for (; ; ) {
for (; ; )
{
int n = jis.read(tmp);
if (n <= -1) {
if (n <= -1)
{
break;
}
buffer.write(tmp, 0, n);
@@ -306,7 +311,7 @@ public class ClientLoader
return rs;
}
catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException
| CompressorException | InvalidHeaderException | CertificateException | SecurityException e)
| CompressorException | InvalidHeaderException | SecurityException e)
{
if (e instanceof ClassNotFoundException)
{
@@ -317,142 +322,175 @@ public class ClientLoader
log.error("Error loading RS!", e);
return null;
} catch (NotFoundException e) {
}
catch (NotFoundException e)
{
e.printStackTrace();
}
return null;
}
private void add(byte[] bytes, String entryName ,JarOutputStream target) throws IOException {
BufferedInputStream in = null;
try {
private void add(byte[] bytes, String entryName, JarOutputStream target) throws IOException
{
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
private static int getStepCount(String jarFile)
{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt"));
return certificates.toArray(new Certificate[certificates.size()]);
}
public static int getStepCount(String jarFile) {
int stepCount = 0;
JarClassLoader jcl = new JarClassLoader();
try {
try
{
ClassPool classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
} catch (NotFoundException e) {
}
catch (NotFoundException e)
{
e.printStackTrace();
}
try {
try
{
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;
while ((entry = in.getNextJarEntry()) != null) {
if (entry.getName().endsWith(".class")) {
while ((entry = in.getNextJarEntry()) != null)
{
if (entry.getName().endsWith(".class"))
{
stepCount++;
}
}
}
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
return stepCount;
}
public static String initHookScrape(String jarFile) {
private static String initHookScrape(String jarFile)
{
int currentStep = 0;
RuneLite.splashScreen.setMessage("Analyzing injected client");
List protectedStuff = new ArrayList<String>();
List<String> protectedStuff = new ArrayList<>();
String clientInstance = "";
JarClassLoader jcl = new JarClassLoader();
try {
try
{
ClassPool classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
} catch (NotFoundException e) {
}
catch (NotFoundException e)
{
e.printStackTrace();
}
try {
try
{
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;
while ((entry = in.getNextJarEntry()) != null) {
if (entry.getName().endsWith(".class")) {
while ((entry = in.getNextJarEntry()) != null)
{
if (entry.getName().endsWith(".class"))
{
File temp = new File(jarFile);
ClassLoader cl = ClassLoader.getSystemClassLoader();
try {
try
{
URLClassLoader child = new URLClassLoader(
new URL[]{temp.toURI().toURL()},
cl
);
try {
try
{
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
RuneLite.splashScreen.setSubMessage(entry.getName());
currentStep++;
RuneLite.splashScreen.setProgress(currentStep, stepCount);
JarClassLoader jcl2 = new JarClassLoader();
try {
try
{
jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile));
Field[] fields = classToLoad.getDeclaredFields();
Method[] methods = classToLoad.getDeclaredMethods();
for (Field f : fields) {
try {
if (f.getName().contains("$")) {
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();
}
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
}
for (Method m : methods) {
for (Method m : methods)
{
RuneLite.splashScreen.setSubMessage("Checked " + m.getName());
if (m.getName().contains("$")) {
if (m.getName().contains("$"))
{
protectedStuff.add(classToLoad.getName() + "." + m.getName());
}
}
RuneLite.splashScreen.setProgress(currentStep, stepCount);
} catch (FileNotFoundException e) {
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
RuneLite.splashScreen.setProgress(2, 5);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Class not found: " + entry.getName());
}
}
}
}
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
int i = 0;
for (Object o : protectedStuff) {
for (String ignored : protectedStuff)
{
i++;
}
preotectedStuffs = new String[i];
i = 0;
for (Object o : protectedStuff) {
preotectedStuffs[i] = (String) o;
for (String o : protectedStuff)
{
preotectedStuffs[i] = o;
i++;
}
return clientInstance;
}
}

View File

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

View File

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

View File

@@ -7,12 +7,15 @@ import javassist.CtNewMethod;
import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class ActorTransform implements Transform {
public class ActorTransform implements Transform
{
private CtClass ct;
@Override
public void modify(Class actor) {
try {
public void modify(Class actor)
{
try
{
ct = ByteCodePatcher.classPool.get(actor.getName());
transformGetAnimation();
@@ -20,7 +23,9 @@ public class ActorTransform implements Transform {
transformGraphicChanged();
ByteCodePatcher.modifiedClasses.add(ct);
} catch (CannotCompileException | NotFoundException e) {
}
catch (CannotCompileException | NotFoundException e)
{
e.printStackTrace();
}
}
@@ -36,7 +41,11 @@ public class ActorTransform implements Transform {
CtMethod getAnimation = ct.getDeclaredMethod("getAnimation");
ct.removeMethod(getAnimation);
getAnimation = CtNewMethod.make("public int getAnimation() { return this.getRsAnimation(); }",ct);
getAnimation = CtNewMethod.make(
"public int getAnimation()" +
"{" +
" return this.getRsAnimation();" +
"}", ct);
ct.addMethod(getAnimation);
}
@@ -47,10 +56,12 @@ public class ActorTransform implements Transform {
ct.removeMethod(getAnimationChanged);
getAnimationChanged = CtNewMethod.make(
"public void animationChanged(int n) { " +
"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);
ByteCodePatcher.clientInstance + ".getCallbacks().post((java.lang.Object)animationChanged);" +
"}", ct);
ct.addMethod(getAnimationChanged);
}
@@ -60,10 +71,12 @@ public class ActorTransform implements Transform {
ct.removeMethod(graphicChanged);
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);" +
ByteCodePatcher.clientInstance+".getCallbacks().post(localGraphicChanged);}",ct);
ByteCodePatcher.clientInstance + ".getCallbacks().post(localGraphicChanged);" +
"}", ct);
ct.addMethod(graphicChanged);
}

View File

@@ -10,13 +10,16 @@ import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class ClientTransform implements Transform {
public class ClientTransform implements Transform
{
private CtClass ct;
@Override
public void modify(Class clazz) {
try {
public void modify(Class clazz)
{
try
{
ct = ByteCodePatcher.classPool.get(clazz.getName());
transformProtectedGetMenuOptions();
@@ -36,7 +39,9 @@ public class ClientTransform implements Transform {
transformcheckClickBox();
ByteCodePatcher.modifiedClasses.add(ct);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
}
@@ -167,7 +172,8 @@ public class ClientTransform implements Transform {
ct.removeMethod(getMenuEntries);
getMenuEntries = CtMethod.make(
"public net.runelite.api.MenuEntry[] getMenuEntries() {" +
"public net.runelite.api.MenuEntry[] getMenuEntries()" +
"{" +
" int n2 = this.getMenuOptionCount();" +
" String[] arrstring = this.getMenuOptions();" +
" String[] arrstring2 = this.getMenuTargets();" +
@@ -178,7 +184,8 @@ public class ClientTransform implements Transform {
" boolean[] arrbl = this.getMenuForceLeftClick();" +
" net.runelite.api.MenuEntry[] arrmenuEntry = new net.runelite.api.MenuEntry[n2];" +
" int n3 = 0;" +
"while (n3 < n2) {"+
" while (n3 < n2) " +
" {" +
" net.runelite.api.MenuEntry menuEntry = arrmenuEntry[n3] = new net.runelite.api.MenuEntry();" +
" menuEntry.setOption(arrstring[n3]);" +
" menuEntry.setTarget(arrstring2[n3]);" +
@@ -187,18 +194,22 @@ public class ClientTransform implements Transform {
" menuEntry.setParam0(arrn3[n3]);" +
" menuEntry.setParam1(arrn4[n3]);" +
" menuEntry.setForceLeftClick(arrbl[n3]);" +
"++n3; }"+
"return arrmenuEntry; }", ct);
" ++n3;" +
" }" +
" return arrmenuEntry;" +
"}", ct);
ct.addMethod(getMenuEntries);
}
private void transformSetMenuEntries() throws CannotCompileException, NotFoundException {
private void transformSetMenuEntries() throws CannotCompileException, NotFoundException
{
CtMethod setMenuEntries;
setMenuEntries = ct.getDeclaredMethod("setMenuEntries");
ct.removeMethod(setMenuEntries);
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();" +
" String[] arrstring2 = this.getMenuTargets();" +
@@ -210,9 +221,11 @@ public class ClientTransform implements Transform {
" net.runelite.api.MenuEntry[] arrmenuEntry2 = arrmenuEntry;" +
" int n3 = arrmenuEntry2.length;" +
" int n4 = 0;" +
"do {" +
" do" +
" {" +
" String string;" +
"if (n4 >= n3) {" +
" if (n4 >= n3)" +
" {" +
" this.setMenuOptionCount(n2);" +
" oldMenuEntryCount = n2;" +
" return;" +
@@ -242,7 +255,8 @@ public class ClientTransform implements Transform {
ct.removeMethod(onMenuOptionsChanged);
onMenuOptionsChanged = CtMethod.make(
"public static void onMenuOptionsChanged(int n2) {"+
"public static void onMenuOptionsChanged(int n2)" +
"{" +
" int n3;" +
" int n4 = oldMenuEntryCount;" +
" oldMenuEntryCount = n3 = " + ByteCodePatcher.clientInstance + ".getMenuOptionCount();" +
@@ -285,7 +299,8 @@ public class ClientTransform implements Transform {
ct.removeMethod(draw2010Menu);
draw2010Menu = CtNewMethod.make(
"public void draw2010Menu() {" +
"public void draw2010Menu()" +
"{" +
" int n2 = this.getMenuX();" +
" int n3 = this.getMenuY();" +
" int n4 = this.getMenuWidth();" +
@@ -317,14 +332,19 @@ public class ClientTransform implements Transform {
" int n8 = this.getMenuOptionCount();" +
" String[] arrstring = this.getMenuTargets();" +
" String[] arrstring2 = this.getMenuOptions();" +
"for (int i = 0; i < n8; ++i) {" +
" for (int i = 0; i < n8; ++i)" +
" {" +
" int n9 = n3 + (n8 - 1 - i) * 15 + 31;" +
" String string = arrstring2[i];" +
"if (!arrstring[i].isEmpty()) {" +
" if (!arrstring[i].isEmpty())" +
" {" +
" string = string + \" \" + arrstring[i];" +
" }" +
" rSFont.drawTextLeftAligned(string, n2 + 3, n9, 13023381, -1);" +
"if (n6 <= n2 || n6 >= n4 + n2 || n7 <= n9 - 13 || n7 >= n9 + 3) continue;" +
" if (n6 <= n2 || n6 >= n4 + n2 || n7 <= n9 - 13 || n7 >= n9 + 3)" +
" {" +
" continue;" +
" }" +
" this.RasterizerFillRectangleAlpha(n2 + 3, n9 - 12, n4 - 6, 15, 16777215, 80);" +
" }" +
"}"
@@ -338,7 +358,8 @@ public class ClientTransform implements Transform {
CtMethod boundingboxCheck2;
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 n7 = net.runelite.api.Perspective.SINE[n5];" +
@@ -383,22 +404,30 @@ public class ClientTransform implements Transform {
" int n38 = n35 - n29;" +
" int n39 = n36 - n30;" +
" int n40 = n37 - n31;" +
"if (Math.abs(n38) > n32 + n26) {" +
" if (Math.abs(n38) > n32 + n26)" +
" {" +
" return false;" +
" }" +
"if (Math.abs(n39) > n33 + n27) {" +
" if (Math.abs(n39) > n33 + n27)" +
" {" +
" return false;" +
" }" +
"if (Math.abs(n40) > n34 + n28) {" +
" if (Math.abs(n40) > n34 + n28)" +
" {" +
" return false;" +
" }" +
"if (Math.abs(n40 * n24 - n39 * n25) > n33 * n28 + n34 * n27) {" +
" if (Math.abs(n40 * n24 - n39 * n25) > n33 * n28 + n34 * n27)" +
" {" +
" return false;" +
" }" +
"if (Math.abs(n38 * n25 - n40 * n23) > n34 * n26 + n32 * n28) {" +
" 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;" +
" if (Math.abs(n39 * n23 - n38 * n24) <= n33 * n26 + n32 * n27)" +
" {" +
" return true;" +
" }" +
" return false;" +
"}", ct);
ct.addMethod(boundingboxCheck2);
@@ -421,13 +450,21 @@ public class ClientTransform implements Transform {
" net.runelite.rs.api.RSModel rSModel = (net.runelite.rs.api.RSModel)model;" +
" boolean bl2 = l2 != 0L && (int)(l2 >>> 16 & 1L) != 1;" +
" boolean bl3 = " + ByteCodePatcher.clientInstance + ".getViewportContainsMouse();" +
"if (!bl2) return;" +
"if (!bl3) return;" +
"boolean bl4 = this.boundingboxCheck2((net.runelite.api.Model)rSModel, n7, n8, n9);" +
"if (!bl4) {" +
" if (!bl2)" +
" {" +
" return;" +
" }" +
"if (rSModel.isClickable()) {" +
" if (!bl3)" +
" {" +
" return;" +
" }" +
" boolean bl4 = this.boundingboxCheck2((net.runelite.api.Model)rSModel, n7, n8, n9);" +
" if (!bl4)" +
" {" +
" return;" +
" }" +
" if (rSModel.isClickable())" +
" {" +
" this.addHashAtMouse(l2);" +
" return;" +
" }" +
@@ -445,15 +482,18 @@ public class ClientTransform implements Transform {
" int n19 = " + ByteCodePatcher.clientInstance + ".getCenterY();" +
" int n20 = 0;" +
" int n21 = 0;" +
"if (n2 != 0) {" +
" if (n2 != 0)" +
" {" +
" n20 = net.runelite.api.Perspective.SINE[n2];" +
" n21 = net.runelite.api.Perspective.COSINE[n2];" +
" }" +
"for (n14 = 0; n14 < n15; ++n14) {" +
" for (n14 = 0; n14 < n15; ++n14)" +
" {" +
" n11 = arrn[n14];" +
" n13 = arrn2[n14];" +
" n12 = arrn3[n14];" +
"if (n2 != 0) {" +
" if (n2 != 0)" +
" {" +
" n10 = n12 * n20 + n11 * n21 >> 16;" +
" n12 = n12 * n21 - n11 * n20 >> 16;" +
" n11 = n10;" +
@@ -462,7 +502,8 @@ public class ClientTransform implements Transform {
" n12 = n6 * n12 - n11 * n5 >> 16;" +
" n11 = n10;" +
" n10 = n4 * (n13 += n8) - n12 * n3 >> 16;" +
"if ((n12 = n13 * n3 + n4 * n12 >> 16) >= 50) {" +
" if ((n12 = n13 * n3 + n4 * n12 >> 16) >= 50)" +
" {" +
" client.rl$modelViewportYs[n14] = n11 * n17 / n12 + n18;" +
" client.rl$modelViewportXs[n14] = n10 * n17 / n12 + n19;" +
" continue;" +
@@ -472,8 +513,10 @@ public class ClientTransform implements Transform {
" n14 = " + ByteCodePatcher.clientInstance + ".getViewportMouseX();" +
" n11 = " + ByteCodePatcher.clientInstance + ".getViewportMouseY();" +
" n13 = 0;" +
"while (n13 < n16) {" +
"if (arrn7[n13] != -2) {" +
" while (n13 < n16)" +
" {" +
" if (arrn7[n13] != -2)" +
" {" +
" int n22;" +
" boolean bl5;" +
" int n23;" +
@@ -486,7 +529,8 @@ public class ClientTransform implements Transform {
" 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)))) {" +
" 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;" +
" }" +

View File

@@ -7,7 +7,8 @@ import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher;
// 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;
// Where Runelites error interceptor is located, not auto-scraped.
@@ -16,15 +17,19 @@ public class ErrorTransform implements Transform {
// private static final String ERROR_WARNING = "Tried to send a warning";
@Override
public void modify(Class clazz) {
try {
public void modify(Class clazz)
{
try
{
System.out.println("[RuneLitePlus] Transforming error method at class: " + ERROR_INSTANCE_CLASS);
ct = ByteCodePatcher.classPool.get(ERROR_INSTANCE_CLASS);
transformError();
ByteCodePatcher.modifiedClasses.add(ct);
} catch (CannotCompileException | NotFoundException e) {
}
catch (CannotCompileException | NotFoundException e)
{
e.printStackTrace();
}
}
@@ -35,9 +40,11 @@ public class ErrorTransform implements Transform {
ct.removeMethod(error);
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);
" System.out.println(\"[RuneLitePlus] Prevented preceeding stack trace from being sent to Jagex\");" +
"}", ct);
ct.addMethod(error);
}
}

View File

@@ -7,22 +7,28 @@ import javassist.CtNewMethod;
import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class PlayerTransform implements Transform {
public class PlayerTransform implements Transform
{
private CtClass ct;
@Override
public void modify(Class player) {
try {
public void modify(Class player)
{
try
{
ct = ByteCodePatcher.classPool.get(player.getName());
transformProtectedGetSkullIcon();
transformGetSkullIcon();
ByteCodePatcher.modifiedClasses.add(ct);
} catch (CannotCompileException | NotFoundException e) {
}
catch (CannotCompileException | NotFoundException e)
{
e.printStackTrace();
}
}
private void transformProtectedGetSkullIcon() throws CannotCompileException, NotFoundException {
private void transformProtectedGetSkullIcon() throws CannotCompileException, NotFoundException
{
CtMethod protectedGetSkullIcon;
protectedGetSkullIcon = ct.getDeclaredMethod("1protect$getRsSkullIcon");
@@ -41,23 +47,27 @@ public class PlayerTransform implements Transform {
ct.removeMethod(getSkullIcon);
getSkullIcon = CtNewMethod.make(
"public "+SkullIcon+" 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);
"public " + SkullIcon + " 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,25 +7,25 @@ import javassist.CtNewMethod;
import javassist.NotFoundException;
import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class ProjectileTransform implements Transform {
public class ProjectileTransform implements Transform
{
private CtClass ct;
// Next variable is manually added, and will break on rev update
private static final String interactingIntvalue = "-1655053057";
@Override
public void modify(Class projectile) {
public void modify(Class projectile)
{
try
{
ct = ByteCodePatcher.classPool.get(projectile.getName());
transformGetAnimation();
transformInteracting();
ByteCodePatcher.modifiedClasses.add(ct);
}
catch (CannotCompileException | NotFoundException e) {
catch (CannotCompileException | NotFoundException e)
{
e.printStackTrace();
}
}
@@ -38,14 +38,16 @@ public class ProjectileTransform implements Transform {
ct.removeMethod(getAnimation);
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);" +
" net.runelite.api.events.ProjectileMoved projectileMoved = new net.runelite.api.events.ProjectileMoved();" +
" projectileMoved.setProjectile(this);" +
" projectileMoved.setPosition(localPoint);" +
" projectileMoved.setZ(n3);" +
ByteCodePatcher.clientInstance + ".getCallbacks().post(projectileMoved); }", ct);
ByteCodePatcher.clientInstance + ".getCallbacks().post(projectileMoved);" +
"}", ct);
ct.addMethod(getAnimation);
}
@@ -58,23 +60,37 @@ public class ProjectileTransform implements Transform {
ct.addMethod(getRsInteracting);
getInteracting = CtNewMethod.make(
"public net.runelite.api.Actor getInteracting() {" +
"public net.runelite.api.Actor getInteracting()" +
"{" +
" int var1 = this.getRsInteracting();" +
"if (var1 == 0) {" +
" if (var1 == 0)" +
" {" +
" return null;" +
"} else {" +
" }" +
" else" +
" {" +
" int var2;" +
"if (var1 > 0) {" +
" if (var1 > 0)" +
" {" +
" var2 = var1 - 1;" +
" net.runelite.rs.api.RSNPC[] var4 = " + ByteCodePatcher.clientInstance + ".getCachedNPCs();" +
" return var4[var2];" +
"} else {" +
" }" +
" else" +
" {" +
" var2 = -var1 - 1;" +
"if (var2 == " + ByteCodePatcher.clientInstance + ".getLocalInteractingIndex()) {" +
" if (var2 == " + ByteCodePatcher.clientInstance + ".getLocalInteractingIndex())" +
" {" +
" return " + ByteCodePatcher.clientInstance + ".getLocalPlayer();" +
"} else {" +
" }" +
" else" +
" {" +
" net.runelite.rs.api.RSPlayer[] var3 = " + ByteCodePatcher.clientInstance + ".getCachedPlayers();" +
"return var3[var2]; }}}}", ct);
" return var3[var2];" +
" }" +
" }" +
" }" +
"}", ct);
ct.addMethod(getInteracting);
}
}