diff --git a/src/main/kotlin/net/revanced/patcher/patch/Patch.kt b/src/main/kotlin/net/revanced/patcher/patch/Patch.kt index 0a53faf..37fe508 100644 --- a/src/main/kotlin/net/revanced/patcher/patch/Patch.kt +++ b/src/main/kotlin/net/revanced/patcher/patch/Patch.kt @@ -1,9 +1,5 @@ package net.revanced.patcher.patch -class Patch(val patchName: String, val fn: () -> PatchResult) { - fun execute(): PatchResult { - return fn() - } +abstract class Patch(val patchName: String) { + abstract fun execute(): PatchResult } - - diff --git a/src/test/kotlin/net/revanced/patcher/PatcherTest.kt b/src/test/kotlin/net/revanced/patcher/PatcherTest.kt index 7057b90..eeedcb6 100644 --- a/src/test/kotlin/net/revanced/patcher/PatcherTest.kt +++ b/src/test/kotlin/net/revanced/patcher/PatcherTest.kt @@ -1,6 +1,7 @@ package net.revanced.patcher import net.revanced.patcher.patch.Patch +import net.revanced.patcher.patch.PatchResult import net.revanced.patcher.patch.PatchResultSuccess import net.revanced.patcher.signature.Signature import net.revanced.patcher.util.ExtraTypes @@ -46,62 +47,64 @@ internal class PatcherTest { val patcher = Patcher(testData, testSigs) patcher.addPatches( - Patch ("TestPatch") { - // Get the method from the resolver cache - val mainMethod = patcher.cache.methods["mainMethod"] - // Get the instruction list - val instructions = mainMethod.method.instructions!! + object : Patch("TestPatch") { + override fun execute(): PatchResult { + // Get the method from the resolver cache + val mainMethod = patcher.cache.methods["mainMethod"] + // Get the instruction list + val instructions = mainMethod.method.instructions!! - // Let's modify it, so it prints "Hello, ReVanced! Editing bytecode." - // Get the start index of our opcode pattern. - // This will be the index of the LDC instruction. - val startIndex = mainMethod.scanData.startIndex - TestUtil.assertNodeEqual(LdcInsnNode("Hello, world!"), instructions[startIndex]!!) - // Create a new LDC node and replace the LDC instruction. - val stringNode = LdcInsnNode("Hello, ReVanced! Editing bytecode.") - instructions.setAt(startIndex, stringNode) + // Let's modify it, so it prints "Hello, ReVanced! Editing bytecode." + // Get the start index of our opcode pattern. + // This will be the index of the LDC instruction. + val startIndex = mainMethod.scanData.startIndex + TestUtil.assertNodeEqual(LdcInsnNode("Hello, world!"), instructions[startIndex]!!) + // Create a new LDC node and replace the LDC instruction. + val stringNode = LdcInsnNode("Hello, ReVanced! Editing bytecode.") + instructions.setAt(startIndex, stringNode) - // Now lets print our string twice! - // Insert our instructions after the second instruction by our pattern. - // This will place our instructions after the original INVOKEVIRTUAL call. - // You could also copy the instructions from the list and then modify the LDC instruction again, - // but this is to show a more advanced example of writing bytecode using the patcher and ASM. - instructions.insertAt( - startIndex + 1, - FieldInsnNode( - GETSTATIC, - Type.getInternalName(System::class.java), // "java/io/System" - "out", - Type.getInternalName(PrintStream::class.java) // "java.io.PrintStream" - ), - LdcInsnNode("Hello, ReVanced! Adding bytecode."), - MethodInsnNode( - INVOKEVIRTUAL, - Type.getInternalName(PrintStream::class.java), // "java/io/PrintStream" - "println", - Type.getMethodDescriptor( - Type.VOID_TYPE, - Type.getType(String::class.java) - ) // "(Ljava/lang/String;)V" + // Now lets print our string twice! + // Insert our instructions after the second instruction by our pattern. + // This will place our instructions after the original INVOKEVIRTUAL call. + // You could also copy the instructions from the list and then modify the LDC instruction again, + // but this is to show a more advanced example of writing bytecode using the patcher and ASM. + instructions.insertAt( + startIndex + 1, + FieldInsnNode( + GETSTATIC, + Type.getInternalName(System::class.java), // "java/io/System" + "out", + Type.getInternalName(PrintStream::class.java) // "java.io.PrintStream" + ), + LdcInsnNode("Hello, ReVanced! Adding bytecode."), + MethodInsnNode( + INVOKEVIRTUAL, + Type.getInternalName(PrintStream::class.java), // "java/io/PrintStream" + "println", + Type.getMethodDescriptor( + Type.VOID_TYPE, + Type.getType(String::class.java) + ) // "(Ljava/lang/String;)V" + ) ) - ) - // Our code now looks like this: - // public static main(java.lang.String[] arg0) { // Method signature: ([Ljava/lang/String;)V - // getstatic java/lang/System.out:java.io.PrintStream - // ldc "Hello, ReVanced! Editing bytecode." (java.lang.String) // We overwrote this instruction. - // invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V - // getstatic java/lang/System.out:java.io.PrintStream // This instruction and the 2 instructions below are written manually. - // ldc "Hello, ReVanced! Adding bytecode." (java.lang.String) - // invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V - // return - // } + // Our code now looks like this: + // public static main(java.lang.String[] arg0) { // Method signature: ([Ljava/lang/String;)V + // getstatic java/lang/System.out:java.io.PrintStream + // ldc "Hello, ReVanced! Editing bytecode." (java.lang.String) // We overwrote this instruction. + // invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V + // getstatic java/lang/System.out:java.io.PrintStream // This instruction and the 2 instructions below are written manually. + // ldc "Hello, ReVanced! Adding bytecode." (java.lang.String) + // invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V + // return + // } - // Finally, tell the patcher that this patch was a success. - // You can also return PatchResultError with a message. - // If an exception is thrown inside this function, - // a PatchResultError will be returned with the error message. - PatchResultSuccess() + // Finally, tell the patcher that this patch was a success. + // You can also return PatchResultError with a message. + // If an exception is thrown inside this function, + // a PatchResultError will be returned with the error message. + return PatchResultSuccess() + } } )