diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetField.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetField.java index cf64538c0d..183159844c 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetField.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetField.java @@ -56,6 +56,13 @@ public class GetField extends Instruction implements GetFieldInstruction this.field = field; } + public GetField(Instructions instructions, net.runelite.asm.Field field) + { + super(instructions, InstructionType.GETFIELD); + this.field = field.getPoolField(); + this.myField = field; + } + @Override public String toString() { diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetStatic.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetStatic.java index 83476e76b1..4224223a5d 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetStatic.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/GetStatic.java @@ -56,6 +56,13 @@ public class GetStatic extends Instruction implements GetFieldInstruction this.field = field; } + public GetStatic(Instructions instructions, net.runelite.asm.Field field) + { + super(instructions, InstructionType.GETSTATIC); + this.field = field.getPoolField(); + this.myField = field; + } + @Override public String toString() { diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeSpecial.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeSpecial.java index ea4e2a8254..76c7c6bcf2 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeSpecial.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeSpecial.java @@ -64,6 +64,13 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction this.method = method; } + public InvokeSpecial(Instructions instructions, net.runelite.asm.Method method) + { + super(instructions, InstructionType.INVOKESPECIAL); + this.method = method.getPoolMethod(); + this.myMethod = method; + } + @Override public void accept(MethodVisitor visitor) { diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeStatic.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeStatic.java index bf85f47c95..60e824c6a3 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeStatic.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeStatic.java @@ -64,6 +64,13 @@ public class InvokeStatic extends Instruction implements InvokeInstruction this.method = method; } + public InvokeStatic(Instructions instructions, net.runelite.asm.Method method) + { + super(instructions, InstructionType.INVOKESTATIC); + this.method = method.getPoolMethod(); + this.myMethod = method; + } + @Override public void accept(MethodVisitor visitor) { diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeVirtual.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeVirtual.java index d9c9abb998..7cae2483fa 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeVirtual.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/InvokeVirtual.java @@ -66,6 +66,13 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction this.method = method; } + public InvokeVirtual(Instructions instructions, net.runelite.asm.Method method) + { + super(instructions, InstructionType.INVOKEVIRTUAL); + this.method = method.getPoolMethod(); + this.myMethod = method; + } + @Override public void accept(MethodVisitor visitor) { diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/New.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/New.java index 2479696ca9..5a0284ea23 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/New.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/New.java @@ -56,6 +56,13 @@ public class New extends Instruction implements TypeInstruction this.clazz = clazz; } + public New(Instructions instructions, net.runelite.asm.ClassFile classFile) + { + super(instructions, InstructionType.NEW); + this.clazz = classFile.getPoolClass(); + this.myClass = classFile; + } + @Override public void accept(MethodVisitor visitor) { diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutField.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutField.java index 73094b31b8..e548cfe1d3 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutField.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutField.java @@ -53,6 +53,12 @@ public class PutField extends Instruction implements SetFieldInstruction super(instructions, type); } + public PutField(Instructions instructions, Field field) + { + super(instructions, InstructionType.PUTFIELD); + this.field = field; + } + public PutField(Instructions instructions, net.runelite.asm.Field field) { super(instructions, InstructionType.PUTFIELD); diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutStatic.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutStatic.java index d5e4cc4ed4..9588db5b2b 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutStatic.java +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/code/instructions/PutStatic.java @@ -52,6 +52,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction super(instructions, type); } + public PutStatic(Instructions instructions, Field field) + { + super(instructions, InstructionType.PUTSTATIC); + this.field = field; + } + public PutStatic(Instructions instructions, net.runelite.asm.Field field) { super(instructions, InstructionType.PUTSTATIC); diff --git a/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java b/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java index 5eb4a5c663..7211b20294 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java +++ b/deobfuscator/src/main/java/net/runelite/asm/pool/Field.java @@ -32,7 +32,7 @@ public class Field { private final Class clazz; private final String name; - private final Type type; + private Type type; public Field(Class clazz, String name, Type type) { @@ -102,4 +102,9 @@ public class Field { return type; } + + public void setType(Type type) + { + this.type = type; + } } diff --git a/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java b/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java index 4585655f2e..53d538888d 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java +++ b/deobfuscator/src/main/java/net/runelite/asm/pool/Method.java @@ -31,7 +31,7 @@ public class Method { private final Class clazz; private final String name; - private final Signature type; + private Signature type; public Method(Class clazz, String name, Signature type) { @@ -101,4 +101,9 @@ public class Method { return type; } + + public void setType(Signature type) + { + this.type = type; + } } diff --git a/injector/src/main/java/com/openosrs/injector/InjectUtil.java b/injector/src/main/java/com/openosrs/injector/InjectUtil.java index 79ceabb196..d8c9fbd7c2 100644 --- a/injector/src/main/java/com/openosrs/injector/InjectUtil.java +++ b/injector/src/main/java/com/openosrs/injector/InjectUtil.java @@ -8,6 +8,8 @@ package com.openosrs.injector; import com.openosrs.injector.injection.InjectData; +import static com.openosrs.injector.rsapi.RSApi.API_BASE; +import static com.openosrs.injector.rsapi.RSApi.RL_API_BASE; import com.openosrs.injector.rsapi.RSApiClass; import com.openosrs.injector.rsapi.RSApiMethod; import java.util.List; @@ -42,8 +44,6 @@ import net.runelite.asm.signature.Signature; import net.runelite.deob.DeobAnnotations; import net.runelite.deob.deobfuscators.arithmetic.DMath; import org.jetbrains.annotations.Nullable; -import static com.openosrs.injector.rsapi.RSApi.API_BASE; -import static com.openosrs.injector.rsapi.RSApi.RL_API_BASE; public interface InjectUtil { @@ -552,4 +552,27 @@ public interface InjectUtil { injectObfuscatedGetter(DMath.modInverse(getter), instrs, into); } + + private static List findArgs(final String str, final List ret, final int from, final int to) + { + if (from >= to) + { + return ret; + } + + int i = from; + while (str.charAt(i) == '[') + { + ++i; + } + + if (str.charAt(i) == 'L') + { + i = str.indexOf(';', i); + } + + ret.add(new Type(str.substring(from, ++i))); + + return findArgs(str, ret, i, to); + } } diff --git a/injector/src/main/java/com/openosrs/injector/Injector.java b/injector/src/main/java/com/openosrs/injector/Injector.java index 9c2903f7e0..5216adae21 100644 --- a/injector/src/main/java/com/openosrs/injector/Injector.java +++ b/injector/src/main/java/com/openosrs/injector/Injector.java @@ -22,6 +22,8 @@ import com.openosrs.injector.injectors.raw.GraphicsObject; import com.openosrs.injector.injectors.raw.Occluder; import com.openosrs.injector.injectors.raw.RasterizerAlpha; import com.openosrs.injector.injectors.raw.RenderDraw; +import com.openosrs.injector.injectors.raw.CopyRuneLiteClasses; +import com.openosrs.injector.injectors.raw.RuneLiteIterableHashTable; import com.openosrs.injector.injectors.raw.RuneliteObject; import com.openosrs.injector.injectors.raw.ScriptVM; import com.openosrs.injector.rsapi.RSApi; @@ -111,6 +113,12 @@ public class Injector extends InjectData implements InjectTaskHandler inject(new CreateAnnotations(this)); + inject(new GraphicsObject(this)); + + inject(new CopyRuneLiteClasses(this)); + + inject(new RuneLiteIterableHashTable(this)); + inject(new RuneliteObject(this)); inject(new InterfaceInjector(this)); @@ -142,8 +150,6 @@ public class Injector extends InjectData implements InjectTaskHandler inject(new AddPlayerToMenu(this)); - inject(new GraphicsObject(this)); - validate(new InjectorValidator(this)); transform(new SourceChanger(this)); diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java new file mode 100644 index 0000000000..74ab5b8b74 --- /dev/null +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/CopyRuneLiteClasses.java @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2021, Owain van Brakel + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this submodule. + */ +package com.openosrs.injector.injectors.raw; + +import com.openosrs.injector.InjectUtil; +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.AbstractInjector; +import java.util.List; +import java.util.ListIterator; +import net.runelite.asm.ClassFile; +import net.runelite.asm.Field; +import net.runelite.asm.Method; +import net.runelite.asm.Type; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.GetField; +import net.runelite.asm.attributes.code.instructions.GetStatic; +import net.runelite.asm.attributes.code.instructions.InvokeSpecial; +import net.runelite.asm.attributes.code.instructions.InvokeStatic; +import net.runelite.asm.attributes.code.instructions.InvokeVirtual; +import net.runelite.asm.attributes.code.instructions.New; +import net.runelite.asm.attributes.code.instructions.PutField; +import net.runelite.asm.attributes.code.instructions.PutStatic; +import net.runelite.asm.pool.Class; +import net.runelite.asm.signature.Signature; +import org.objectweb.asm.Opcodes; + +public class CopyRuneLiteClasses extends AbstractInjector +{ + private static final List RUNELITE_OBJECTS = List.of( + "RuneLiteObject", + "RuneLiteIterableHashTable" + ); + + public CopyRuneLiteClasses(InjectData inject) + { + super(inject); + } + + public void inject() + { + for (String className : RUNELITE_OBJECTS) + { + ClassFile runeliteObjectVanilla = inject.vanilla.findClass(className); + + final ClassFile runeLiteObjectDeob = inject.getDeobfuscated() + .findClass(className); + + if (runeliteObjectVanilla == null) + { + runeliteObjectVanilla = new ClassFile(inject.vanilla); + runeliteObjectVanilla.setVersion(Opcodes.V1_8); + runeliteObjectVanilla.setName(className); + runeliteObjectVanilla.setAccess(runeLiteObjectDeob.getAccess()); + + if (runeLiteObjectDeob.getParentClass() != null) + { + ClassFile deobClass = inject.getDeobfuscated().findClass(runeLiteObjectDeob.getParentClass().getName()); + + if (deobClass != null) + { + runeliteObjectVanilla.setParentClass(inject.toVanilla(deobClass).getPoolClass()); + } + else + { + runeliteObjectVanilla.setParentClass(runeLiteObjectDeob.getParentClass()); + } + } + + inject.toVanilla.put(runeLiteObjectDeob, runeliteObjectVanilla); + + for (Class interfaze : runeLiteObjectDeob.getInterfaces()) + { + runeliteObjectVanilla.getInterfaces().addInterface(interfaze); + } + + for (Field field : runeLiteObjectDeob.getFields()) + { + field.setType(InjectUtil.deobToVanilla(inject, field.getType())); + runeliteObjectVanilla.addField(field); + } + + for (Method method : runeLiteObjectDeob.getMethods()) + { + method.setDescriptor(getObfuscatedSignature(method.getDescriptor())); + + Code code = method.getCode(); + + if (code != null) + { + Instructions ins = code.getInstructions(); + for (ListIterator iterator = ins.listIterator(); iterator.hasNext(); ) + { + Instruction i = iterator.next(); + + if (i instanceof PutField) + { + net.runelite.asm.pool.Field field = ((PutField) i).getField(); + Field vanilla = findField(field); + + if (vanilla != null) + { + iterator.set(new PutField(ins, vanilla)); + } + else + { + field.setType(getObfuscatedSignature(field.getType())); + iterator.set(new PutField(ins, field)); + } + } + else if (i instanceof GetField) + { + net.runelite.asm.pool.Field field = ((GetField) i).getField(); + Field vanilla = findField(field); + + if (vanilla != null) + { + iterator.set(new GetField(ins, vanilla)); + } + else + { + field.setType(getObfuscatedSignature(field.getType())); + iterator.set(new GetField(ins, field)); + } + } + else if (i instanceof PutStatic) + { + net.runelite.asm.pool.Field field = ((PutStatic) i).getField(); + Field vanilla = findField(field); + + if (vanilla != null) + { + iterator.set(new PutStatic(ins, vanilla)); + } + else + { + field.setType(getObfuscatedSignature(field.getType())); + iterator.set(new PutStatic(ins, field)); + } + } + else if (i instanceof GetStatic) + { + net.runelite.asm.pool.Field field = ((GetStatic) i).getField(); + Field vanilla = findField(field); + + if (vanilla != null) + { + iterator.set(new GetStatic(ins, vanilla)); + } + else + { + field.setType(getObfuscatedSignature(field.getType())); + iterator.set(new GetStatic(ins, field)); + } + } + else if (i instanceof InvokeSpecial) + { + net.runelite.asm.pool.Method meth = ((InvokeSpecial) i).getMethod(); + Method vanilla = findMethod(meth, true); + + if (vanilla != null) + { + iterator.set(new InvokeSpecial(ins, vanilla)); + } + else + { + meth.setType(getObfuscatedSignature(meth.getType())); + iterator.set(new InvokeSpecial(ins, meth)); + } + } + else if (i instanceof InvokeStatic) + { + net.runelite.asm.pool.Method meth = ((InvokeStatic) i).getMethod(); + Method vanilla = findMethod(meth, false); + + if (vanilla != null) + { + iterator.set(new InvokeStatic(ins, vanilla)); + } + else + { + meth.setType(getObfuscatedSignature(meth.getType())); + iterator.set(new InvokeStatic(ins, meth)); + } + } + else if (i instanceof InvokeVirtual) + { + net.runelite.asm.pool.Method meth = ((InvokeVirtual) i).getMethod(); + Method vanilla = findMethod(meth, true); + + if (vanilla != null) + { + iterator.set(new InvokeVirtual(ins, vanilla)); + } + else + { + meth.setType(getObfuscatedSignature(meth.getType())); + iterator.set(new InvokeVirtual(ins, meth)); + } + } + else if (i instanceof New) + { + + Class clazz = ((New) i).getNewClass(); + ClassFile deobClass = inject.getDeobfuscated().findClass(clazz.getName()); + + if (deobClass != null) + { + iterator.set(new New(ins, inject.toVanilla(deobClass))); + } + } + } + } + + runeliteObjectVanilla.addMethod(method); + } + + inject.vanilla.addClass(runeliteObjectVanilla); + } + } + } + + private Signature getObfuscatedSignature(Signature signature) + { + Signature.Builder builder = new Signature.Builder(); + + for (int j = 0; j < signature.size(); ++j) + { + Type type = signature.getTypeOfArg(j); + builder.addArgument(InjectUtil.deobToVanilla(inject, type)); + } + + builder.setReturnType(InjectUtil.deobToVanilla(inject, signature.getReturnValue())); + + return builder.build(); + } + + private Type getObfuscatedSignature(Type type) + { + return InjectUtil.deobToVanilla(inject, type); + } + + private Method findMethod(net.runelite.asm.pool.Method meth, boolean notStatic) + { + try + { + return InjectUtil.findMethod(inject, meth.getName(), meth.getClazz().getName(), meth.getType()::equals, notStatic, false); + } + catch (Exception e) + { + return null; + } + } + + private Field findField(net.runelite.asm.pool.Field field) + { + try + { + return InjectUtil.findField(inject, field.getName(), field.getClazz().getName()); + } + catch (Exception e) + { + return null; + } + } +} diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java new file mode 100644 index 0000000000..a8c63dd97b --- /dev/null +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneLiteIterableHashTable.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021, Owain van Brakel + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this submodule. + */ +package com.openosrs.injector.injectors.raw; + +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.AbstractInjector; +import java.util.List; +import net.runelite.asm.ClassFile; +import net.runelite.asm.Method; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.InstructionType; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instructions.ALoad; +import net.runelite.asm.attributes.code.instructions.Dup; +import net.runelite.asm.attributes.code.instructions.InvokeSpecial; +import net.runelite.asm.attributes.code.instructions.New; +import net.runelite.asm.attributes.code.instructions.Return; +import net.runelite.asm.signature.Signature; + +public class RuneLiteIterableHashTable extends AbstractInjector +{ + private static final String RUNELITE_ITERABLE_HASHTABLE = "RuneLiteIterableHashTable"; + + public RuneLiteIterableHashTable(InjectData inject) + { + super(inject); + } + + public void inject() + { + ClassFile runeliteIterableHashTableVanilla = inject.vanilla.findClass(RUNELITE_ITERABLE_HASHTABLE); + + final ClassFile nodeHashTableVanilla = inject.toVanilla( + inject.getDeobfuscated() + .findClass("NodeHashTable") + ); + + Method copy = new Method(nodeHashTableVanilla, "iterator", new Signature("()Ljava/util/Iterator;")); + copy.setPublic(); + + final Code code = new Code(copy); + code.setMaxStack(3); + copy.setCode(code); + nodeHashTableVanilla.addMethod(copy); + + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); + + ins.add(new New(instructions, runeliteIterableHashTableVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new ALoad(instructions, 0)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteIterableHashTableVanilla.getPoolClass(), "", new Signature("(L" + nodeHashTableVanilla.getName() + ";)V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); + } +} diff --git a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteObject.java b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteObject.java index 0cfeba8cd2..131479c395 100644 --- a/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteObject.java +++ b/injector/src/main/java/com/openosrs/injector/injectors/raw/RuneliteObject.java @@ -16,14 +16,11 @@ import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.InstructionType; import net.runelite.asm.attributes.code.Instructions; -import net.runelite.asm.attributes.code.instructions.ALoad; import net.runelite.asm.attributes.code.instructions.Dup; import net.runelite.asm.attributes.code.instructions.InvokeSpecial; import net.runelite.asm.attributes.code.instructions.New; import net.runelite.asm.attributes.code.instructions.Return; -import net.runelite.asm.attributes.code.instructions.VReturn; import net.runelite.asm.signature.Signature; -import org.objectweb.asm.Opcodes; public class RuneliteObject extends AbstractInjector { @@ -38,66 +35,25 @@ public class RuneliteObject extends AbstractInjector { ClassFile runeliteObjectVanilla = inject.vanilla.findClass(RUNELITE_OBJECT); - final ClassFile graphicsObjectVanilla = inject.toVanilla( - inject.getDeobfuscated() - .findClass("GraphicsObject") - ); - - graphicsObjectVanilla.clearFinal(); - final ClassFile clientVanilla = inject.toVanilla( inject.getDeobfuscated() .findClass("Client") ); - final ClassFile runeLiteObjectDeob = inject.getDeobfuscated() - .findClass(RUNELITE_OBJECT); + Method copy = new Method(clientVanilla, "createRuneLiteObject", new Signature("()Lnet/runelite/api/RuneLiteObject;")); + copy.setPublic(); - if (runeliteObjectVanilla == null) - { - runeliteObjectVanilla = new ClassFile(inject.vanilla); - runeliteObjectVanilla.setName(RUNELITE_OBJECT); - runeliteObjectVanilla.setParentClass(graphicsObjectVanilla.getPoolClass()); - runeliteObjectVanilla.setAccess(Opcodes.ACC_PUBLIC); - runeliteObjectVanilla.setVersion(Opcodes.V1_8); - inject.vanilla.addClass(runeliteObjectVanilla); + final Code code = new Code(copy); + code.setMaxStack(2); + copy.setCode(code); + clientVanilla.addMethod(copy); - inject.toVanilla.put(runeLiteObjectDeob, runeliteObjectVanilla); - } + final Instructions instructions = code.getInstructions(); + final List ins = instructions.getInstructions(); - { - Method initRuneliteObject = new Method(runeliteObjectVanilla, "", new Signature("()V")); - initRuneliteObject.setPublic(); - - final Code code = new Code(initRuneliteObject); - code.setMaxStack(1); - initRuneliteObject.setCode(code); - runeliteObjectVanilla.addMethod(initRuneliteObject); - - final Instructions instructions = code.getInstructions(); - final List ins = instructions.getInstructions(); - - ins.add(new ALoad(instructions, 0)); - ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(graphicsObjectVanilla.getPoolClass(), "", new Signature("()V")))); - ins.add(new VReturn(instructions)); - } - - { - Method copy = new Method(clientVanilla, "createRuneLiteObject", new Signature("()Lnet/runelite/api/RuneLiteObject;")); - copy.setPublic(); - - final Code code = new Code(copy); - code.setMaxStack(2); - copy.setCode(code); - clientVanilla.addMethod(copy); - - final Instructions instructions = code.getInstructions(); - final List ins = instructions.getInstructions(); - - ins.add(new New(instructions, runeliteObjectVanilla.getPoolClass())); - ins.add(new Dup(instructions)); - ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteObjectVanilla.getPoolClass(), "", new Signature("()V")))); - ins.add(new Return(instructions, InstructionType.ARETURN)); - } + ins.add(new New(instructions, runeliteObjectVanilla.getPoolClass())); + ins.add(new Dup(instructions)); + ins.add(new InvokeSpecial(instructions, new net.runelite.asm.pool.Method(runeliteObjectVanilla.getPoolClass(), "", new Signature("()V")))); + ins.add(new Return(instructions, InstructionType.ARETURN)); } } 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 c529b073da..6afd761a68 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 @@ -78,7 +78,7 @@ import okhttp3.Response; public class ClientLoader implements Supplier { private static final String INJECTED_CLIENT_NAME = "/injected-client.oprs"; - private static final int NUM_ATTEMPTS = 6; + private static final int NUM_ATTEMPTS = 0; private static File LOCK_FILE = new File(RuneLite.CACHE_DIR, "cache.lock"); private static File VANILLA_CACHE = new File(RuneLite.CACHE_DIR, "vanilla.cache"); private static File PATCHED_CACHE = new File(RuneLite.CACHE_DIR, "patched.cache"); diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 28b9893321..e66e32b460 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -137,6 +137,7 @@ import net.runelite.api.widgets.WidgetType; import net.runelite.rs.api.RSAbstractArchive; import net.runelite.rs.api.RSArchive; import net.runelite.rs.api.RSChatChannel; +import net.runelite.rs.api.RSClanChannel; import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSEnumComposition; import net.runelite.rs.api.RSFriendSystem; @@ -2319,20 +2320,20 @@ public abstract class RSClientMixin implements RSClient @FieldHook("guestClanChannel") public static void onGuestClanChannelChanged(int idx) { - client.getCallbacks().post(new ClanChannelChanged(client.getGuestClanChannel(), true)); + client.getCallbacks().post(new ClanChannelChanged(client.getGuestClanChannel(), -1, true)); } @Inject @FieldHook("currentClanChannels") public static void onCurrentClanChannelsChanged(int idx) { - if (idx == -1) - { - // don't fire on array field itself being set - return; - } + RSClanChannel[] clanChannels = client.getCurrentClanChannels(); - client.getCallbacks().post(new ClanChannelChanged(client.getClanChannel(), false)); + if (idx >= 0 && idx < clanChannels.length) + { + RSClanChannel clanChannel = clanChannels[idx]; + client.getCallbacks().post(new ClanChannelChanged(clanChannel, idx, false)); + } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNodeHashTableMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNodeHashTableMixin.java index dd67fb5a1f..c457087a84 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSNodeHashTableMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNodeHashTableMixin.java @@ -1,38 +1,8 @@ package net.runelite.mixins; -import net.runelite.api.Node; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; import net.runelite.rs.api.RSNodeHashTable; @Mixin(RSNodeHashTable.class) public abstract class RSNodeHashTableMixin implements RSNodeHashTable -{ - @Inject - @Override - public Collection getNodes() - { - // Copied in RSWidgetMixin.getParentId to reduce allocations - List nodes = new ArrayList(); - - Node[] buckets = getBuckets(); - for (int i = 0; i < buckets.length; ++i) - { - Node node = buckets[i]; - - // It looks like the first node in the bucket is always - // a sentinel - Node cur = node.getNext(); - while (cur != node) - { - nodes.add(cur); - cur = cur.getNext(); - } - } - - return nodes; - } -} +{} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java index 99d9c61bec..b4db85cf4e 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RuneLiteObjectMixin.java @@ -42,24 +42,9 @@ public abstract class RuneLiteObjectMixin implements RSRuneLiteObject @Shadow("client") private static RSClient client; - @Inject - private static boolean loop; - @Inject private static RSModel model; - @Inject - RuneLiteObjectMixin() - { - setFinished(true); - } - - @Inject - public void setModel(Model var1) - { - model = (RSModel) var1; - } - @Inject public void setLocation(LocalPoint localPoint, int plane) { @@ -69,6 +54,14 @@ public abstract class RuneLiteObjectMixin implements RSRuneLiteObject setHeight(Perspective.getTileHeight(client, localPoint, plane)); } + @Inject + public void setAnimation(Sequence var1) + { + setFrame(0); + setFrameCycle(0); + setSequenceDefinition((RSSequenceDefinition) var1); + } + @Inject public void advanceRL(int var1) { @@ -90,7 +83,7 @@ public abstract class RuneLiteObjectMixin implements RSRuneLiteObject } } - if (loop && finished()) + if (isLooping() && finished()) { setFinished(false); setFrame(0); @@ -100,44 +93,9 @@ public abstract class RuneLiteObjectMixin implements RSRuneLiteObject } @Inject - public boolean isActive() + public void setModel(Model var1) { - return !finished(); - } - - @Inject - public void setActive(boolean active) - { - if (finished() == active) - { - setFinished(!active); - - if (active) - { - setFrame(0); - setFrameCycle(0); - client.getGraphicsObjectDeque().addFirst(this); - } - else - { - unlink(); - } - - } - } - - @Inject - public void setShouldLoop(boolean var1) - { - loop = var1; - } - - @Inject - public void setAnimation(Sequence var1) - { - setFrame(0); - setFrameCycle(0); - setSequenceDefinition((RSSequenceDefinition) var1); + model = (RSModel) var1; } @Inject diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java new file mode 100644 index 0000000000..29833ca736 --- /dev/null +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteIterableHashTable.java @@ -0,0 +1,4 @@ +package net.runelite.rs.api; + +public interface RSRuneLiteIterableHashTable +{} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteObject.java b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteObject.java index a1bd48c7ba..eb44ef1abd 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteObject.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSRuneLiteObject.java @@ -4,6 +4,8 @@ import net.runelite.api.RuneLiteObject; public interface RSRuneLiteObject extends RuneLiteObject, RSGraphicsObject { + boolean isLooping(); + void advanceRL(int var1); RSModel getModelRl(); diff --git a/runescape-client/src/main/java/RuneLiteIterableHashTable.java b/runescape-client/src/main/java/RuneLiteIterableHashTable.java new file mode 100644 index 0000000000..ca4f181efb --- /dev/null +++ b/runescape-client/src/main/java/RuneLiteIterableHashTable.java @@ -0,0 +1,70 @@ +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class RuneLiteIterableHashTable implements Iterator +{ + public Node node; + public final NodeHashTable nodeHashTable; + public int it; + + public RuneLiteIterableHashTable(NodeHashTable nodeHashTable) + { + this.nodeHashTable = nodeHashTable; + } + + @Override + public boolean hasNext() + { + if (this.it > 0 && this.nodeHashTable.buckets[this.it - 1] != this.node) + { + return true; + } + else + { + for (int i = this.it; i < this.nodeHashTable.size; ++i) + { + Node bucket = this.nodeHashTable.buckets[i]; + Node previous = bucket.previous; + + if (bucket != previous) + { + return true; + } + } + + return false; + } + } + + @Override + public Node next() + { + if (this.it > 0 && this.nodeHashTable.buckets[this.it - 1] != this.node) + { + Node node = this.node; + this.node = node.previous; + + return node; + } + else + { + Node node; + Node previous; + + do + { + if (this.it >= this.nodeHashTable.size) + { + throw new NoSuchElementException(); + } + + node = this.nodeHashTable.buckets[this.it++]; + previous = node.previous; + } while (node == previous); + + this.node = previous.previous; + + return previous; + } + } +} diff --git a/runescape-client/src/main/java/RuneLiteObject.java b/runescape-client/src/main/java/RuneLiteObject.java index 1990b62e27..e4afc402de 100644 --- a/runescape-client/src/main/java/RuneLiteObject.java +++ b/runescape-client/src/main/java/RuneLiteObject.java @@ -7,6 +7,10 @@ public class RuneLiteObject extends GraphicsObject super.isFinished = true; } + public boolean isLooping() { + return loop; + } + public boolean isActive() { return !super.isFinished; } @@ -35,33 +39,6 @@ public class RuneLiteObject extends GraphicsObject this.loop = var1; } - @Override - public void advance(int var1) - { - if (super.sequenceDefinition != null) { - super.advance(var1); - if (this.loop && super.isFinished) { - super.isFinished = false; - super.frame = 0; - super.frameCycle = 0; - } - - } - } - - @Override - public Model getModel() - { - if (super.sequenceDefinition != null) - { - return super.sequenceDefinition.transformSpotAnimationModel(this.model, super.frame); - } - else - { - return this.model.toSharedSequenceModel(true); - } - } - public void setModel(Model var1) { this.model = var1; }