fix: breaking changes by revanced-patcher dependency

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
oSumAtrIX 2022-05-19 00:00:45 +02:00
parent f90205b243
commit 51d250491f
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
5 changed files with 73 additions and 48 deletions

View File

@ -25,11 +25,13 @@ repositories {
dependencies { dependencies {
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
implementation("app.revanced:revanced-patcher:+") implementation("app.revanced:revanced-patcher:+")
implementation("app.revanced:revanced-patches:+")
implementation("info.picocli:picocli:+") implementation("info.picocli:picocli:+")
implementation("me.tongfei:progressbar:+")
implementation("com.github.li-wjohnson:jadb:master-SNAPSHOT") // using a fork instead. implementation("com.github.li-wjohnson:jadb:master-SNAPSHOT") // using a fork instead.
implementation("org.bouncycastle:bcpkix-jdk15on:+") implementation("org.bouncycastle:bcpkix-jdk15on:+")
implementation(kotlin("reflect"))
} }
java { java {

View File

@ -1,6 +1,8 @@
package app.revanced.cli package app.revanced.cli
import app.revanced.patch.Patches import app.revanced.patch.Patches
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.extensions.findAnnotationRecursively
import app.revanced.utils.adb.Adb import app.revanced.utils.adb.Adb
import picocli.CommandLine.* import picocli.CommandLine.*
import java.io.File import java.io.File
@ -47,36 +49,36 @@ internal object MainCommand : Runnable {
override fun run() { override fun run() {
if (listOnly) { if (listOnly) {
patchBundles.forEach { for (patchBundle in patchBundles) for (it in Patches.load(patchBundle)) println(
Patches.load(it).forEach { "[available] ${
println(it().metadata) it.javaClass.findAnnotationRecursively(
} Name::class.java
} )?.name ?: Name::class.java.name
}"
)
return return
} }
val outputFile = File(outputPath)
val patcher = app.revanced.patcher.Patcher( val patcher = app.revanced.patcher.Patcher(
inputFile, inputFile, cacheDirectory, patchResources
cacheDirectory,
patchResources
) )
var adb: Adb? = null
deploy?.let {
adb = Adb(
outputFile, patcher.packageName, deploy!!
)
}
Patcher.start(patcher) Patcher.start(patcher)
if (clean) { if (clean) {
File(cacheDirectory).deleteRecursively() File(cacheDirectory).deleteRecursively()
outputFile.delete()
} }
val outputFile = File(outputPath) adb?.deploy()
deploy?.let {
Adb(
outputFile,
patcher.packageName,
deploy!!
).deploy()
}
if (clean) outputFile.delete()
} }
} }

View File

@ -1,7 +1,10 @@
package app.revanced.cli package app.revanced.cli
import app.revanced.patch.Patches import app.revanced.patch.Patches
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.base.Data import app.revanced.patcher.data.base.Data
import app.revanced.patcher.extensions.findAnnotationRecursively
import app.revanced.patcher.patch.base.Patch import app.revanced.patcher.patch.base.Patch
import app.revanced.utils.filesystem.FileSystemUtils import app.revanced.utils.filesystem.FileSystemUtils
import app.revanced.utils.signing.Signer import app.revanced.utils.signing.Signer
@ -15,10 +18,8 @@ internal class Patcher {
// add patches, but filter incompatible or excluded patches // add patches, but filter incompatible or excluded patches
patcher.addPatchesFiltered() patcher.addPatchesFiltered()
// apply patches // apply patches
for ((meta, result) in patcher.applyPatches { for ((patch, result) in patcher.applyPatches()) {
println("Applying $it.") println("[error: ${result.isFailure}] $patch")
}) {
println("Applied ${meta.name}. The result was $result.")
} }
// write output file // write output file
@ -34,7 +35,7 @@ internal class Patcher {
} }
if (MainCommand.patchResources) { if (MainCommand.patchResources) {
for (file in File(MainCommand.cacheDirectory).resolve("build/").listFiles().first().listFiles()) { for (file in File(MainCommand.cacheDirectory).resolve("build/").listFiles()?.first()?.listFiles()!!) {
if (!file.isDirectory) { if (!file.isDirectory) {
zipFileSystem.replaceFile(file.name, file.readBytes()) zipFileSystem.replaceFile(file.name, file.readBytes())
continue continue
@ -48,6 +49,8 @@ internal class Patcher {
// and sign the apk file // and sign the apk file
Signer.signApk(outFile) Signer.signApk(outFile)
println("[done]")
} }
private fun app.revanced.patcher.Patcher.addPatchesFiltered() { private fun app.revanced.patcher.Patcher.addPatchesFiltered() {
@ -58,25 +61,34 @@ internal class Patcher {
MainCommand.patchBundles.forEach { bundle -> MainCommand.patchBundles.forEach { bundle ->
val includedPatches = mutableListOf<Patch<Data>>() val includedPatches = mutableListOf<Patch<Data>>()
Patches.load(bundle).forEach patch@{ Patches.load(bundle).forEach patch@{ it ->
val patch = it() val patch = it.getDeclaredConstructor().newInstance()
val filterOutPatches = true val filterOutPatches = true
if (filterOutPatches && !patch.metadata.compatiblePackages.any { packageMetadata ->
val compatibilityAnnotation = patch.javaClass.findAnnotationRecursively(Compatibility::class.java)
val patchName =
patch.javaClass.findAnnotationRecursively(Name::class.java)?.name ?: Name::class.java.name
if (checkInclude && !MainCommand.includedPatches.contains(patchName)) {
return@patch
}
if (filterOutPatches) {
if (compatibilityAnnotation == null || !(compatibilityAnnotation.compatiblePackages.any { packageMetadata ->
packageMetadata.name == packageName && packageMetadata.versions.any { packageMetadata.name == packageName && packageMetadata.versions.any {
it == packageVersion it == packageVersion
} }
}) { })) {
// TODO: misleading error message
println("Skipping ${patch.metadata.name} due to incompatibility with current package $packageName.") println("[Skipped] $patchName: Incompatible with current package.")
return@patch return@patch
} }
if (checkInclude && !MainCommand.includedPatches.contains(patch.metadata.shortName)) {
return@patch
} }
println("Adding ${patch.metadata.name}.")
println("[loaded] $patchName")
includedPatches.add(patch) includedPatches.add(patch)
} }

View File

@ -1,26 +1,35 @@
package app.revanced.patch package app.revanced.patch
import app.revanced.patcher.data.base.Data
import app.revanced.patcher.patch.base.Patch import app.revanced.patcher.patch.base.Patch
import java.io.File import java.io.File
import java.net.URLClassLoader import java.net.URLClassLoader
import java.util.jar.JarFile
internal object Patches { internal object Patches {
/** /**
* This method loads patches from a given patch file * This method loads patches from a given jar file containing [Patch]es
* @return the loaded patches represented as a list of functions returning instances of [Patch] * @return the loaded patches represented as a list of [Patch] classes
*/ */
internal fun load(patchesJar: File): List<() -> Patch<Data>> { internal fun load(patchesJar: File) = buildList {
val url = patchesJar.toURI().toURL() val jarFile = JarFile(patchesJar)
val classLoader = URLClassLoader(arrayOf(url)) val classLoader = URLClassLoader(arrayOf(patchesJar.toURI().toURL()))
val indexClass = classLoader.loadClass("app.revanced.patches.Index") val entries = jarFile.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
if (!entry.name.endsWith(".class") || entry.name.contains("$")) continue
val index = indexClass.declaredFields.last() val clazz = classLoader.loadClass(entry.realName.replace('/', '.').replace(".class", ""))
index.isAccessible = true
if (!clazz.isAnnotationPresent(app.revanced.patcher.patch.annotations.Patch::class.java)) continue
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return index.get(null) as List<() -> Patch<Data>> val patch = clazz as Class<Patch<*>>
// TODO: include declared classes from patch
this.add(patch)
}
} }
} }

View File

@ -8,7 +8,7 @@ internal object Constants {
private const val COMMAND_CHMOD_MOUNT = "chmod +x" private const val COMMAND_CHMOD_MOUNT = "chmod +x"
internal const val COMMAND_PID_OF = "pidof -s" internal const val COMMAND_PID_OF = "pidof -s"
internal const val COMMAND_CREATE_DIR = "mkdir -p" internal const val COMMAND_CREATE_DIR = "mkdir -p"
internal const val COMMAND_LOGCAT = "logcat -c && logcat --pid=$($COMMAND_PID_OF $PLACEHOLDER)" internal const val COMMAND_LOGCAT = "logcat -c && logcat | grep AndroidRuntime"
internal const val COMMAND_RESTART = "monkey -p $PLACEHOLDER 1 && kill ${'$'}($COMMAND_PID_OF $PLACEHOLDER)" internal const val COMMAND_RESTART = "monkey -p $PLACEHOLDER 1 && kill ${'$'}($COMMAND_PID_OF $PLACEHOLDER)"
// default mount file name // default mount file name