diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index 9c70435b0b..d49b97c9a2 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -45,13 +45,16 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; 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; import java.util.jar.Attributes; import java.util.jar.JarEntry; @@ -88,6 +91,7 @@ public class ClientLoader private final ClientConfigLoader clientConfigLoader; private ClientUpdateCheckMode updateCheckMode; private JarOutputStream target; + private boolean scrapedHooks = false; @Inject private ClientLoader( @@ -231,22 +235,31 @@ public class ClientLoader Gson gson = new Gson(); Hooks hooks = gson.fromJson(new BufferedReader(new FileReader(hooksFile)), Hooks.class); - if (hooks.clientInstance.equals("")|| + if (hooks == null && !scrapedHooks) { + System.out.println("[RuneLit] Bad hooks, re-scraping."); + ByteCodePatcher.clientInstance = initVanillaInjected(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.findHooks(injectedClientFile.getPath()); + scrapedHooks=true; + } + if ((hooks.clientInstance.equals("")|| hooks.projectileClass.equals("") || hooks.actorClass.equals("") || - hooks.playerClass.equals("")) { + hooks.playerClass.equals("")) && !scrapedHooks) { System.out.println("[RuneLit] Bad hooks, re-scraping."); - ByteCodePatcher.clientInstance = getClientInstance(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.clientInstance = initVanillaInjected(ByteCodeUtils.injectedClientFile.getPath()); ByteCodePatcher.findHooks(injectedClientFile.getPath()); - } else { + scrapedHooks=true; + + } else if (!scrapedHooks) { ByteCodePatcher.clientInstance = hooks.clientInstance; ByteCodePatcher.applyHooks(ByteCodeUtils.injectedClientFile, hooks); System.out.println("[RuneLit] Loaded hooks"); + scrapedHooks=true; } } else { System.out.println("[RuneLit] Hooks file not found, scraping hooks."); - ByteCodePatcher.clientInstance = getClientInstance(ByteCodeUtils.injectedClientFile.getPath()); + ByteCodePatcher.clientInstance = initVanillaInjected(ByteCodeUtils.injectedClientFile.getPath()); ByteCodePatcher.findHooks(injectedClientFile.getPath()); } @@ -335,7 +348,9 @@ public class ClientLoader return certificates.toArray(new Certificate[certificates.size()]); } - public static String getClientInstance(String jarFile) { + public static String initVanillaInjected(String jarFile) { + List protectedMethods = new ArrayList<>(); + String clientInstance = ""; JarClassLoader jcl = new JarClassLoader(); try { ClassPool classPool = new ClassPool(true); @@ -363,17 +378,23 @@ public class ClientLoader try { jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile)); Field[] fields = classToLoad.getDeclaredFields(); + Method[] methods = classToLoad.getMethods(); for (Field f : fields) { try { if (f.getType().getName()=="client") { ByteCodePatcher.hooks.clientInstance = classToLoad.getName()+"."+f.getName(); System.out.println("[RuneLit] Found client instance at "+classToLoad.getName()+"."+f.getName()); - return classToLoad.getName()+"."+f.getName(); + clientInstance = classToLoad.getName()+"."+f.getName(); } } catch (Exception e) { e.printStackTrace(); } } + for (Method m : methods) { + if (m.getName().contains("protect")) { + protectedMethods.add(classToLoad.getName()+":"+m.getName()); + } + } } catch (FileNotFoundException e) { e.printStackTrace(); } @@ -391,6 +412,13 @@ public class ClientLoader } catch (Exception e) { e.printStackTrace(); } - return ""; + String[] hooksProtectedMethods = new String[protectedMethods.size()]; + int i = 0; + for (String s : protectedMethods) { + hooksProtectedMethods[i] = s; + i++; + } + ByteCodePatcher.hooks.protectedMethods = hooksProtectedMethods; + return clientInstance; } } diff --git a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java index 6d75fc81da..e07199187d 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/bytecode/Hooks.java @@ -1,11 +1,15 @@ package net.runelite.client.rs.bytecode; +import java.lang.reflect.Method; +import java.util.List; + public class Hooks { public String clientInstance = ""; public String actorClass = ""; public String projectileClass = ""; public String playerClass = ""; + public String[] protectedMethods; public Hooks() { }