mirror of
https://github.com/revanced/revanced-patcher.git
synced 2025-04-30 21:34:25 +02:00
refactor: convert Patch to abstract class
BREAKING CHANGE: Patch class is now an abstract class. You must implement it. You can use anonymous implements, like done in the tests.
This commit is contained in:
parent
428f7f4dec
commit
cb9b1b9416
@ -1,9 +1,5 @@
|
|||||||
package net.revanced.patcher.patch
|
package net.revanced.patcher.patch
|
||||||
|
|
||||||
class Patch(val patchName: String, val fn: () -> PatchResult) {
|
abstract class Patch(val patchName: String) {
|
||||||
fun execute(): PatchResult {
|
abstract fun execute(): PatchResult
|
||||||
return fn()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.revanced.patcher
|
package net.revanced.patcher
|
||||||
|
|
||||||
import net.revanced.patcher.patch.Patch
|
import net.revanced.patcher.patch.Patch
|
||||||
|
import net.revanced.patcher.patch.PatchResult
|
||||||
import net.revanced.patcher.patch.PatchResultSuccess
|
import net.revanced.patcher.patch.PatchResultSuccess
|
||||||
import net.revanced.patcher.signature.Signature
|
import net.revanced.patcher.signature.Signature
|
||||||
import net.revanced.patcher.util.ExtraTypes
|
import net.revanced.patcher.util.ExtraTypes
|
||||||
@ -46,62 +47,64 @@ internal class PatcherTest {
|
|||||||
val patcher = Patcher(testData, testSigs)
|
val patcher = Patcher(testData, testSigs)
|
||||||
|
|
||||||
patcher.addPatches(
|
patcher.addPatches(
|
||||||
Patch ("TestPatch") {
|
object : Patch("TestPatch") {
|
||||||
// Get the method from the resolver cache
|
override fun execute(): PatchResult {
|
||||||
val mainMethod = patcher.cache.methods["mainMethod"]
|
// Get the method from the resolver cache
|
||||||
// Get the instruction list
|
val mainMethod = patcher.cache.methods["mainMethod"]
|
||||||
val instructions = mainMethod.method.instructions!!
|
// Get the instruction list
|
||||||
|
val instructions = mainMethod.method.instructions!!
|
||||||
|
|
||||||
// Let's modify it, so it prints "Hello, ReVanced! Editing bytecode."
|
// Let's modify it, so it prints "Hello, ReVanced! Editing bytecode."
|
||||||
// Get the start index of our opcode pattern.
|
// Get the start index of our opcode pattern.
|
||||||
// This will be the index of the LDC instruction.
|
// This will be the index of the LDC instruction.
|
||||||
val startIndex = mainMethod.scanData.startIndex
|
val startIndex = mainMethod.scanData.startIndex
|
||||||
TestUtil.assertNodeEqual(LdcInsnNode("Hello, world!"), instructions[startIndex]!!)
|
TestUtil.assertNodeEqual(LdcInsnNode("Hello, world!"), instructions[startIndex]!!)
|
||||||
// Create a new LDC node and replace the LDC instruction.
|
// Create a new LDC node and replace the LDC instruction.
|
||||||
val stringNode = LdcInsnNode("Hello, ReVanced! Editing bytecode.")
|
val stringNode = LdcInsnNode("Hello, ReVanced! Editing bytecode.")
|
||||||
instructions.setAt(startIndex, stringNode)
|
instructions.setAt(startIndex, stringNode)
|
||||||
|
|
||||||
// Now lets print our string twice!
|
// Now lets print our string twice!
|
||||||
// Insert our instructions after the second instruction by our pattern.
|
// Insert our instructions after the second instruction by our pattern.
|
||||||
// This will place our instructions after the original INVOKEVIRTUAL call.
|
// 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,
|
// 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.
|
// but this is to show a more advanced example of writing bytecode using the patcher and ASM.
|
||||||
instructions.insertAt(
|
instructions.insertAt(
|
||||||
startIndex + 1,
|
startIndex + 1,
|
||||||
FieldInsnNode(
|
FieldInsnNode(
|
||||||
GETSTATIC,
|
GETSTATIC,
|
||||||
Type.getInternalName(System::class.java), // "java/io/System"
|
Type.getInternalName(System::class.java), // "java/io/System"
|
||||||
"out",
|
"out",
|
||||||
Type.getInternalName(PrintStream::class.java) // "java.io.PrintStream"
|
Type.getInternalName(PrintStream::class.java) // "java.io.PrintStream"
|
||||||
),
|
),
|
||||||
LdcInsnNode("Hello, ReVanced! Adding bytecode."),
|
LdcInsnNode("Hello, ReVanced! Adding bytecode."),
|
||||||
MethodInsnNode(
|
MethodInsnNode(
|
||||||
INVOKEVIRTUAL,
|
INVOKEVIRTUAL,
|
||||||
Type.getInternalName(PrintStream::class.java), // "java/io/PrintStream"
|
Type.getInternalName(PrintStream::class.java), // "java/io/PrintStream"
|
||||||
"println",
|
"println",
|
||||||
Type.getMethodDescriptor(
|
Type.getMethodDescriptor(
|
||||||
Type.VOID_TYPE,
|
Type.VOID_TYPE,
|
||||||
Type.getType(String::class.java)
|
Type.getType(String::class.java)
|
||||||
) // "(Ljava/lang/String;)V"
|
) // "(Ljava/lang/String;)V"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
// Our code now looks like this:
|
// Our code now looks like this:
|
||||||
// public static main(java.lang.String[] arg0) { // Method signature: ([Ljava/lang/String;)V
|
// public static main(java.lang.String[] arg0) { // Method signature: ([Ljava/lang/String;)V
|
||||||
// getstatic java/lang/System.out:java.io.PrintStream
|
// getstatic java/lang/System.out:java.io.PrintStream
|
||||||
// ldc "Hello, ReVanced! Editing bytecode." (java.lang.String) // We overwrote this instruction.
|
// ldc "Hello, ReVanced! Editing bytecode." (java.lang.String) // We overwrote this instruction.
|
||||||
// invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V
|
// 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.
|
// 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)
|
// ldc "Hello, ReVanced! Adding bytecode." (java.lang.String)
|
||||||
// invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V
|
// invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Finally, tell the patcher that this patch was a success.
|
// Finally, tell the patcher that this patch was a success.
|
||||||
// You can also return PatchResultError with a message.
|
// You can also return PatchResultError with a message.
|
||||||
// If an exception is thrown inside this function,
|
// If an exception is thrown inside this function,
|
||||||
// a PatchResultError will be returned with the error message.
|
// a PatchResultError will be returned with the error message.
|
||||||
PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user