diff --git a/injector/injector.gradle.kts b/injector/injector.gradle.kts index 66484a6950..4683c894e3 100644 --- a/injector/injector.gradle.kts +++ b/injector/injector.gradle.kts @@ -14,8 +14,10 @@ dependencies { vanillaDep(group = "net.runelite.rs", name = "vanilla", version = rsversion.toString()) annotationProcessor(group = "org.projectlombok", name = "lombok", version = ProjectVersions.lombokVersion) + testAnnotationProcessor(group = "org.projectlombok", name = "lombok", version = ProjectVersions.lombokVersion) compileOnly(group = "org.projectlombok", name = "lombok", version = ProjectVersions.lombokVersion) + testCompileOnly(group = "org.projectlombok", name = "lombok", version = ProjectVersions.lombokVersion) implementation(gradleApi()) @@ -29,6 +31,8 @@ dependencies { implementation(group = "org.jetbrains", name = "annotations", version = "22.0.0") implementation(group = "com.google.guava", name = "guava", version = "30.1.1-jre") implementation(group = "net.sf.jopt-simple", name = "jopt-simple", version = "5.0.4") + + testImplementation(group = "junit", name = "junit", version = "4.12") } tasks.register("inject") { diff --git a/injector/src/main/java/com/openosrs/injector/injection/InjectData.java b/injector/src/main/java/com/openosrs/injector/injection/InjectData.java index ea1af6a0a4..8bccb1e5f9 100644 --- a/injector/src/main/java/com/openosrs/injector/injection/InjectData.java +++ b/injector/src/main/java/com/openosrs/injector/injection/InjectData.java @@ -13,7 +13,9 @@ import com.openosrs.injector.rsapi.RSApi; import java.util.HashMap; import java.util.Map; import java.util.function.BiConsumer; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; @@ -24,6 +26,8 @@ import net.runelite.asm.signature.Signature; /** * Abstract class meant as the interface of {@link com.openosrs.injector.Injector injection} for injectors */ +@AllArgsConstructor +@NoArgsConstructor public abstract class InjectData { public static final String HOOKS = "net/runelite/client/callback/Hooks"; diff --git a/injector/src/test/java/com/openosrs/injector/TestInjection.java b/injector/src/test/java/com/openosrs/injector/TestInjection.java new file mode 100644 index 0000000000..14631cb59d --- /dev/null +++ b/injector/src/test/java/com/openosrs/injector/TestInjection.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019, Lucas + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this source tree. + */ +package com.openosrs.injector; + +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.Injector; +import com.openosrs.injector.rsapi.RSApi; +import net.runelite.asm.ClassGroup; + +public class TestInjection extends InjectData +{ + public TestInjection(ClassGroup vanilla, ClassGroup deobfuscated, ClassGroup mixins, RSApi rsApi) + { + super(vanilla, deobfuscated, mixins, rsApi); + } + + @Override + public void runChildInjector(Injector injector) throws InjectException + { + injector.inject(); + } +} diff --git a/injector/src/test/java/com/openosrs/injector/injectors/MixinInjectorTest.java b/injector/src/test/java/com/openosrs/injector/injectors/MixinInjectorTest.java new file mode 100644 index 0000000000..538d426b31 --- /dev/null +++ b/injector/src/test/java/com/openosrs/injector/injectors/MixinInjectorTest.java @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.openosrs.injector.injectors; + +import com.google.common.io.ByteStreams; +import com.openosrs.injector.TestInjection; +import com.openosrs.injector.rsapi.RSApi; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import javax.inject.Provider; +import net.runelite.api.mixins.Copy; +import net.runelite.api.mixins.Replace; +import net.runelite.api.mixins.Shadow; +import net.runelite.asm.ClassFile; +import net.runelite.asm.ClassGroup; +import net.runelite.asm.Field; +import net.runelite.asm.Method; +import static net.runelite.asm.Type.INT; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.instructions.GetStatic; +import net.runelite.asm.attributes.code.instructions.IMul; +import net.runelite.asm.attributes.code.instructions.InvokeVirtual; +import net.runelite.asm.attributes.code.instructions.LDC; +import net.runelite.asm.signature.Signature; +import net.runelite.asm.visitors.ClassFileVisitor; +import net.runelite.deob.util.JarUtil; +import net.runelite.mapping.ObfuscatedGetter; +import net.runelite.mapping.ObfuscatedName; +import net.runelite.mapping.ObfuscatedSignature; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ACC_STATIC; + +@ObfuscatedName("com/openosrs/injector/injectors/VanillaTarget") +class DeobTarget +{ + @ObfuscatedName("ob_foo4") + @ObfuscatedGetter(intValue = 1157381415) + static int foo4; + + @ObfuscatedName("ob_foo3") + @ObfuscatedSignature( + descriptor = "(I)V", + garbageValue = "123" + ) + private void foo3() + { + // De-obfuscated foo3 + System.out.println("foo3"); + } +} + +class VanillaTarget +{ + static int ob_foo4; + + private void ob_foo3(int garbageValue) + { + // Obfuscated foo3 + if (garbageValue != 123) + { + return; + } + System.out.println("foo3"); + } +} + +abstract class Source +{ + @net.runelite.api.mixins.Inject + private static int foo; + @Shadow("foo4") + private static int foo4; + + @net.runelite.api.mixins.Inject + private void foo2() + { + } + + @Copy("foo3") + @Replace("foo3") + private void copy$foo3() + { + System.out.println("replaced"); + System.out.println(foo4); + copy$foo3(); + } +} + +// Test shadowing the "foo" field injected by Source +abstract class Source2 +{ + @Shadow("foo") + private static int foo; + + @net.runelite.api.mixins.Inject + private void foo5() + { + System.out.println(foo); + } +} + +public class MixinInjectorTest +{ + @Test + public void testInject() throws Exception + { + InputStream deobIn = getClass().getResourceAsStream("DeobTarget.class"); + ClassFile deobTarget = JarUtil.loadClass(ByteStreams.toByteArray(deobIn)); + + ClassGroup deob = new ClassGroup(); + deob.addClass(deobTarget); + + InputStream vanillaIn = getClass().getResourceAsStream("VanillaTarget.class"); + ClassFile vanillaTarget = JarUtil.loadClass(ByteStreams.toByteArray(vanillaIn)); + + ClassGroup vanilla = new ClassGroup(); + vanilla.addClass(vanillaTarget); + + Map, List> mixinClasses = new HashMap<>(); + mixinClasses.put(() -> loadClass(Source.class), Collections.singletonList(vanillaTarget)); + mixinClasses.put(() -> loadClass(Source2.class), Collections.singletonList(vanillaTarget)); + + TestInjection inject = new TestInjection(vanilla, deob, new ClassGroup(), new RSApi()); + inject.initToVanilla(); + new MixinInjector(inject).inject(mixinClasses); + + // Check if "foo" has been injected + Field foo = vanillaTarget.findField("foo"); + assertNotNull(foo); + assertEquals(INT, foo.getType()); + assertEquals(ACC_PUBLIC | ACC_STATIC, foo.getAccessFlags()); + + // Check if "foo2()V" has been injected + Method foo2 = vanillaTarget.findMethod("foo2"); + assertNotNull(foo2); + assertEquals(new Signature("()V"), foo2.getDescriptor()); + assertEquals(ACC_PUBLIC, foo2.getAccessFlags()); + + // Check if "ob_foo3(I)V" was copied + Method foo3 = vanillaTarget.findMethod("copy$foo3"); + assertNotNull(foo3); + assertEquals(new Signature("(I)V"), foo3.getDescriptor()); + assertEquals(ACC_PUBLIC, foo3.getAccessFlags()); + + // Check if "ob_foo3(I)V" was replaced + 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); + // Check that the "foo4" field access in the new code body was mapped correctly + 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("com/openosrs/injector/injectors/VanillaTarget")) + { + return false; + } + + if (!field.getName().equals("ob_foo4")) + { + return false; + } + + return true; + }) + .count(), 1); + + assert getStaticHasGetter(ob_foo3, "ob_foo4"); + // Check that the "foo3()" call in the new code body was mapped to the copy + 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("com/openosrs/injector/injectors/VanillaTarget")) + { + return false; + } + + if (!method.getName().equals("copy$foo3")) + { + return false; + } + + return true; + }) + .count(), 1); + + // Check if "foo5()V" was injected + Method foo5 = vanillaTarget.findMethod("foo5"); + assertNotNull(foo5); + assertEquals(new Signature("()V"), foo5.getDescriptor()); + assertEquals(ACC_PUBLIC, foo5.getAccessFlags()); + // Check that the shadow "foo" field access was mapped correctly + 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("com/openosrs/injector/injectors/VanillaTarget")) + { + return false; + } + + if (!field.getName().equals("foo")) + { + return false; + } + + return true; + }) + .count(), 1); + } + + private boolean getStaticHasGetter(Method ob_foo3, String gottenField) + { + ListIterator it = ob_foo3.getCode().getInstructions().listIterator(); + Instruction i; + while (it.hasNext() && + !((i = it.next()) instanceof GetStatic && + ((GetStatic) i).getField().getName().equals(gottenField))); + + return + (i = it.next()) instanceof LDC && + ((LDC) i).getConstantAsInt() == 1157381415 && + it.next() instanceof IMul; + } + + private static ClassFile loadClass(Class clazz) + { + try (InputStream is = clazz.getClassLoader().getResourceAsStream(clazz.getName().replace('.', '/') + ".class")) + { + ClassReader reader = new ClassReader(is); + ClassFileVisitor cv = new ClassFileVisitor(); + + reader.accept(cv, 0); + + return cv.getClassFile(); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } +} diff --git a/injector/src/test/java/com/openosrs/injector/injectors/raw/DrawAfterWidgetsTest.java b/injector/src/test/java/com/openosrs/injector/injectors/raw/DrawAfterWidgetsTest.java new file mode 100644 index 0000000000..ec2abae403 --- /dev/null +++ b/injector/src/test/java/com/openosrs/injector/injectors/raw/DrawAfterWidgetsTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018, Lotto + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.openosrs.injector.injectors.raw; + +import com.google.common.io.ByteStreams; +import com.openosrs.injector.InjectUtil; +import com.openosrs.injector.TestInjection; +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.rsapi.RSApi; +import javax.swing.plaf.TabbedPaneUI; +import net.runelite.asm.Annotation; +import net.runelite.asm.ClassFile; +import net.runelite.asm.ClassGroup; +import net.runelite.asm.Field; +import net.runelite.asm.Named; +import net.runelite.asm.Type; +import net.runelite.asm.attributes.Annotated; +import net.runelite.deob.DeobAnnotations; +import net.runelite.deob.util.JarUtil; +import org.junit.Test; +import static net.runelite.deob.DeobAnnotations.OBFUSCATED_NAME; +import static net.runelite.deob.DeobAnnotations.OBFUSCATED_SIGNATURE; + +public class DrawAfterWidgetsTest +{ + @Test + public void testInjectDrawWidgetsRev160() throws Exception + { + // Rev 160 does not have the drawWidgets call inlined + + ClassFile deobClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_deob160.class"))); + ClassFile deobRasterizer = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_deob160.class"))); + + ClassGroup deob = new ClassGroup(); + deob.addClass(deobClient); + deob.addClass(deobRasterizer); + + ClassFile obClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_ob160.class"))); + ClassFile obRasterizer = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_ob160.class"))); + + ClassGroup vanilla = new ClassGroup(); + vanilla.addClass(obClient); + vanilla.addClass(obRasterizer); + + InjectData inject = new TestInjection(vanilla, deob, new ClassGroup(), new RSApi()); + addPhonyFields(deob, vanilla); + inject.initToVanilla(); + new DrawAfterWidgets(inject).inject(); + } + + @Test + public void testInjectDrawWidgetsRev180() throws Exception + { + // Rev 180 has the drawWidgets call inlined + + ClassFile deobClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_deob180.class"))); + ClassFile deobRasterizer = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_deob180.class"))); + + ClassGroup deob = new ClassGroup(); + deob.addClass(deobClient); + deob.addClass(deobRasterizer); + + ClassFile obClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_ob180.class"))); + ClassFile obRasterizer = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_ob180.class"))); + + ClassGroup vanilla = new ClassGroup(); + vanilla.addClass(obClient); + vanilla.addClass(obRasterizer); + + InjectData inject = new TestInjection(vanilla, deob, new ClassGroup(), new RSApi()); + addPhonyFields(deob, vanilla); + inject.initToVanilla(); + new DrawAfterWidgets(inject).inject(); + } + + private static void addPhonyFields(ClassGroup deob, ClassGroup vanilla) + { + final ClassFile d = deob.findClass("Client"); + final ClassFile v = vanilla.findClass("client"); + final Field clientD = new Field(d, "client", new Type("LClient;")); + clientD.findAnnotation(OBFUSCATED_NAME, true).setElement("obclient"); + clientD.findAnnotation(OBFUSCATED_SIGNATURE, true).setElement("descriptor", "Lclient;"); + clientD.setStatic(); + d.addField(clientD); + final Field clientV = new Field(v, "obclient", new Type("Lclient;")); + clientV.setStatic(); + v.addField(clientV); + final Field callbacks = new Field(v, "callbacks", new Type("LCallbacks;")); + v.addField(callbacks); + } +} diff --git a/injector/src/test/java/com/openosrs/injector/injectors/raw/DrawMenuTest.java b/injector/src/test/java/com/openosrs/injector/injectors/raw/DrawMenuTest.java new file mode 100644 index 0000000000..3f06b84c68 --- /dev/null +++ b/injector/src/test/java/com/openosrs/injector/injectors/raw/DrawMenuTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Lucas + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this source tree. + */ +package com.openosrs.injector.injectors.raw; + +import com.google.common.io.ByteStreams; +import com.openosrs.injector.TestInjection; +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.rsapi.RSApi; +import net.runelite.asm.ClassFile; +import net.runelite.asm.ClassGroup; +import net.runelite.deob.util.JarUtil; +import org.junit.Test; + +public class DrawMenuTest +{ + @Test + public void test160() throws Exception + { + // 160 has both drawMenu and drawTopLeftText inlined + ClassFile deobClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_deob160.class"))); + ClassFile obClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_ob160.class"))); + + ClassGroup van = new ClassGroup(); + van.addClass(obClient); + ClassGroup deob = new ClassGroup(); + deob.addClass(deobClient); + + InjectData inject = new TestInjection(van, deob, new ClassGroup(), new RSApi()); + inject.initToVanilla(); + new DrawMenu(inject).inject(); + } + + @Test + public void test180() throws Exception + { + // 180 has only drawMenu inlined + ClassFile deobClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_deob180.class"))); + ClassFile obClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_ob180.class"))); + + ClassGroup van = new ClassGroup(); + van.addClass(obClient); + ClassGroup deob = new ClassGroup(); + deob.addClass(deobClient); + + InjectData inject = new TestInjection(van, deob, new ClassGroup(), new RSApi()); + inject.initToVanilla(); + new DrawMenu(inject).inject(); + } +} diff --git a/injector/src/test/java/com/openosrs/injector/transformers/SourceChangerTest.java b/injector/src/test/java/com/openosrs/injector/transformers/SourceChangerTest.java new file mode 100644 index 0000000000..18a1fcc0aa --- /dev/null +++ b/injector/src/test/java/com/openosrs/injector/transformers/SourceChangerTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Lucas + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this source tree. + */ +package com.openosrs.injector.transformers; + +import com.openosrs.injector.InjectException; +import com.openosrs.injector.injection.InjectData; +import com.openosrs.injector.injectors.Injector; +import com.openosrs.injector.transformers.srcchangeclasses.NewName; +import com.openosrs.injector.transformers.srcchangeclasses.OldName; +import java.lang.invoke.MethodHandles; +import java.util.function.BiConsumer; +import net.runelite.asm.ClassFile; +import net.runelite.asm.ClassGroup; +import net.runelite.asm.objectwebasm.NonloadingClassWriter; +import net.runelite.asm.visitors.ClassFileVisitor; +import org.junit.Ignore; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; + +public class SourceChangerTest +{ + private static final String PACKAGE = "com.openosrs.injector.transformers.srcchangeclasses."; + + @Test + @Ignore // Ignored because it's not really testing anything atm, but it works! + public void test() throws Exception + { + final ClassFileVisitor deob = new ClassFileVisitor(), vann = new ClassFileVisitor(); + new ClassReader(PACKAGE + "NewName").accept(deob, ClassReader.SKIP_FRAMES); + new ClassReader(PACKAGE + "OldName").accept(vann, ClassReader.SKIP_FRAMES); + + new SourceChanger( + new InjectData(new ClassGroup(), new ClassGroup(), null, null) { + public void runChildInjector(Injector injector) throws InjectException + {} + + @Override + public void forEachPair(BiConsumer consumer) + { + consumer.accept(deob.getClassFile(), vann.getClassFile()); + } + }).transformImpl(); + + final ClassGroup group = new ClassGroup(); + group.addClass(vann.getClassFile()); + + final ClassWriter cw = new NonloadingClassWriter(group, 0); + vann.getClassFile().accept(cw); + + OldName obj = (OldName) MethodHandles.privateLookupIn( + NewName.class, + MethodHandles.lookup()) + .defineClass(cw.toByteArray()) + .getDeclaredConstructor() + .newInstance(); + + obj.obfMethodName(); + } +} diff --git a/injector/src/test/java/com/openosrs/injector/transformers/srcchangeclasses/NewName.java b/injector/src/test/java/com/openosrs/injector/transformers/srcchangeclasses/NewName.java new file mode 100644 index 0000000000..7578ed7812 --- /dev/null +++ b/injector/src/test/java/com/openosrs/injector/transformers/srcchangeclasses/NewName.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Lucas + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this source tree. + */ +package com.openosrs.injector.transformers.srcchangeclasses; + +public class NewName +{ + public void deobMethodName() + { + // do something interesting + } +} diff --git a/injector/src/test/java/com/openosrs/injector/transformers/srcchangeclasses/OldName.java b/injector/src/test/java/com/openosrs/injector/transformers/srcchangeclasses/OldName.java new file mode 100644 index 0000000000..b8adde516c --- /dev/null +++ b/injector/src/test/java/com/openosrs/injector/transformers/srcchangeclasses/OldName.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Lucas + * All rights reserved. + * + * This code is licensed under GPL3, see the complete license in + * the LICENSE file in the root directory of this source tree. + */ +package com.openosrs.injector.transformers.srcchangeclasses; + +public class OldName +{ + public void obfMethodName() + { + new RuntimeException().printStackTrace(); + } +} diff --git a/injector/src/test/resources/drawafterwidgets/Client_deob160.class b/injector/src/test/resources/drawafterwidgets/Client_deob160.class new file mode 100644 index 0000000000..f0248c3985 Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Client_deob160.class differ diff --git a/injector/src/test/resources/drawafterwidgets/Client_deob180.class b/injector/src/test/resources/drawafterwidgets/Client_deob180.class new file mode 100644 index 0000000000..a2fc0dfbee Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Client_deob180.class differ diff --git a/injector/src/test/resources/drawafterwidgets/Client_ob160.class b/injector/src/test/resources/drawafterwidgets/Client_ob160.class new file mode 100644 index 0000000000..2058173233 Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Client_ob160.class differ diff --git a/injector/src/test/resources/drawafterwidgets/Client_ob180.class b/injector/src/test/resources/drawafterwidgets/Client_ob180.class new file mode 100644 index 0000000000..913f307f74 Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Client_ob180.class differ diff --git a/injector/src/test/resources/drawafterwidgets/Rasterizer2D_deob160.class b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_deob160.class new file mode 100644 index 0000000000..5cfe67d121 Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_deob160.class differ diff --git a/injector/src/test/resources/drawafterwidgets/Rasterizer2D_deob180.class b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_deob180.class new file mode 100644 index 0000000000..0f2cbce685 Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_deob180.class differ diff --git a/injector/src/test/resources/drawafterwidgets/Rasterizer2D_ob160.class b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_ob160.class new file mode 100644 index 0000000000..b29703e7ce Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_ob160.class differ diff --git a/injector/src/test/resources/drawafterwidgets/Rasterizer2D_ob180.class b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_ob180.class new file mode 100644 index 0000000000..0ef73dbecc Binary files /dev/null and b/injector/src/test/resources/drawafterwidgets/Rasterizer2D_ob180.class differ