Merge pull request #26 from runelite-extended/MenuEntriesFinito

ClientTransform
This commit is contained in:
James
2019-04-20 21:19:26 -07:00
committed by GitHub
4 changed files with 359 additions and 162 deletions

View File

@@ -18,10 +18,4 @@ public interface KittenNotifierConfig extends Config{
hidden = true
)
default boolean catOwned() { return false; }
@ConfigItem(
keyName = "catOwned",
name = "",
description = ""
)
void catOwned(Boolean bool);
}

View File

@@ -2,6 +2,7 @@ package net.runelite.client.plugins.kittennotifier;
import com.google.inject.Provides;
import net.runelite.api.ChatMessageType;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.NpcActionChanged;
import net.runelite.api.events.NpcSpawned;
import net.runelite.client.Notifier;
@@ -20,6 +21,8 @@ import javax.inject.Inject;
type = "utility"
)
public class KittenNotifierPlugin extends Plugin{
public boolean catOwned = false;
@Inject
private Notifier notifier;
@Inject
@@ -51,36 +54,33 @@ public class KittenNotifierPlugin extends Plugin{
}
}
@Subscribe
public void onNpcActionChanged(NpcActionChanged event) {
if (event.getNpcComposition()!=null)
public void onGameTick(GameTick event) {
if (!config.catOwned()) {
for (NPC npc : client.getNpcs()) {
if (npc.getInteracting() != null) {
if (npc.getName().equals("Cat") && !config.catOwned()) {
// If this if statement is included in previous it could null.
if (npc.getInteracting()!=null)
if (npc.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) {
config.catOwned(true);
notifier.notify("Your kitten has grown into a cat.");
if (npc.getName().equals("Cat") && !config.catOwned()) {
// If this if statement is included in previous it could null.
catOwned = true;
notifier.notify("Your kitten has grown into a cat.");
}
}
}
}
}
}
@Subscribe
public void onNpcSpawned(NpcSpawned event) {
NPC cat = event.getNpc();
if (cat.getName() != null) {
if (cat.getName().equalsIgnoreCase("Kitten")) {
if (cat.getInteracting().getName().contentEquals(client.getLocalPlayer().getName())) {
config.catOwned(false);
if (cat.getInteracting()!=null)
if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) {
if (cat.getName().contains("itten") && !config.catOwned()) {
catOwned = false;
}
}
else if (cat.getName().contentEquals("Cat")) {
else if (cat.getName().equals("Cat")) {
if (cat.getInteracting().getName().equalsIgnoreCase(client.getLocalPlayer().getName())) {
config.catOwned(true);
catOwned = true;
}
}
}
}
}

View File

@@ -8,22 +8,19 @@ 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.PlayerTransform;
import net.runelite.client.rs.bytecode.transformers.ProjectileTransform;
import net.runelite.http.api.RuneLiteAPI;
import org.xeustechnologies.jcl.JarClassLoader;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
@@ -33,154 +30,166 @@ import java.util.jar.JarInputStream;
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();
public static ClassPool classPool = null;
public static ClassLoader cl = ClassLoader.getSystemClassLoader();
public static List<CtClass> modifiedClasses = new ArrayList<>();
public static Hooks hooks = new Hooks();
public static String clientInstance;
public static JarClassLoader jcl = new JarClassLoader();
public static ClassPool classPool = null;
public static ClassLoader cl = ClassLoader.getSystemClassLoader();
public static void applyHooks(File jf, Hooks hooks) {
try {
URLClassLoader child = new URLClassLoader(
new URL[] {jf.toURI().toURL()},
cl
);
try {
Class actorClass = Class.forName(hooks.actorClass, false, child);
transformActor(actorClass);
Class projectileClass = Class.forName(hooks.projectileClass, false, child);
transformProjectile(projectileClass);
Class playerClass = Class.forName(hooks.playerClass, false, child);
transformPlayer(playerClass);
ByteCodeUtils.updateHijackedJar();
} catch (Exception e) {
e.printStackTrace();
}
public static void applyHooks(File jf, Hooks hooks) {
try {
URLClassLoader child = new URLClassLoader(
new URL[] {jf.toURI().toURL()},
cl
);
try {
Class actorClass = Class.forName(hooks.actorClass, false, child);
transformActor(actorClass);
Class projectileClass = Class.forName(hooks.projectileClass, false, child);
transformProjectile(projectileClass);
Class playerClass = Class.forName(hooks.playerClass, false, child);
transformPlayer(playerClass);
} catch (Exception e) {
e.printStackTrace();
}
}
//experimental
Class clientClass = Class.forName("client", false, child);
transformBlackjack(clientClass);
public static void findHooks(String jf) {
try {
classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar");
} catch (NotFoundException e) {
e.printStackTrace();
}
ByteCodeUtils.updateHijackedJar();
} catch (Exception e) {
e.printStackTrace();
}
try {
jcl.add(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")) {
checkClasses(new File(jf), entry);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try {
Writer writer = new FileWriter(ClientLoader.hooksFile);
gson.toJson(hooks, writer);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
ByteCodeUtils.updateHijackedJar();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void checkClasses(File jf, JarEntry entry) {
try {
URLClassLoader child = new URLClassLoader(
new URL[] {jf.toURI().toURL()},
cl
);
try {
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
checkActor(classToLoad);
checkProjectile(classToLoad);
checkPlayer(classToLoad);
} catch (Exception e) {
e.printStackTrace();
}
public static void findHooks(String jf) {
try {
classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar");
} catch (NotFoundException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Class not found: "+entry.getName());
}
}
try {
jcl.add(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")) {
checkClasses(new File(jf), entry);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try {
Writer writer = new FileWriter(ClientLoader.hooksFile);
gson.toJson(hooks, writer);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
ByteCodeUtils.updateHijackedJar();
}
public 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) {
hooks.actorClass = current.getName();
System.out.println("[RuneLit] Transforming Actor at class: "+current.getName());
ActorTransform at = new ActorTransform();
at.modify(current);
}
} catch (NoSuchMethodException e) {
//e.printStackTrace();
} catch (NoClassDefFoundError e) {
//e.printStackTrace();
}
}
public static void checkClasses(File jf, JarEntry entry) {
try {
URLClassLoader child = new URLClassLoader(
new URL[] {jf.toURI().toURL()},
cl
);
try {
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
checkActor(classToLoad);
checkProjectile(classToLoad);
checkPlayer(classToLoad);
} catch (Exception e) {
e.printStackTrace();
}
public static void transformActor(Class actor) {
System.out.println("[RuneLit] Transforming Actor at class: "+actor.getName());
ActorTransform at = new ActorTransform();
at.modify(actor);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Class not found: "+entry.getName());
}
}
public static void checkProjectile(Class current) {
try {
Method method = current.getDeclaredMethod("projectileMoved", new Class[] { int.class, int.class, int.class, int.class});
if (method!=null) {
hooks.projectileClass = current.getName();
System.out.println("[RuneLit] Transforming Projectile at class: "+current.getName());
ProjectileTransform pt = new ProjectileTransform();
pt.modify(current);
}
} catch (NoSuchMethodException e) {
//e.printStackTrace();
} catch (NoClassDefFoundError e) {
//e.printStackTrace();
}
}
public 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) {
hooks.actorClass = current.getName();
System.out.println("[RuneLit] Transforming Actor at class: "+current.getName());
ActorTransform at = new ActorTransform();
at.modify(current);
}
} catch (NoSuchMethodException e) {
//e.printStackTrace();
} catch (NoClassDefFoundError e) {
//e.printStackTrace();
}
}
public static void transformProjectile(Class projectile) {
System.out.println("[RuneLit] Transforming Projectile at class: "+projectile.getName());
ProjectileTransform pt = new ProjectileTransform();
pt.modify(projectile);
}
public static void transformActor(Class actor) {
System.out.println("[RuneLit] Transforming Actor at class: "+actor.getName());
ActorTransform at = new ActorTransform();
at.modify(actor);
}
public static void checkPlayer(Class current) {
try {
Method method = current.getDeclaredMethod("getSkullIcon");
if (method!=null) {
hooks.playerClass = current.getName();
System.out.println("[RuneLit] Transforming Player at class: "+current.getName());
PlayerTransform pt = new PlayerTransform();
pt.modify(current);
}
} catch (NoSuchMethodException e) {
//e.printStackTrace();
} catch (NoClassDefFoundError e) {
//e.printStackTrace();
}
}
public static void checkProjectile(Class current) {
try {
Method method = current.getDeclaredMethod("projectileMoved", new Class[] { int.class, int.class, int.class, int.class});
if (method!=null) {
hooks.projectileClass = current.getName();
System.out.println("[RuneLit] Transforming Projectile at class: "+current.getName());
ProjectileTransform pt = new ProjectileTransform();
pt.modify(current);
}
} catch (NoSuchMethodException e) {
//e.printStackTrace();
} catch (NoClassDefFoundError e) {
//e.printStackTrace();
}
}
public static void transformProjectile(Class projectile) {
System.out.println("[RuneLit] Transforming Projectile at class: "+projectile.getName());
ProjectileTransform pt = new ProjectileTransform();
pt.modify(projectile);
}
public static void checkPlayer(Class current) {
try {
Method method = current.getDeclaredMethod("getSkullIcon");
if (method!=null) {
hooks.playerClass = current.getName();
System.out.println("[RuneLit] Transforming Player at class: "+current.getName());
PlayerTransform pt = new PlayerTransform();
pt.modify(current);
}
} catch (NoSuchMethodException e) {
//e.printStackTrace();
} catch (NoClassDefFoundError e) {
//e.printStackTrace();
}
}
public static void transformPlayer(Class player) {
System.out.println("[RuneLit] Transforming Player at class: "+player.getName());
PlayerTransform pt = new PlayerTransform();
pt.modify(player);
}
public static void transformBlackjack(Class clazz) {
System.out.println("[RuneLit] Transforming Blackjack at class: "+clazz.getName());
ClientTransform bt = new ClientTransform();
bt.modify(clazz);
}
public static void transformPlayer(Class player) {
System.out.println("[RuneLit] Transforming Player at class: "+player.getName());
PlayerTransform pt = new PlayerTransform();
pt.modify(player);
}
}

View File

@@ -0,0 +1,194 @@
package net.runelite.client.rs.bytecode.transformers;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtMember;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.bytecode.StackMapTable;
import net.runelite.client.rs.bytecode.ByteCodePatcher;
public class ClientTransform implements Transform {
public CtClass ct = null;
@Override
public void modify(Class clazz) {
try {
ct = ByteCodePatcher.classPool.get(clazz.getName());
transformProtectedGetMenuOptions();
transformProtectedGetMenuTargets();
transformProtectedGetMenuIdentifiers();
transformProtectedGetMenuTypes();
transformProtectedGetMenuActionParams0();
transformProtectedGetMenuActionParams1();
transformGetMenuEntries();
transformSetMenuEntries();
transformOnMenuOptionsChanged();
ByteCodePatcher.modifiedClasses.add(ct);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformProtectedGetMenuOptions() {
CtMethod protectedGetMenuOptions;
try {
protectedGetMenuOptions = ct.getDeclaredMethod("1protect$getMenuOptions");
ct.removeMethod(protectedGetMenuOptions);
protectedGetMenuOptions.setName("getMenuOptions");
ct.addMethod(protectedGetMenuOptions);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformProtectedGetMenuTargets() {
CtMethod protectedGetMenuTargets;
try {
protectedGetMenuTargets = ct.getDeclaredMethod("1protect$getMenuTargets");
ct.removeMethod(protectedGetMenuTargets);
protectedGetMenuTargets.setName("getMenuTargets");
ct.addMethod(protectedGetMenuTargets);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformProtectedGetMenuIdentifiers() {
CtMethod protectedGetMenuIdentifiers;
try {
protectedGetMenuIdentifiers = ct.getDeclaredMethod("1protect$getMenuIdentifiers");
ct.removeMethod(protectedGetMenuIdentifiers);
protectedGetMenuIdentifiers.setName("getMenuIdentifiers");
ct.addMethod(protectedGetMenuIdentifiers);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformProtectedGetMenuTypes() {
CtMethod protectedGetMenuTypes;
try {
protectedGetMenuTypes = ct.getDeclaredMethod("1protect$getMenuTypes");
// Don't remove as this is referenced elsewhere in client
//ct.removeMethod(protectedGetMenuTypes);
CtMethod newProtectedGetMenuTypes = CtNewMethod.copy(protectedGetMenuTypes, ct, null);
newProtectedGetMenuTypes.setName("getMenuTypes");
ct.addMethod(newProtectedGetMenuTypes);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformProtectedGetMenuActionParams0() {
CtMethod protectedGetMenuActionParams0;
try {
protectedGetMenuActionParams0 = ct.getDeclaredMethod("1protect$getMenuActionParams0");
ct.removeMethod(protectedGetMenuActionParams0);
protectedGetMenuActionParams0.setName("getMenuActionParams0");
ct.addMethod(protectedGetMenuActionParams0);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformProtectedGetMenuActionParams1() {
CtMethod protectedGetMenuActionParams1;
try {
protectedGetMenuActionParams1 = ct.getDeclaredMethod("1protect$getMenuActionParams1");
ct.removeMethod(protectedGetMenuActionParams1);
protectedGetMenuActionParams1.setName("getMenuActionParams1");
ct.addMethod(protectedGetMenuActionParams1);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void transform() {}
public void transformGetMenuEntries() {
CtMethod getMenuEntries;
try {
getMenuEntries = ct.getDeclaredMethod("getMenuEntries");
ct.removeMethod(getMenuEntries);
getMenuEntries = CtMethod.make("public net.runelite.api.MenuEntry[] getMenuEntries() {" +
" int n2 = this.getMenuOptionCount();"+
" String[] arrstring = this.getMenuOptions();"+
" String[] arrstring2 = this.getMenuTargets();"+
" int[] arrn = this.getMenuIdentifiers();"+
" int[] arrn2 = this.getMenuTypes();"+
" int[] arrn3 = this.getMenuActionParams0();"+
" int[] arrn4 = this.getMenuActionParams1();"+
" boolean[] arrbl = this.getMenuForceLeftClick();"+
" net.runelite.api.MenuEntry[] arrmenuEntry = new net.runelite.api.MenuEntry[n2];"+
" int n3 = 0;"+
" while (n3 < n2) {"+
" net.runelite.api.MenuEntry menuEntry = arrmenuEntry[n3] = new net.runelite.api.MenuEntry();"+
" menuEntry.setOption(arrstring[n3]);"+
" menuEntry.setTarget(arrstring2[n3]);"+
" menuEntry.setIdentifier(arrn[n3]);"+
" menuEntry.setType(arrn2[n3]);"+
" menuEntry.setParam0(arrn3[n3]);"+
" menuEntry.setParam1(arrn4[n3]);"+
" menuEntry.setForceLeftClick(arrbl[n3]);"+
" ++n3;"+
" }"+
" return arrmenuEntry;"+
" }", ct);
ct.addMethod(getMenuEntries);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformSetMenuEntries() {
CtMethod setMenuEntries;
try {
setMenuEntries = ct.getDeclaredMethods("setMenuEntries"/*, works for now */)[0];
ct.removeMethod(setMenuEntries);
String src;
setMenuEntries = CtNewMethod.make(
"public void setMenuEntries(net.runelite.api.MenuEntry[] paramArrayOfMenuEntry) {" +
"int i = 0;" +
"String[] arrayOfString1 = this.getMenuOptions();" +
"String[] arrayOfString2 = this.getMenuTargets();" +
"int[] arrayOfInt1 = this.getMenuIdentifiers();" +
"int[] arrayOfInt2 = this.getMenuTypes();" +
"int[] arrayOfInt3 = this.getMenuActionParams0();" +
"int[] arrayOfInt4 = this.getMenuActionParams1();" +
"boolean[] arrayOfBoolean = getMenuForceLeftClick();" +
"int testingInt[] = {1,2,3,4,5,6};" +
"for (int m = 0 ; m < paramArrayOfMenuEntry.length ; m++) {" +
"net.runelite.api.MenuEntry menuEntry = paramArrayOfMenuEntry[m];" +
"}" +
"}"
, ct);
ct.addMethod(setMenuEntries);
} catch (Exception e) {
e.printStackTrace();
}
}
public void transformOnMenuOptionsChanged() {
CtMethod onMenuOptionsChanged;
try {
onMenuOptionsChanged = ct.getDeclaredMethod("onMenuOptionsChanged", new CtClass[]{CtClass.intType});
ct.removeMethod(onMenuOptionsChanged);
onMenuOptionsChanged = CtMethod.make(" public static void onMenuOptionsChanged(int n2) {"+
" int n3;" +
" int n4 = oldMenuEntryCount;"+
" oldMenuEntryCount = n3 = "+ByteCodePatcher.clientInstance+".getMenuOptionCount();"+
" if (n3 != n4 + 1) return;"+
" net.runelite.api.events.MenuEntryAdded menuEntryAdded = new net.runelite.api.events.MenuEntryAdded("+ByteCodePatcher.clientInstance+".getMenuOptions()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuTargets()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuTypes()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuIdentifiers()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuActionParams0()[n3 - 1], "+ByteCodePatcher.clientInstance+".getMenuActionParams1()[n3 - 1]);"+
" "+ByteCodePatcher.clientInstance+".getCallbacks().post((Object)menuEntryAdded);" +
" }"
, ct);
ct.addMethod(onMenuOptionsChanged);
} catch (Exception e) {
e.printStackTrace();
}
}
}