diff --git a/src/main/java/com/openosrs/injector/InjectUtil.java b/src/main/java/com/openosrs/injector/InjectUtil.java index 0179271..b6683d3 100644 --- a/src/main/java/com/openosrs/injector/InjectUtil.java +++ b/src/main/java/com/openosrs/injector/InjectUtil.java @@ -6,6 +6,7 @@ import static com.openosrs.injector.rsapi.RSApi.API_BASE; import com.openosrs.injector.rsapi.RSApiClass; import com.openosrs.injector.rsapi.RSApiMethod; import java.util.List; +import java.util.function.Predicate; import java.util.stream.Collectors; import net.runelite.asm.Annotated; import net.runelite.asm.ClassFile; @@ -60,7 +61,7 @@ public interface InjectUtil InjectData data, String name, String classHint, - Signature sig) + @Nullable Predicate sig) throws Injexception { return findMethod(data, name, classHint, sig, false, false); @@ -99,7 +100,7 @@ public interface InjectUtil InjectData data, String name, @Nullable String classHint, - @Nullable Signature sig, + @Nullable Predicate sig, boolean notStatic, boolean returnDeob) throws Injexception @@ -113,11 +114,9 @@ public interface InjectUtil if (notStatic) { if (sig == null) - m = cf.findMethodDeep(name); + m = InjectUtil.findMethodDeep(cf, name, s -> true); else - m = cf.findMethodDeep(name, sig); - if (m == null) - throw new Injexception(String.format("Couldn't find %s in subclasses of %s", name, classHint)); + m = InjectUtil.findMethodDeep(cf, name, sig); } else m = cf.findMethod(name); @@ -130,7 +129,7 @@ public interface InjectUtil for (Method m : cf.getMethods()) if (m.getName().equals(name)) if (!notStatic || !m.isStatic()) - if (sig == null || sig.equals(m.getDescriptor())) + if (sig == null || sig.test(m.getDescriptor())) return returnDeob ? m : data.toVanilla(m); throw new Injexception(String.format("Couldn't find %s", name)); @@ -145,59 +144,19 @@ public interface InjectUtil return clazz; } - static Method findMethodWithArgs(InjectData data, String name, String hintClass, Signature sig) throws Injexception - { - final ClassGroup deob = data.getDeobfuscated(); - if (hintClass != null) - { - ClassFile clazz = findClassOrThrow(deob, hintClass); - Method method = clazz.findStaticMethod(name); - - if (method != null && argsMatch(sig, method.getDescriptor())) - return data.toVanilla(method); - } - - for (ClassFile c : deob) - for (Method m : c.getMethods()) - if (m.getName().equals(name) && argsMatch(sig, m.getDescriptor())) - return data.toVanilla(m); - - throw new Injexception("Method called " + name + " with args matching " + sig + " doesn't exist"); - } - - static Method findMethodWithArgsDeep(InjectData data, ClassFile clazz, String name, Signature sig) throws Injexception + /** + * Fail-fast implementation of ClassFile.findMethodDeep, using a predicate for signature + */ + static Method findMethodDeep(ClassFile clazz, String name, Predicate type) throws Injexception { do - for (Method m : clazz.getMethods()) - if (m.getName().equals(name) && argsMatch(sig, m.getDescriptor())) - return data.toVanilla(m); + for (Method method : clazz.getMethods()) + if (method.getName().equals(name)) + if (type.test(method.getDescriptor())) + return method; while ((clazz = clazz.getParent()) != null); - throw new Injexception("Method called " + name + " with args matching " + sig + " doesn't exist"); - } - - /** - * Fail-fast implementation of ClassGroup.findStaticMethod - */ - static Method findStaticMethod(ClassGroup group, String name, Signature type) throws Injexception - { - Method m = group.findStaticMethod(name, type); - if (m == null) - throw new Injexception(String.format("Method %s couldn't be found", name + type.toString())); - - return m; - } - - /** - * Fail-fast implementation of ClassFile.findMethodDeep - */ - static Method findMethodDeep(ClassFile clazz, String name, Signature type) throws Injexception - { - Method m = clazz.findMethodDeep(name, type); - if (m == null) - throw new Injexception(String.format("Method %s couldn't be found", name + type.toString())); - - return m; + throw new Injexception(String.format("Method %s couldn't be found", name + type.toString())); } /** diff --git a/src/main/java/com/openosrs/injector/Injection.java b/src/main/java/com/openosrs/injector/Injection.java index 3e3f3c0..a5343d0 100644 --- a/src/main/java/com/openosrs/injector/Injection.java +++ b/src/main/java/com/openosrs/injector/Injection.java @@ -9,6 +9,7 @@ import com.openosrs.injector.injectors.MixinInjector; import com.openosrs.injector.injectors.RSApiInjector; import com.openosrs.injector.injectors.raw.ClearColorBuffer; import com.openosrs.injector.injectors.raw.DrawAfterWidgets; +import com.openosrs.injector.injectors.raw.HidePlayerAttacks; import com.openosrs.injector.injectors.raw.Occluder; import com.openosrs.injector.injectors.raw.RasterizerAlpha; import com.openosrs.injector.injectors.raw.RenderDraw; @@ -66,7 +67,7 @@ public class Injection extends InjectData implements InjectTaskHandler // inject(new DrawMenu(this)); - // inject(new HidePlayerAttacks(this)); + inject(new HidePlayerAttacks(this)); validate(new InjectorValidator(this)); } diff --git a/src/main/java/com/openosrs/injector/InjectorValidator.java b/src/main/java/com/openosrs/injector/InjectorValidator.java index 8c1d47a..a412291 100644 --- a/src/main/java/com/openosrs/injector/InjectorValidator.java +++ b/src/main/java/com/openosrs/injector/InjectorValidator.java @@ -31,9 +31,7 @@ public class InjectorValidator implements Validator for (Class intf : cf.getInterfaces()) { if (!intf.getName().startsWith(API_BASE)) - { continue; - } RSApiClass apiC = rsApi.findClass(intf.getName()); if (apiC == null) @@ -59,9 +57,7 @@ public class InjectorValidator implements Validator for (RSApiMethod apiMethod : apiClass) { if (apiMethod.isSynthetic() || apiMethod.isDefault()) - { continue; - } if (clazz.findMethodDeep(apiMethod.getName(), apiMethod.getSignature()) == null) { diff --git a/src/main/java/com/openosrs/injector/injection/InjectData.java b/src/main/java/com/openosrs/injector/injection/InjectData.java index 7daa80a..89304db 100644 --- a/src/main/java/com/openosrs/injector/injection/InjectData.java +++ b/src/main/java/com/openosrs/injector/injection/InjectData.java @@ -5,8 +5,6 @@ import com.openosrs.injector.InjectUtil; import com.openosrs.injector.Injexception; import com.openosrs.injector.injectors.Injector; import com.openosrs.injector.rsapi.RSApi; -import static com.openosrs.injector.rsapi.RSApi.*; -import com.openosrs.injector.rsapi.RSApiClass; import java.util.HashMap; import java.util.Map; import java.util.function.BiConsumer; @@ -16,7 +14,6 @@ import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; import net.runelite.asm.Type; -import net.runelite.asm.pool.Class; import net.runelite.asm.signature.Signature; /** @@ -155,34 +152,4 @@ public abstract class InjectData action.accept(pair.getKey(), pair.getValue()); } } - - public Type deobfuscatedTypeToApiType(Type type) - { - if (type.isPrimitive()) - { - return type; - } - - ClassFile cf = deobfuscated.findClass(type.getInternalName()); - if (cf == null) - { - return type; // not my type - } - - RSApiClass apiClass = rsApi.findClass(API_BASE + cf.getName()); - - Class rlApiType = null; - - for (Class intf : apiClass.getInterfaces()) - { - if (intf.getName().startsWith(RL_API_BASE)) - { - rlApiType = intf; - } - } - - final Class finalType = rlApiType == null ? apiClass.getClazz() : rlApiType; - - return Type.getType("L" + finalType.getName() + ";", type.getDimensions()); - } } diff --git a/src/main/java/com/openosrs/injector/injectors/InjectConstruct.java b/src/main/java/com/openosrs/injector/injectors/InjectConstruct.java index 33825bc..34c9196 100644 --- a/src/main/java/com/openosrs/injector/injectors/InjectConstruct.java +++ b/src/main/java/com/openosrs/injector/injectors/InjectConstruct.java @@ -39,9 +39,7 @@ public class InjectConstruct extends AbstractInjector { Annotation construct = apiMethod.getAnnotations().find(CONSTRUCT); if (construct == null) - { continue; - } final Method method = apiMethod.getMethod(); final Class clazz = method.getClazz(); @@ -75,9 +73,8 @@ public class InjectConstruct extends AbstractInjector final net.runelite.asm.Method constructor = classToConstruct.findMethod("", constr); if (constructor == null) - { throw new Injexception("Unable to find constructor for " + classToConstruct.getName() + "." + constr); - } + net.runelite.asm.Method setterMethod = new net.runelite.asm.Method(targetClass, apiMethod.getName(), apiMethod.getType()); setterMethod.setAccessFlags(ACC_PUBLIC); diff --git a/src/main/java/com/openosrs/injector/injectors/InjectHook.java b/src/main/java/com/openosrs/injector/injectors/InjectHook.java index cd7c2a5..48d3079 100644 --- a/src/main/java/com/openosrs/injector/injectors/InjectHook.java +++ b/src/main/java/com/openosrs/injector/injectors/InjectHook.java @@ -57,9 +57,7 @@ public class InjectHook extends AbstractInjector public void inject() throws Injexception { for (Map.Entry, List> entry : mixinTargets.entrySet()) - { injectMethods(entry.getKey(), entry.getValue()); - } injectHooks(); @@ -124,33 +122,23 @@ public class InjectHook extends AbstractInjector Method method = code.getMethod(); if (method.getName().equals(CLINIT)) - { return; - } if (!(i instanceof SetFieldInstruction)) - { return; - } if (!done.add(i)) - { return; - } SetFieldInstruction sfi = (SetFieldInstruction) i; Field fieldBeingSet = sfi.getMyField(); if (fieldBeingSet == null) - { return; - } HookInfo hookInfo = hooked.get(fieldBeingSet); if (hookInfo == null) - { return; - } log.trace("Found injection location for hook {} at instruction {}", hookInfo.method.getName(), sfi); ++injectedHooks; @@ -159,9 +147,7 @@ public class InjectHook extends AbstractInjector StackContext objectStackContext = null; if (sfi instanceof PutField) - { objectStackContext = ic.getPops().get(1); - } int idx = ins.getInstructions().indexOf(sfi); assert idx != -1; @@ -169,14 +155,10 @@ public class InjectHook extends AbstractInjector try { if (hookInfo.before) - { injectCallbackBefore(ins, idx, hookInfo, null, objectStackContext, value); - } else - { // idx + 1 to insert after the set injectCallback(ins, idx + 1, hookInfo, null, objectStackContext); - } } catch (Injexception ex) { @@ -197,33 +179,23 @@ public class InjectHook extends AbstractInjector Method method = code.getMethod(); if (method.getName().equals(CLINIT)) - { return; - } if (!(i instanceof ArrayStore)) - { return; - } if (!doneIh.add(i)) - { return; - } ArrayStore as = (ArrayStore) i; Field fieldBeingSet = as.getMyField(ic); if (fieldBeingSet == null) - { return; - } HookInfo hookInfo = hooked.get(fieldBeingSet); if (hookInfo == null) - { return; - } StackContext value = ic.getPops().get(0); StackContext index = ic.getPops().get(1); @@ -233,9 +205,7 @@ public class InjectHook extends AbstractInjector StackContext objectStackContext = null; if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD) - { objectStackContext = arrayReferencePushed.getPops().get(0); - } // inject hook after 'i' log.debug("Found array injection location for hook {} at instruction {}", hookInfo.method.getName(), i); @@ -247,13 +217,9 @@ public class InjectHook extends AbstractInjector try { if (hookInfo.before) - { injectCallbackBefore(ins, idx, hookInfo, index, objectStackContext, value); - } else - { injectCallback(ins, idx + 1, hookInfo, index, objectStackContext); - } } catch (Injexception ex) { @@ -272,9 +238,7 @@ public class InjectHook extends AbstractInjector if (!hookInfo.method.isStatic()) { if (object == null) - { throw new Injexception("null object"); - } ins.getInstructions().add(idx++, new Dup(ins)); // dup value idx = recursivelyPush(ins, idx, object); @@ -308,7 +272,7 @@ public class InjectHook extends AbstractInjector } Instruction invoke = hookInfo.getInvoke(ins); - ins.getInstructions().add(idx++, invoke); + ins.getInstructions().add(idx, invoke); } private int recursivelyPush(Instructions ins, int idx, StackContext sctx) @@ -322,9 +286,7 @@ public class InjectHook extends AbstractInjector } for (StackContext s : Lists.reverse(ctx.getPops())) - { idx = recursivelyPush(ins, idx, s); - } ins.getInstructions().add(idx++, ctx.getInstruction().clone()); return idx; @@ -341,16 +303,12 @@ public class InjectHook extends AbstractInjector } if (index != null) - { idx = recursivelyPush(ins, idx, index); - } else - { ins.getInstructions().add(idx++, new LDC(ins, -1)); - } Instruction invoke = hookInfo.getInvoke(ins); - ins.getInstructions().add(idx++, invoke); + ins.getInstructions().add(idx, invoke); } @AllArgsConstructor diff --git a/src/main/java/com/openosrs/injector/injectors/InjectHookMethod.java b/src/main/java/com/openosrs/injector/injectors/InjectHookMethod.java index 8622de5..1de8412 100644 --- a/src/main/java/com/openosrs/injector/injectors/InjectHookMethod.java +++ b/src/main/java/com/openosrs/injector/injectors/InjectHookMethod.java @@ -35,9 +35,7 @@ public class InjectHookMethod extends AbstractInjector public void inject() throws Injexception { for (Map.Entry, List> entry : mixinTargets.entrySet()) - { injectMethods(entry.getKey(), entry.getValue()); - } log.info("Injected {} method hooks", injected); } @@ -52,9 +50,7 @@ public class InjectHookMethod extends AbstractInjector { final Annotation methodHook = mixinMethod.getAnnotations().find(METHODHOOK); if (methodHook == null) - { continue; - } if (!mixinMethod.getDescriptor().isVoid()) throw new Injexception("Method hook " + mixinMethod.getPoolMethod() + " doesn't have void return type"); @@ -64,18 +60,8 @@ public class InjectHookMethod extends AbstractInjector final ClassFile deobTarget = inject.toDeob(targetClass.getName()); final Signature deobSig = InjectUtil.apiToDeob(inject, mixinMethod.getDescriptor()); - - final Method targetMethod; - if (mixinMethod.isStatic()) - { - targetMethod = InjectUtil.findMethodWithArgs(inject, hookName, deobTarget.getName(), deobSig); // , deobSig); - } - else - { - targetMethod = InjectUtil.findMethodWithArgsDeep(inject, deobTarget, hookName, deobSig); - } - - assert mixinMethod.isStatic() == targetMethod.isStatic() : "Mixin method isn't static but deob has a static method named the same as the hook, and I was too lazy to do something about this bug"; + final boolean notStatic = !mixinMethod.isStatic(); + final Method targetMethod = InjectUtil.findMethod(inject, hookName, deobTarget.getName(), sig -> InjectUtil.argsMatch(sig, deobSig), notStatic, false); final net.runelite.asm.pool.Method hookMethod = new net.runelite.asm.pool.Method( targetClass.getPoolClass(), @@ -94,32 +80,24 @@ public class InjectHookMethod extends AbstractInjector private void inject(final Method method, final net.runelite.asm.pool.Method hookMethod, boolean end) { final Instructions ins = method.getCode().getInstructions(); + final ListIterator it; if (end) { - final ListIterator it = ins.listIterator(ins.size() - 1); + it = ins.listIterator(ins.size()); while (it.hasPrevious()) - { if (it.previous() instanceof ReturnInstruction) - { insertVoke(method, hookMethod, it); - } - } return; } - final ListIterator it = ins.listIterator(); - + it = ins.listIterator(); if (method.getName().equals("")) { while (it.hasNext()) - { if (it.next() instanceof InvokeSpecial) - { break; - } - } assert it.hasNext() : "Constructor without invokespecial"; } @@ -133,9 +111,7 @@ public class InjectHookMethod extends AbstractInjector int varIdx = 0; if (!method.isStatic()) - { iterator.add(new ALoad(instructions, varIdx++)); - } for (Type type : hookMethod.getType().getArguments()) { diff --git a/src/main/java/com/openosrs/injector/injectors/InterfaceInjector.java b/src/main/java/com/openosrs/injector/injectors/InterfaceInjector.java index 3df3dca..d747162 100644 --- a/src/main/java/com/openosrs/injector/injectors/InterfaceInjector.java +++ b/src/main/java/com/openosrs/injector/injectors/InterfaceInjector.java @@ -29,9 +29,7 @@ public class InterfaceInjector extends AbstractInjector final String impls = DeobAnnotations.getImplements(deobCf); if (impls == null) - { return; - } final String fullName = API_BASE + impls; if (!inject.getRsApi().hasClass(fullName)) diff --git a/src/main/java/com/openosrs/injector/injectors/MixinInjector.java b/src/main/java/com/openosrs/injector/injectors/MixinInjector.java index 2ccf7b3..890facc 100644 --- a/src/main/java/com/openosrs/injector/injectors/MixinInjector.java +++ b/src/main/java/com/openosrs/injector/injectors/MixinInjector.java @@ -109,14 +109,7 @@ public class MixinInjector extends AbstractInjector if (MIXIN.equals(annotation.getType())) { builder.put( - new Provider() - { - @Override - public ClassFile get() - { - return mixinClass; - } - }, + () -> mixinClass, ImmutableList.of(InjectUtil.getVanillaClassFromAnnotationString(inject, annotation)) ); } @@ -129,15 +122,11 @@ public class MixinInjector extends AbstractInjector @Override public ClassFile get() { - if (bytes == null) - { - bytes = JarUtil.writeClass(mixinClass.getGroup(), mixinClass); - return mixinClass; - } - else - { + if (bytes != null) return JarUtil.loadClass(bytes); - } + + bytes = JarUtil.writeClass(mixinClass.getGroup(), mixinClass); + return mixinClass; } }; @@ -168,32 +157,28 @@ public class MixinInjector extends AbstractInjector { for (Field field : mixinClass.getFields()) { - if (field.getAnnotations().find(INJECT) != null || - ASSERTION_FIELD.equals(field.getName()) && - targetClass.findField(ASSERTION_FIELD, Type.BOOLEAN) == null) + if (field.getAnnotations().find(INJECT) == null && + (!ASSERTION_FIELD.equals(field.getName()) || + targetClass.findField(ASSERTION_FIELD, Type.BOOLEAN) != null)) { - Field copy = new Field(targetClass, field.getName(), field.getType()); - copy.setAccessFlags(field.getAccessFlags()); - copy.setPublic(); - copy.setValue(field.getValue()); - - for (Annotation annotation : field.getAnnotations()) - { - if (!annotation.getType().toString().startsWith("Lnet/runelite/api/mixins")) - { - copy.getAnnotations().addAnnotation(annotation); - } - } - - targetClass.addField(copy); - - if (injectedFields.containsKey(field.getName()) && !ASSERTION_FIELD.equals(field.getName())) - { - throw new Injexception("Duplicate field: " + field.getName()); - } - - injectedFields.put(field.getName(), copy); + continue; } + + Field copy = new Field(targetClass, field.getName(), field.getType()); + copy.setAccessFlags(field.getAccessFlags()); + copy.setPublic(); + copy.setValue(field.getValue()); + + for (Annotation annotation : field.getAnnotations()) + if (!annotation.getType().toString().startsWith("Lnet/runelite/api/mixins")) + copy.getAnnotations().addAnnotation(annotation); + + targetClass.addField(copy); + + if (injectedFields.containsKey(field.getName()) && !ASSERTION_FIELD.equals(field.getName())) + throw new Injexception("Duplicate field: " + field.getName()); + + injectedFields.put(field.getName(), copy); } } } @@ -206,23 +191,20 @@ public class MixinInjector extends AbstractInjector { Annotation shadow = field.getAnnotations().find(SHADOW); - if (shadow != null) - { - if (!field.isStatic()) - { - throw new Injexception("Shadowed fields must be static"); - } + if (shadow == null) + continue; - String shadowed = shadow.getElement().getString(); + if (!field.isStatic()) + throw new Injexception("Shadowed fields must be static"); - Field targetField = injectedFields.get(shadowed); - if (targetField == null) - { - targetField = InjectUtil.findStaticField(inject, shadowed, null, InjectUtil.apiToDeob(inject, field.getType())); - } + String shadowed = shadow.getElement().getString(); - shadowFields.put(field.getPoolField(), targetField); - } + Field targetField = injectedFields.get(shadowed); + + if (targetField == null) + targetField = InjectUtil.findStaticField(inject, shadowed, null, InjectUtil.apiToDeob(inject, field.getType())); + + shadowFields.put(field.getPoolField(), targetField); } } @@ -240,28 +222,22 @@ public class MixinInjector extends AbstractInjector { Annotation copyA = mixinMethod.getAnnotations().find(COPY); if (copyA == null) - { continue; - } String copiedName = copyA.getElement().getString(); Signature deobSig = InjectUtil.apiToDeob(inject, mixinMethod.getDescriptor()); boolean notStat = !mixinMethod.isStatic(); - Method deobSourceMethod = InjectUtil.findMethod(inject, copiedName, inject.toDeob(targetClass.getName()).getName(), deobSig, notStat, true); + Method deobSourceMethod = InjectUtil.findMethod(inject, copiedName, inject.toDeob(targetClass.getName()).getName(), deobSig::equals, notStat, true); if (mixinMethod.isStatic() != deobSourceMethod.isStatic()) - { throw new Injexception("Mixin method " + mixinMethod + " should be " + (deobSourceMethod.isStatic() ? "static" : "non-static")); - } // The actual method we're copying, including code etc Method sourceMethod = inject.toVanilla(deobSourceMethod); if (mixinMethod.getDescriptor().size() > sourceMethod.getDescriptor().size()) - { throw new Injexception("Mixin methods cannot have more parameters than their corresponding ob method"); - } Method copy = new Method(targetClass, "copy$" + copiedName, sourceMethod.getDescriptor()); moveCode(copy, sourceMethod.getCode()); @@ -294,9 +270,7 @@ public class MixinInjector extends AbstractInjector if ((hasInject && isInit) || isClinit) { if (!"()V".equals(mixinMethod.getDescriptor().toString())) - { throw new Injexception("Injected constructors cannot have arguments"); - } Method[] originalMethods = targetClass.getMethods().stream() .filter(m -> m.getName().equals(mixinMethod.getName())) @@ -307,15 +281,11 @@ public class MixinInjector extends AbstractInjector // If there isn't a already just inject ours, otherwise rename it // This is always true for if (originalMethods.length > 0) - { name = "rl$$" + (isInit ? "init" : "clinit"); - } String numberlessName = name; for (int i = 1; targetClass.findMethod(name, mixinMethod.getDescriptor()) != null; i++) - { name = numberlessName + i; - } Method copy = new Method(targetClass, name, mixinMethod.getDescriptor()); moveCode(copy, mixinMethod.getCode()); @@ -337,10 +307,10 @@ public class MixinInjector extends AbstractInjector assert invoke.getMethod().getName().equals(""); listIter.remove(); int pops = invoke.getMethod().getType().getArguments().size() + 1; + for (int i = 0; i < pops; i++) - { listIter.add(new Pop(instructions)); - } + break; } } @@ -502,16 +472,15 @@ public class MixinInjector extends AbstractInjector Code newCode = new Code(targetMethod); newCode.setMaxStack(sourceCode.getMaxStack()); newCode.getInstructions().getInstructions().addAll(sourceCode.getInstructions().getInstructions()); + // Update instructions for each instruction for (Instruction i : newCode.getInstructions()) - { i.setInstructions(newCode.getInstructions()); - } + newCode.getExceptions().getExceptions().addAll(sourceCode.getExceptions().getExceptions()); for (net.runelite.asm.attributes.code.Exception e : newCode.getExceptions().getExceptions()) - { e.setExceptions(newCode.getExceptions()); - } + targetMethod.setCode(newCode); } @@ -587,10 +556,9 @@ public class MixinInjector extends AbstractInjector else if (i instanceof PushConstantInstruction) { PushConstantInstruction pi = (PushConstantInstruction) i; + if (mixinCf.getPoolClass().equals(pi.getConstant())) - { pi.setConstant(cf.getPoolClass()); - } } verify(mixinCf, i); @@ -606,15 +574,11 @@ public class MixinInjector extends AbstractInjector if (fi.getField().getClazz().getName().equals(mixinCf.getName())) { if (i instanceof PutField || i instanceof GetField) - { throw new Injexception("Access to non static member field of mixin"); - } Field field = fi.getMyField(); if (field != null && !field.isPublic()) - { throw new Injexception("Static access to non public field " + field); - } } } else if (i instanceof InvokeStatic) @@ -623,16 +587,12 @@ public class MixinInjector extends AbstractInjector if (is.getMethod().getClazz() != mixinCf.getPoolClass() && is.getMethod().getClazz().getName().startsWith(MIXIN_BASE)) - { throw new Injexception("Invoking static methods of other mixins is not supported"); - } } else if (i instanceof InvokeDynamic) - { // RS classes don't verify under java 7+ due to the // super() invokespecial being inside of a try{} throw new Injexception("Injected bytecode must be Java 6 compatible"); - } } private Method findDeobMatching(ClassFile deobClass, Method mixinMethod, String deobName) throws Injexception @@ -642,26 +602,18 @@ public class MixinInjector extends AbstractInjector for (Method method : deobClass.getMethods()) { if (!deobName.equals(method.getName())) - { continue; - } if (InjectUtil.apiToDeobSigEquals(inject, method.getDescriptor(), mixinMethod.getDescriptor())) - { matching.add(method); - } } if (matching.size() > 1) - { // this happens when it has found several deob methods for some mixin method, // to get rid of the error, refine your search by making your mixin method have more parameters throw new Injexception("There are several matching methods when there should only be one"); - } else if (matching.size() == 1) - { return matching.get(0); - } return inject.getDeobfuscated().findStaticMethod(deobName); } diff --git a/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java b/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java index a9eb8d2..5f3acbb 100644 --- a/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java +++ b/src/main/java/com/openosrs/injector/injectors/RSApiInjector.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; +import net.runelite.asm.Annotated; import net.runelite.asm.ClassFile; import net.runelite.asm.Field; import net.runelite.asm.Method; @@ -51,30 +52,10 @@ public class RSApiInjector extends AbstractInjector { for (Field deobField : deobClass.getFields()) { - final String exportedName = InjectUtil.getExportedName(deobField); - if (exportedName == null) - { + final List matching = findImportsFor(deobField, deobField.isStatic(), implementingClass); + + if (matching == null) continue; - } - - final List matching = new ArrayList<>(); - - if (deobField.isStatic()) - { - for (RSApiClass api : inject.getRsApi()) - { - api.fetchImported(matching, exportedName); - } - } - else if (implementingClass != null) - { - implementingClass.fetchImported(matching, exportedName); - } - - if (matching.size() == 0) - { - continue; - } final Type deobType = deobField.getType(); @@ -129,38 +110,9 @@ public class RSApiInjector extends AbstractInjector final Number getter = DeobAnnotations.getObfuscatedGetter(deobField); if (deobField.isStatic() != vanillaField.isStatic()) // Can this even happen - { throw new Injexception("Something went horribly wrong, and this should honestly never happen, but you never know. Btw it's the static-ness"); - } - for (RSApiMethod apiMethod : matching) - { - final ClassFile targetClass = InjectUtil.fromApiMethod(inject, apiMethod); - apiMethod.setInjected(true); - - if (apiMethod.getSignature().isVoid()) - { - ++set; - log.debug("Injecting setter {} for {} into {}", apiMethod.getMethod(), vanillaField.getPoolField(), targetClass.getPoolClass()); - InjectSetter.inject( - targetClass, - apiMethod, - vanillaField, - modInverseOrNull(getter) - ); - } - else - { - ++get; - log.debug("Injecting getter {} for {} into {}", apiMethod.getMethod(), vanillaField.getPoolField(), targetClass.getPoolClass()); - InjectGetter.inject( - targetClass, - apiMethod, - vanillaField, - getter - ); - } - } + inject(matching, deobField, vanillaField, getter); } } @@ -168,30 +120,10 @@ public class RSApiInjector extends AbstractInjector { for (Method deobMethod : deobClass.getMethods()) { - final String exportedName = InjectUtil.getExportedName(deobMethod); - if (exportedName == null) - { + final List matching = findImportsFor(deobMethod, deobMethod.isStatic(), implementingClass); + + if (matching == null) continue; - } - - final List matching = new ArrayList<>(); - - if (deobMethod.isStatic()) - { - for (RSApiClass api : inject.getRsApi()) - { - api.fetchImported(matching, exportedName); - } - } - else if (implementingClass != null) - { - implementingClass.fetchImported(matching, exportedName); - } - - if (matching.size() == 0) - { - continue; - } final Signature deobSig = deobMethod.getDescriptor(); @@ -221,9 +153,7 @@ public class RSApiInjector extends AbstractInjector apiMethod.setInjected(true); } else if (matching.size() != 0) - { throw new Injexception("Multiple api imports matching method " + deobMethod.getPoolMethod()); - } } } @@ -232,46 +162,71 @@ public class RSApiInjector extends AbstractInjector for (Map.Entry> entry : retryFields.entrySet()) { final List matched = entry.getValue(); - final Field field = entry.getKey(); + final Field deobField = entry.getKey(); matched.removeIf(RSApiMethod::isInjected); if (matched.size() > 2) + throw new Injexception("More than 2 imported api methods for field " + deobField.getPoolField()); + + final Field vanillaField = inject.toVanilla(deobField); + final Number getter = DeobAnnotations.getObfuscatedGetter(deobField); + + inject(matched, deobField, vanillaField, getter); + } + } + + private List findImportsFor(Annotated object, boolean statik, RSApiClass implemented) + { + final String exportedName = InjectUtil.getExportedName(object); + if (exportedName == null) + return null; + + final List matching = new ArrayList<>(); + + if (statik) + { + for (RSApiClass api : inject.getRsApi()) { - throw new Injexception("More than 2 imported api methods for field " + field.getPoolField()); + api.fetchImported(matching, exportedName); } + } + else if (implemented != null) + { + implemented.fetchImported(matching, exportedName); + } - final Field vanillaField = inject.toVanilla(field); - final Number getter = DeobAnnotations.getObfuscatedGetter(field); + return matching; + } - for (RSApiMethod apiMethod : matched) + private void inject(List matched, Field field, Field targetField, Number getter) throws Injexception + { + for (RSApiMethod apiMethod : matched) + { + final ClassFile targetClass = InjectUtil.fromApiMethod(inject, apiMethod); + apiMethod.setInjected(true); + + if (apiMethod.getSignature().isVoid()) { - final ClassFile targetClass = InjectUtil.fromApiMethod(inject, apiMethod); - - apiMethod.setInjected(true); - - if (apiMethod.getSignature().isVoid()) - { - ++set; - log.debug("Injecting setter {} for {} into {}", apiMethod.getMethod(), field.getPoolField(), targetClass.getPoolClass()); - InjectSetter.inject( - targetClass, - apiMethod, - vanillaField, - modInverseOrNull(getter) - ); - } - else - { - ++get; - log.debug("Injecting getter {} for {} into {}", apiMethod.getMethod(), field.getPoolField(), targetClass.getPoolClass()); - InjectGetter.inject( - targetClass, - apiMethod, - vanillaField, - getter - ); - } + ++set; + log.debug("Injecting setter {} for {} into {}", apiMethod.getMethod(), field.getPoolField(), targetClass.getPoolClass()); + InjectSetter.inject( + targetClass, + apiMethod, + targetField, + modInverseOrNull(getter) + ); + } + else + { + ++get; + log.debug("Injecting getter {} for {} into {}", apiMethod.getMethod(), field.getPoolField(), targetClass.getPoolClass()); + InjectGetter.inject( + targetClass, + apiMethod, + targetField, + getter + ); } } } @@ -279,9 +234,7 @@ public class RSApiInjector extends AbstractInjector private static Number modInverseOrNull(Number getter) { if (getter == null) - { return null; - } // inverse getter to get the setter return DMath.modInverse(getter); diff --git a/src/main/java/com/openosrs/injector/injectors/raw/DrawAfterWidgets.java b/src/main/java/com/openosrs/injector/injectors/raw/DrawAfterWidgets.java index 75b4794..7f79fc9 100644 --- a/src/main/java/com/openosrs/injector/injectors/raw/DrawAfterWidgets.java +++ b/src/main/java/com/openosrs/injector/injectors/raw/DrawAfterWidgets.java @@ -40,34 +40,34 @@ public class DrawAfterWidgets extends AbstractInjector * Revision 180 - client.gs(): * ______________________________________________________ - * @Export("drawLoggedIn") - * final void drawLoggedIn() { - * if(rootInterface != -1) { - * ClientPreferences.method1809(rootInterface); - * } + * @Export("drawLoggedIn") + * final void drawLoggedIn() { + * if(rootInterface != -1) { + * ClientPreferences.method1809(rootInterface); + * } - * int var1; - * for(var1 = 0; var1 < rootWidgetCount; ++var1) { - * if(__client_od[var1]) { - * __client_ot[var1] = true; - * } + * int var1; + * for(var1 = 0; var1 < rootWidgetCount; ++var1) { + * if(__client_od[var1]) { + * __client_ot[var1] = true; + * } - * __client_oq[var1] = __client_od[var1]; - * __client_od[var1] = false; - * } + * __client_oq[var1] = __client_od[var1]; + * __client_od[var1] = false; + * } - * __client_oo = cycle; - * __client_lq = -1; - * __client_ln = -1; - * UserComparator6.__fg_jh = null; - * if(rootInterface != -1) { - * rootWidgetCount = 0; - * Interpreter.method1977(rootInterface, 0, 0, SoundCache.canvasWidth, Huffman.canvasHeight, 0, 0, -1); - * } + * __client_oo = cycle; + * __client_lq = -1; + * __client_ln = -1; + * UserComparator6.__fg_jh = null; + * if(rootInterface != -1) { + * rootWidgetCount = 0; + * Interpreter.drawWidgets(rootInterface, 0, 0, SoundCache.canvasWidth, Huffman.canvasHeight, 0, 0, -1); + * } - * < -- here appearantly + * <-- here - * Rasterizer2D.Rasterizer2D_resetClip(); + * Rasterizer2D.Rasterizer2D_resetClip(); * ______________________________________________________ */ @@ -132,7 +132,7 @@ public class DrawAfterWidgets extends AbstractInjector { // If we get here, we're either in the wrong method // or Jagex has removed the "if (535573958 * kl != -1)" - log.debug("Could not find the label for jumping to the " + noClip + " call in " + m); + // log.debug("Could not find the label for jumping to the " + noClip + " call in " + m); continue; } diff --git a/src/main/java/com/openosrs/injector/injectors/raw/HidePlayerAttacks.java b/src/main/java/com/openosrs/injector/injectors/raw/HidePlayerAttacks.java index 6238c58..58bbbfb 100644 --- a/src/main/java/com/openosrs/injector/injectors/raw/HidePlayerAttacks.java +++ b/src/main/java/com/openosrs/injector/injectors/raw/HidePlayerAttacks.java @@ -35,8 +35,15 @@ public class HidePlayerAttacks extends AbstractInjector final Method addPlayerOptions = InjectUtil.findMethod(inject, "addPlayerToMenu"); final net.runelite.asm.pool.Method shouldHideAttackOptionFor = inject.getVanilla().findClass("client").findMethod("shouldHideAttackOptionFor").getPoolMethod(); - injectHideAttack(addPlayerOptions, shouldHideAttackOptionFor); - injectHideCast(addPlayerOptions, shouldHideAttackOptionFor); + try + { + injectHideAttack(addPlayerOptions, shouldHideAttackOptionFor); + injectHideCast(addPlayerOptions, shouldHideAttackOptionFor); + } + catch (Injexception | AssertionError e) + { + log.warn("HidePlayerAttacks failed, but as this doesn't mess up anything other than that functionality, we're carrying on", e); + } } private void injectHideAttack(Method addPlayerOptions, net.runelite.asm.pool.Method shouldHideAttackOptionFor) throws Injexception @@ -144,38 +151,69 @@ public class HidePlayerAttacks extends AbstractInjector // <--- Inject comparison here (duh) // // add option n such - + final Field flags = InjectUtil.findField(inject, "selectedSpellFlags", "Client").getPoolField(); Instructions ins = addPlayerOptions.getCode().getInstructions(); - log.info(String.valueOf(ins.getInstructions().size())); ListIterator iterator = ins.getInstructions().listIterator(); + boolean b1, b2, iAnd, getstatic; + b1 = b2 = iAnd = getstatic = false; while (iterator.hasNext()) { Instruction i = iterator.next(); - if (!(i instanceof BiPush) || (byte) ((BiPush) i).getConstant() != 8) + + if (i instanceof Label) + { + b1 = b2 = iAnd = getstatic = false; + continue; + } + + if ((i instanceof BiPush) && (byte) ((BiPush) i).getConstant() == 8) + { + if (!b1) + b1 = true; + else if (!b2) + b2 = true; + else throw new Injexception("3 bipushes? fucking mental, Hide spells failed btw"); + + continue; + } + + if (i instanceof IAnd) + { + iAnd = true; + continue; + } + + if (i instanceof GetStatic && ((GetStatic) i).getField().equals(flags)) + { + getstatic = true; + continue; + } + + + if (!(i instanceof JumpingInstruction)) + { + if (b1 && b2 && iAnd && getstatic) + { + throw new Injexception("@ me in discord if this shit is broken lol, hide spells failed btw"); + } + continue; + } + + if (!(b1 && b2 && iAnd && getstatic)) { continue; } - i = iterator.next(); - while (!(i instanceof BiPush) || (byte) ((BiPush) i).getConstant() != 8) + Label target; + if (i instanceof IfICmpNe) { - i = iterator.next(); + target = ((IfICmpNe) i).getJumps().get(0); } - - i = iterator.next(); - if (!(i instanceof IAnd)) + else { - throw new Injexception("Yikes I didn't expect this"); + throw new Injexception("@ me in discord if this shit is broken lol, hide spells failed btw"); } - i = iterator.next(); - if (!(i instanceof IfICmpNe)) - { - continue; - } - - Label target = ((IfICmpNe) i).getJumps().get(0); - // Load the player ALoad i1 = new ALoad(ins, 0); // Get the boolean diff --git a/src/main/java/com/openosrs/injector/injectors/raw/Occluder.java b/src/main/java/com/openosrs/injector/injectors/raw/Occluder.java index 9038b5c..e05b0a4 100644 --- a/src/main/java/com/openosrs/injector/injectors/raw/Occluder.java +++ b/src/main/java/com/openosrs/injector/injectors/raw/Occluder.java @@ -42,16 +42,12 @@ public class Occluder extends AbstractInjector Instruction i = it.next(); if (!(i instanceof BiPush)) - { continue; - } boolean shouldChange = (byte) ((BiPush) i).getConstant() == OLDVALUE; if (!shouldChange) - { continue; - } replaced++; @@ -61,8 +57,6 @@ public class Occluder extends AbstractInjector } if (replaced != 10) - { throw new Injexception("Only found " + replaced + " 25's to replace in occlude instead of expected 10"); - } } } diff --git a/src/main/java/com/openosrs/injector/injectors/raw/RenderDraw.java b/src/main/java/com/openosrs/injector/injectors/raw/RenderDraw.java index bdcaba5..b6510f5 100644 --- a/src/main/java/com/openosrs/injector/injectors/raw/RenderDraw.java +++ b/src/main/java/com/openosrs/injector/injectors/raw/RenderDraw.java @@ -1,11 +1,11 @@ package com.openosrs.injector.injectors.raw; +import com.openosrs.injector.InjectUtil; import com.openosrs.injector.Injexception; import com.openosrs.injector.injection.InjectData; import static com.openosrs.injector.injection.InjectData.HOOKS; import com.openosrs.injector.injectors.AbstractInjector; import java.util.ListIterator; -import net.runelite.asm.ClassGroup; import net.runelite.asm.Method; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.Instructions; @@ -37,16 +37,9 @@ public class RenderDraw extends AbstractInjector * This class replaces entity draw invocation instructions * with the renderDraw method on drawcallbacks */ - final ClassGroup deob = inject.getDeobfuscated(); - final net.runelite.asm.pool.Method draw = inject.toVanilla(deob - .findClass("Entity") - .findMethod("draw") - ).getPoolMethod(); + final net.runelite.asm.pool.Method draw = InjectUtil.findMethod(inject, "draw", "Entity", null, true, false).getPoolMethod(); - final Method drawTile = inject.toVanilla(deob - .findClass("Scene") - .findMethod("drawTile") - ); + final Method drawTile = InjectUtil.findMethod(inject, "drawTile", "Scene", null, true, false); Instructions ins = drawTile.getCode().getInstructions(); for (ListIterator iterator = ins.listIterator(); iterator.hasNext(); ) diff --git a/src/main/java/com/openosrs/injector/rsapi/RSApi.java b/src/main/java/com/openosrs/injector/rsapi/RSApi.java index ed0e6a7..1e90860 100644 --- a/src/main/java/com/openosrs/injector/rsapi/RSApi.java +++ b/src/main/java/com/openosrs/injector/rsapi/RSApi.java @@ -38,9 +38,7 @@ public class RSApi implements Iterable for (File file : classes) { if (!file.getName().startsWith("RS")) - { continue; - } try (InputStream is = new FileInputStream(file)) { @@ -65,14 +63,12 @@ public class RSApi implements Iterable } @VisibleForTesting - public void init() + private void init() { final ImmutableMap.Builder builder = ImmutableMap.builder(); for (RSApiClass clazz : this) - { builder.put(clazz.getName(), clazz); - } this.map = builder.build(); @@ -112,17 +108,11 @@ public class RSApi implements Iterable { RSApiClass clazz = findClass(interf.getName()); if (clazz != null) - { return clazz; - } for (RSApiClass apiC : this) - { if (apiC.getInterfaces().contains(interf)) - { return apiC; - } - } return null; } diff --git a/src/main/java/com/openosrs/injector/rsapi/RSApiClass.java b/src/main/java/com/openosrs/injector/rsapi/RSApiClass.java index 00fb66d..632e9b7 100644 --- a/src/main/java/com/openosrs/injector/rsapi/RSApiClass.java +++ b/src/main/java/com/openosrs/injector/rsapi/RSApiClass.java @@ -30,9 +30,7 @@ public class RSApiClass implements Iterable for (RSApiMethod method : this) { if (method.isSynthetic()) - { continue; - } final Annotations annotations = method.getAnnotations(); if (annotations.find(CONSTRUCT) != null) @@ -70,9 +68,7 @@ public class RSApiClass implements Iterable { List imported = imports.get(str); if (imported == null) - { return; - } to.addAll(imported); } diff --git a/src/main/java/com/openosrs/injector/rsapi/RSApiClassVisitor.java b/src/main/java/com/openosrs/injector/rsapi/RSApiClassVisitor.java index 9f626df..70cbffb 100644 --- a/src/main/java/com/openosrs/injector/rsapi/RSApiClassVisitor.java +++ b/src/main/java/com/openosrs/injector/rsapi/RSApiClassVisitor.java @@ -21,9 +21,7 @@ public class RSApiClassVisitor extends ClassVisitor apiClass.setClazz(new Class(name)); for (String s : interfaces) - { apiClass.getInterfaces().add(new Class(s)); - } } public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)