@Test public void testInject() throws Exception { InputStream deobIn = getClass().getResourceAsStream("DeobTarget.class"); ClassFile deobTarget = ClassUtil.loadClass(deobIn); ClassGroup deob = new ClassGroup(); deob.addClass(deobTarget); InputStream vanillaIn = getClass().getResourceAsStream("VanillaTarget.class"); ClassFile vanillaTarget = ClassUtil.loadClass(vanillaIn); ClassGroup vanilla = new ClassGroup(); vanilla.addClass(vanillaTarget); Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>(); mixinClasses.put(Source.class, Collections.singletonList(vanillaTarget)); mixinClasses.put(Source2.class, Collections.singletonList(vanillaTarget)); Inject inject = new Inject(deob, vanilla); new MixinInjector(inject).inject(mixinClasses); Field foo = vanillaTarget.findField("foo"); assertNotNull(foo); assertEquals(INT, foo.getType()); assertEquals(ACC_PUBLIC | ACC_STATIC, foo.getAccessFlags()); Method foo2 = vanillaTarget.findMethod("foo2"); assertNotNull(foo2); assertEquals(new Signature("()V"), foo2.getDescriptor()); assertEquals(ACC_PUBLIC, foo2.getAccessFlags()); Method foo3 = vanillaTarget.findMethod("copy$foo3"); assertNotNull(foo3); assertEquals(new Signature("(I)V"), foo3.getDescriptor()); assertEquals(ACC_PUBLIC, foo3.getAccessFlags()); Method ob_foo3 = vanillaTarget.findMethod("ob_foo3"); assertNotNull(ob_foo3); assertEquals(new Signature("(I)V"), ob_foo3.getDescriptor()); assertEquals(ob_foo3 .getCode() .getInstructions() .getInstructions() .stream() .filter(i -> i instanceof LDC && ((LDC) i).getConstant().equals("replaced")) .count(), 1); assertEquals(ob_foo3 .getCode() .getInstructions() .getInstructions() .stream() .filter(i -> { if (!(i instanceof GetStatic)) { return false; } net.runelite.asm.pool.Field field = ((GetStatic) i).getField(); if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) { return false; } if (!field.getName().equals("ob_foo4")) { return false; } return true; }) .count(), 1); assertEquals(ob_foo3 .getCode() .getInstructions() .getInstructions() .stream() .filter(i -> { if (!(i instanceof InvokeVirtual)) { return false; } net.runelite.asm.pool.Method method = ((InvokeVirtual) i).getMethod(); if (!method.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) { return false; } if (!method.getName().equals("copy$foo3")) { return false; } return true; }) .count(), 1); Method foo5 = vanillaTarget.findMethod("foo5"); assertNotNull(foo5); assertEquals(new Signature("()V"), foo5.getDescriptor()); assertEquals(ACC_PUBLIC, foo5.getAccessFlags()); assertEquals(foo5 .getCode() .getInstructions() .getInstructions() .stream() .filter(i -> { if (!(i instanceof GetStatic)) { return false; } net.runelite.asm.pool.Field field = ((GetStatic) i).getField(); if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget")) { return false; } if (!field.getName().equals("foo")) { return false; } return true; }) .count(), 1); }
public void inject() throws InjectionException { ClassPath classPath; try { classPath = ClassPath.from(this.getClass().getClassLoader()); } catch (IOException ex) { throw new InjectionException(ex); } Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>(); for (ClassInfo classInfo : classPath.getTopLevelClasses(MIXIN_BASE)) { Class<?> mixinClass = classInfo.load(); List<ClassFile> mixinTargets = new ArrayList<>(); for (Mixin mixin : mixinClass.getAnnotationsByType(Mixin.class)) { Class<?> implementInto = mixin.value(); ClassFile targetCf = inject.findVanillaForInterface(implementInto); if (targetCf == null) { throw new InjectionException("No class implements " + implementInto + " for mixin " + mixinClass); } mixinTargets.add(targetCf); } mixinClasses.put(mixinClass, mixinTargets); } inject(mixinClasses); }
MixinInjector { public void inject() throws InjectionException { ClassPath classPath; try { classPath = ClassPath.from(this.getClass().getClassLoader()); } catch (IOException ex) { throw new InjectionException(ex); } Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>(); for (ClassInfo classInfo : classPath.getTopLevelClasses(MIXIN_BASE)) { Class<?> mixinClass = classInfo.load(); List<ClassFile> mixinTargets = new ArrayList<>(); for (Mixin mixin : mixinClass.getAnnotationsByType(Mixin.class)) { Class<?> implementInto = mixin.value(); ClassFile targetCf = inject.findVanillaForInterface(implementInto); if (targetCf == null) { throw new InjectionException("No class implements " + implementInto + " for mixin " + mixinClass); } mixinTargets.add(targetCf); } mixinClasses.put(mixinClass, mixinTargets); } inject(mixinClasses); } }
MixinInjector { public void inject() throws InjectionException { ClassPath classPath; try { classPath = ClassPath.from(this.getClass().getClassLoader()); } catch (IOException ex) { throw new InjectionException(ex); } Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>(); for (ClassInfo classInfo : classPath.getTopLevelClasses(MIXIN_BASE)) { Class<?> mixinClass = classInfo.load(); List<ClassFile> mixinTargets = new ArrayList<>(); for (Mixin mixin : mixinClass.getAnnotationsByType(Mixin.class)) { Class<?> implementInto = mixin.value(); ClassFile targetCf = inject.findVanillaForInterface(implementInto); if (targetCf == null) { throw new InjectionException("No class implements " + implementInto + " for mixin " + mixinClass); } mixinTargets.add(targetCf); } mixinClasses.put(mixinClass, mixinTargets); } inject(mixinClasses); } MixinInjector(Inject inject); }
MixinInjector { public void inject() throws InjectionException { ClassPath classPath; try { classPath = ClassPath.from(this.getClass().getClassLoader()); } catch (IOException ex) { throw new InjectionException(ex); } Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>(); for (ClassInfo classInfo : classPath.getTopLevelClasses(MIXIN_BASE)) { Class<?> mixinClass = classInfo.load(); List<ClassFile> mixinTargets = new ArrayList<>(); for (Mixin mixin : mixinClass.getAnnotationsByType(Mixin.class)) { Class<?> implementInto = mixin.value(); ClassFile targetCf = inject.findVanillaForInterface(implementInto); if (targetCf == null) { throw new InjectionException("No class implements " + implementInto + " for mixin " + mixinClass); } mixinTargets.add(targetCf); } mixinClasses.put(mixinClass, mixinTargets); } inject(mixinClasses); } MixinInjector(Inject inject); void inject(); void inject(Map<Class<?>, List<ClassFile>> mixinClasses); }
MixinInjector { public void inject() throws InjectionException { ClassPath classPath; try { classPath = ClassPath.from(this.getClass().getClassLoader()); } catch (IOException ex) { throw new InjectionException(ex); } Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>(); for (ClassInfo classInfo : classPath.getTopLevelClasses(MIXIN_BASE)) { Class<?> mixinClass = classInfo.load(); List<ClassFile> mixinTargets = new ArrayList<>(); for (Mixin mixin : mixinClass.getAnnotationsByType(Mixin.class)) { Class<?> implementInto = mixin.value(); ClassFile targetCf = inject.findVanillaForInterface(implementInto); if (targetCf == null) { throw new InjectionException("No class implements " + implementInto + " for mixin " + mixinClass); } mixinTargets.add(targetCf); } mixinClasses.put(mixinClass, mixinTargets); } inject(mixinClasses); } MixinInjector(Inject inject); void inject(); void inject(Map<Class<?>, List<ClassFile>> mixinClasses);  }