update to newest patcher v22

This commit is contained in:
oSumAtrIX
2026-01-28 16:27:41 +01:00
parent e6032a1e4f
commit b140badcf1
5 changed files with 56 additions and 59 deletions

View File

@@ -42,6 +42,11 @@ dependencies {
kotlin { kotlin {
compilerOptions { compilerOptions {
jvmTarget.set(JvmTarget.JVM_11) jvmTarget.set(JvmTarget.JVM_11)
freeCompilerArgs.addAll(
"-Xexplicit-backing-fields",
"-Xcontext-parameters",
)
} }
} }

View File

@@ -13,7 +13,7 @@ bcpg-jdk18on = { module = "org.bouncycastle:bcpg-jdk18on", version.ref = "bcpg-j
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx" }
picocli = { module = "info.picocli:picocli", version.ref = "picocli" } picocli = { module = "info.picocli:picocli", version.ref = "picocli" }
revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" } revanced-patcher = { module = "app.revanced:patcher", version.ref = "revanced-patcher" }
revanced-library = { module = "app.revanced:revanced-library-jvm", version.ref = "revanced-library" } revanced-library = { module = "app.revanced:revanced-library-jvm", version.ref = "revanced-library" }
sigstore-java = { module = "dev.sigstore:sigstore-java", version.ref = "sigstore" } sigstore-java = { module = "dev.sigstore:sigstore-java", version.ref = "sigstore" }

View File

@@ -3,7 +3,7 @@ package app.revanced.cli.command
import app.revanced.library.PackageName import app.revanced.library.PackageName
import app.revanced.library.VersionMap import app.revanced.library.VersionMap
import app.revanced.library.mostCommonCompatibleVersions import app.revanced.library.mostCommonCompatibleVersions
import app.revanced.patcher.patch.loadPatchesFromJar import app.revanced.patcher.patch.loadPatches
import picocli.CommandLine import picocli.CommandLine
import java.io.File import java.io.File
import java.util.logging.Logger import java.util.logging.Logger
@@ -48,15 +48,14 @@ internal class ListCompatibleVersions : Runnable {
} }
} }
fun buildString(entry: Map.Entry<PackageName, VersionMap>) = fun buildString(entry: Map.Entry<PackageName, VersionMap>) = buildString {
buildString { val (name, versions) = entry
val (name, versions) = entry appendLine("Package name: $name")
appendLine("Package name: $name") appendLine("Most common compatible versions:")
appendLine("Most common compatible versions:") appendLine(versions.buildVersionsString().prependIndent("\t"))
appendLine(versions.buildVersionsString().prependIndent("\t")) }
}
val patches = loadPatchesFromJar(patchesFiles) val patches = loadPatches(patchesFiles = patchesFiles.toTypedArray())
patches.mostCommonCompatibleVersions( patches.mostCommonCompatibleVersions(
packageNames, packageNames,

View File

@@ -2,7 +2,7 @@ package app.revanced.cli.command
import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.Package
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.loadPatchesFromJar import app.revanced.patcher.patch.loadPatches
import picocli.CommandLine.* import picocli.CommandLine.*
import picocli.CommandLine.Help.Visibility.ALWAYS import picocli.CommandLine.Help.Visibility.ALWAYS
import java.io.File import java.io.File
@@ -86,13 +86,10 @@ internal object ListPatchesCommand : Runnable {
} }
fun PatchOption<*>.buildString() = buildString { fun PatchOption<*>.buildString() = buildString {
appendLine("Title: $title") appendLine("Name: $name")
description?.let { appendLine("Description: $it") } description?.let { appendLine("Description: $it") }
appendLine("Required: $required") appendLine("Required: $required")
default?.let { default?.let { append("Default: $it") }
appendLine("Key: $key")
append("Default: $it")
} ?: append("Key: $key")
values?.let { values -> values?.let { values ->
appendLine("\nPossible values:") appendLine("\nPossible values:")
@@ -102,7 +99,7 @@ internal object ListPatchesCommand : Runnable {
append("\nType: $type") append("\nType: $type")
} }
fun IndexedValue<Patch<*>>.buildString() = let { (index, patch) -> fun IndexedValue<Patch>.buildString() = let { (index, patch) ->
buildString { buildString {
if (withIndex) appendLine("Index: $index") if (withIndex) appendLine("Index: $index")
@@ -132,10 +129,10 @@ internal object ListPatchesCommand : Runnable {
} }
} }
fun Patch<*>.filterCompatiblePackages(name: String) = compatiblePackages?.any { (compatiblePackageName, _) -> compatiblePackageName == name } fun Patch.filterCompatiblePackages(name: String) = compatiblePackages?.any { (compatiblePackageName, _) -> compatiblePackageName == name }
?: withUniversalPatches ?: withUniversalPatches
val patches = loadPatchesFromJar(patchesFiles).withIndex().toList() val patches = loadPatches(patchesFiles = patchesFiles.toTypedArray()).withIndex().toList()
val filtered = val filtered =
packageName?.let { patches.filter { (_, patch) -> patch.filterCompatiblePackages(it) } } ?: patches packageName?.let { patches.filter { (_, patch) -> patch.filterCompatiblePackages(it) } } ?: patches

View File

@@ -4,10 +4,9 @@ import app.revanced.library.ApkUtils
import app.revanced.library.ApkUtils.applyTo import app.revanced.library.ApkUtils.applyTo
import app.revanced.library.installation.installer.* import app.revanced.library.installation.installer.*
import app.revanced.library.setOptions import app.revanced.library.setOptions
import app.revanced.patcher.Patcher
import app.revanced.patcher.PatcherConfig
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.loadPatchesFromJar import app.revanced.patcher.patch.loadPatches
import app.revanced.patcher.patcher
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import picocli.CommandLine import picocli.CommandLine
import picocli.CommandLine.ArgGroup import picocli.CommandLine.ArgGroup
@@ -123,7 +122,7 @@ internal object PatchCommand : Runnable {
names = ["-i", "--install"], names = ["-i", "--install"],
required = true, required = true,
description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."], description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."],
fallbackValue = "", // Empty string is used to select the first of connected devices. fallbackValue = "", // Empty string is used to select the first of connected devices.
arity = "0..1", arity = "0..1",
) )
internal var deviceSerial: String? = null internal var deviceSerial: String? = null
@@ -260,7 +259,7 @@ internal object PatchCommand : Runnable {
} else { } else {
AdbInstaller(deviceSerial) AdbInstaller(deviceSerial)
} }
} catch (e: DeviceNotFoundException) { } catch (_: DeviceNotFoundException) {
if (deviceSerial?.isNotEmpty() == true) { if (deviceSerial?.isNotEmpty() == true) {
logger.severe( logger.severe(
"Device with serial $deviceSerial not found to install to. " + "Device with serial $deviceSerial not found to install to. " +
@@ -285,62 +284,59 @@ internal object PatchCommand : Runnable {
logger.info("Loading patches") logger.info("Loading patches")
val patches = loadPatchesFromJar(patchesFiles) val patches = loadPatches(patchesFiles = patchesFiles.toTypedArray()) { file, throwable ->
logger.severe("Failed to load patches from ${file.path}:\n$throwable")
}
// endregion // endregion
val patcherTemporaryFilesPath = temporaryFilesPath.resolve("patcher") val patcherTemporaryFilesPath = temporaryFilesPath.resolve("patcher")
val (packageName, patcherResult) = Patcher( lateinit var capturedPackageName: String
PatcherConfig(
apk,
patcherTemporaryFilesPath,
aaptBinaryPath?.path,
patcherTemporaryFilesPath.absolutePath,
),
).use { patcher ->
val packageName = patcher.context.packageMetadata.packageName
val packageVersion = patcher.context.packageMetadata.packageVersion
val filteredPatches = patches.filterPatchSelection(packageName, packageVersion) val patch = patcher(
apk,
patcherTemporaryFilesPath,
aaptBinaryPath,
patcherTemporaryFilesPath.absolutePath,
) { packageName, versionName ->
capturedPackageName = packageName
val filteredPatches = patches.filterPatchSelection(packageName, versionName)
logger.info("Setting patch options") logger.info("Setting patch options")
val patchesList = patches.toList() val patchesList = patches.toList()
selection.filter { it.enabled != null }.associate { selection.filter { it.enabled != null }.associate {
val enabledSelection = it.enabled!! val enabledSelection = it.enabled!!
val name = enabledSelection.selector.name ?: patchesList[enabledSelection.selector.index!!].name!!
(enabledSelection.selector.name ?: patchesList[enabledSelection.selector.index!!].name!!) to name to enabledSelection.options
enabledSelection.options
}.let(filteredPatches::setOptions) }.let(filteredPatches::setOptions)
patcher += filteredPatches filteredPatches
}
// Execute patches. val patchesResult = patch { patchResult ->
runBlocking { val exception = patchResult.exception
patcher().collect { patchResult -> ?: return@patch logger.info("\"${patchResult.patch}\" succeeded")
val exception = patchResult.exception
?: return@collect logger.info("\"${patchResult.patch}\" succeeded")
StringWriter().use { writer -> StringWriter().use { writer ->
exception.printStackTrace(PrintWriter(writer)) exception.printStackTrace(PrintWriter(writer))
logger.severe("\"${patchResult.patch}\" failed:\n$writer") logger.severe("\"${patchResult.patch}\" failed:\n$writer")
}
}
} }
patcher.context.packageMetadata.packageName to patcher.get()
} }
// region Save. // region Save.
apk.copyTo(temporaryFilesPath.resolve(apk.name), overwrite = true).apply { apk.copyTo(temporaryFilesPath.resolve(apk.name), overwrite = true).let {
patcherResult.applyTo(this) patchesResult.applyTo(it)
}.let { patchedApkFile ->
if (installation?.mount != true) { if (installation?.mount != true) {
ApkUtils.signApk( ApkUtils.signApk(
patchedApkFile, it,
outputFilePath, outputFilePath,
signer, signer,
ApkUtils.KeyStoreDetails( ApkUtils.KeyStoreDetails(
@@ -351,7 +347,7 @@ internal object PatchCommand : Runnable {
), ),
) )
} else { } else {
patchedApkFile.copyTo(outputFilePath, overwrite = true) it.copyTo(outputFilePath, overwrite = true)
} }
} }
@@ -363,7 +359,7 @@ internal object PatchCommand : Runnable {
installation?.deviceSerial?.let { installation?.deviceSerial?.let {
runBlocking { runBlocking {
when (val result = installer!!.install(Installer.Apk(outputFilePath, packageName))) { when (val result = installer!!.install(Installer.Apk(outputFilePath, capturedPackageName))) {
RootInstallerResult.FAILURE -> logger.severe("Failed to mount the patched APK file") RootInstallerResult.FAILURE -> logger.severe("Failed to mount the patched APK file")
is AdbInstallerResult.Failure -> logger.severe(result.exception.toString()) is AdbInstallerResult.Failure -> logger.severe(result.exception.toString())
else -> logger.info("Installed the patched APK file") else -> logger.info("Installed the patched APK file")
@@ -386,10 +382,10 @@ internal object PatchCommand : Runnable {
* @param packageVersion The version of the APK file to be patched. * @param packageVersion The version of the APK file to be patched.
* @return The filtered patches. * @return The filtered patches.
*/ */
private fun Set<Patch<*>>.filterPatchSelection( private fun Set<Patch>.filterPatchSelection(
packageName: String, packageName: String,
packageVersion: String, packageVersion: String,
): Set<Patch<*>> = buildSet { ) = buildSet {
val enabledPatchesByName = val enabledPatchesByName =
selection.mapNotNull { it.enabled?.selector?.name }.toSet() selection.mapNotNull { it.enabled?.selector?.name }.toSet()
val enabledPatchesByIndex = val enabledPatchesByIndex =