mirror of
https://github.com/ReVanced/revanced-cli.git
synced 2026-01-18 00:43:58 +00:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64b7e86252 | ||
|
|
7be9af0942 | ||
|
|
6a35cf7ea4 | ||
|
|
4914fd37bc | ||
|
|
38052b6ecf | ||
|
|
6e21d81964 | ||
|
|
3a733e5137 | ||
|
|
4f4e1f9834 | ||
|
|
e035d93d2c | ||
|
|
839854d890 | ||
|
|
43c772c98d | ||
|
|
b6dff6d832 | ||
|
|
29b057dead | ||
|
|
7df4a7e7da | ||
|
|
07c09f092c | ||
|
|
e8c9c80349 | ||
|
|
467d8387e6 | ||
|
|
65637c8b3a | ||
|
|
aa21137e99 | ||
|
|
b35302094a | ||
|
|
dfb527fc29 | ||
|
|
ac2332a592 | ||
|
|
a530624fb2 | ||
|
|
0e3ecc3a51 | ||
|
|
7fac75c6b6 | ||
|
|
7ca0b35e45 | ||
|
|
cb0fde4908 | ||
|
|
75e810e42e | ||
|
|
37cc77dfc5 | ||
|
|
075bf406fd | ||
|
|
71c81510f7 | ||
|
|
51fd16409f | ||
|
|
3f5345af6e | ||
|
|
649d9bdb2a | ||
|
|
f4b04698d8 | ||
|
|
240ab18eaf | ||
|
|
096dba2337 | ||
|
|
26780f94e5 | ||
|
|
faa52e2c68 | ||
|
|
e3e74ac0e9 | ||
|
|
de1bdb708c | ||
|
|
9b2b933998 | ||
|
|
fb5a72fdc0 | ||
|
|
86c5992630 | ||
|
|
06d2139ebf | ||
|
|
15ba4f40cd | ||
|
|
2d70037913 | ||
|
|
34108b9229 | ||
|
|
64a323e7e7 | ||
|
|
372470c77b | ||
|
|
3cef245728 | ||
|
|
aa54a2b1a9 | ||
|
|
f8c430be33 | ||
|
|
7692c18282 |
12
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
12
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
@@ -59,3 +59,15 @@ body:
|
|||||||
description: Add additional context here.
|
description: Add additional context here.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
- type: checkboxes
|
||||||
|
id: acknowledgements
|
||||||
|
attributes:
|
||||||
|
label: Acknowledgements
|
||||||
|
description: Your issue will be closed if you haven't done these steps.
|
||||||
|
options:
|
||||||
|
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
|
||||||
|
required: true
|
||||||
|
- label: I have written a short but informative title.
|
||||||
|
required: true
|
||||||
|
- label: I filled out all of the requested information in this issue properly.
|
||||||
|
required: true
|
||||||
14
.github/ISSUE_TEMPLATE/feature-issue.yml
vendored
14
.github/ISSUE_TEMPLATE/feature-issue.yml
vendored
@@ -43,4 +43,16 @@ body:
|
|||||||
label: Additional context
|
label: Additional context
|
||||||
description: Add additional context here.
|
description: Add additional context here.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
- type: checkboxes
|
||||||
|
id: acknowledgements
|
||||||
|
attributes:
|
||||||
|
label: Acknowledgements
|
||||||
|
description: Your issue will be closed if you haven't done these steps.
|
||||||
|
options:
|
||||||
|
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
|
||||||
|
required: true
|
||||||
|
- label: I have written a short but informative title.
|
||||||
|
required: true
|
||||||
|
- label: I filled out all of the requested information in this issue properly.
|
||||||
|
required: true
|
||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup JDK
|
- name: Setup JDK
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -111,4 +111,6 @@ gradle-app.setting
|
|||||||
.gradletasknamecache
|
.gradletasknamecache
|
||||||
|
|
||||||
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
|
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
|
||||||
# gradle/wrapper/gradle-wrapper.properties
|
# gradle/wrapper/gradle-wrapper.properties
|
||||||
|
revanced-cache/
|
||||||
|
options.toml
|
||||||
|
|||||||
1
.idea/.gitignore
generated
vendored
1
.idea/.gitignore
generated
vendored
@@ -6,3 +6,4 @@
|
|||||||
# Datasource local storage ignored files
|
# Datasource local storage ignored files
|
||||||
/dataSources/
|
/dataSources/
|
||||||
/dataSources.local.xml
|
/dataSources.local.xml
|
||||||
|
/kotlinc.xml
|
||||||
|
|||||||
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
@@ -8,7 +8,5 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/../revanced-patcher" vcs="Git" />
|
|
||||||
<mapping directory="$PROJECT_DIR$/../revanced-patches" vcs="Git" />
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
92
CHANGELOG.md
92
CHANGELOG.md
@@ -1,3 +1,95 @@
|
|||||||
|
# [2.15.0](https://github.com/revanced/revanced-cli/compare/v2.14.0...v2.15.0) (2022-10-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **gitignore:** ignore `options.toml` ([#158](https://github.com/revanced/revanced-cli/issues/158)) ([7be9af0](https://github.com/revanced/revanced-cli/commit/7be9af0942de2a834b9e57403d46263b65f1a422))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* use `am` instead of `monkey` to launch the app ([#159](https://github.com/revanced/revanced-cli/issues/159)) ([6a35cf7](https://github.com/revanced/revanced-cli/commit/6a35cf7ea46a4474120626ce03d28490cc96bf07))
|
||||||
|
|
||||||
|
# [2.14.0](https://github.com/revanced/revanced-cli/compare/v2.13.0...v2.14.0) (2022-10-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* escape quotation mark in string ([6e21d81](https://github.com/revanced/revanced-cli/commit/6e21d81964e8160e06ffda7051dd484e4aaaa432))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* handle unmounting deleted files ([#148](https://github.com/revanced/revanced-cli/issues/148)) ([3a733e5](https://github.com/revanced/revanced-cli/commit/3a733e513717799ca0e32327e5b8be043680c556))
|
||||||
|
* unmount all occurrences in `/proc/mounts` ([#131](https://github.com/revanced/revanced-cli/issues/131)) ([4f4e1f9](https://github.com/revanced/revanced-cli/commit/4f4e1f9834bf28d9be2efd4fd7bae19951b85258))
|
||||||
|
|
||||||
|
# [2.13.0](https://github.com/revanced/revanced-cli/compare/v2.12.0...v2.13.0) (2022-10-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* check, if input file exists ([b6dff6d](https://github.com/revanced/revanced-cli/commit/b6dff6d832de4a513a6d86b0a59b2458eddd23c2))
|
||||||
|
|
||||||
|
# [2.12.0](https://github.com/revanced/revanced-cli/compare/v2.11.2...v2.12.0) (2022-09-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* remove unused option `-r` ([467d838](https://github.com/revanced/revanced-cli/commit/467d8387e646c88d24a30406a5b2e84065ef4d54))
|
||||||
|
|
||||||
|
## [2.11.2](https://github.com/revanced/revanced-cli/compare/v2.11.1...v2.11.2) (2022-09-23)
|
||||||
|
|
||||||
|
## [2.11.1](https://github.com/revanced/revanced-cli/compare/v2.11.0...v2.11.1) (2022-09-21)
|
||||||
|
|
||||||
|
# [2.11.0](https://github.com/revanced/revanced-cli/compare/v2.10.2...v2.11.0) (2022-09-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* section `acknowledgements` for issue templates ([0e3ecc3](https://github.com/revanced/revanced-cli/commit/0e3ecc3a51540b71072ae0be0eb94d115a5b1f92))
|
||||||
|
|
||||||
|
## [2.10.2](https://github.com/revanced/revanced-cli/compare/v2.10.1...v2.10.2) (2022-09-18)
|
||||||
|
|
||||||
|
## [2.10.1](https://github.com/revanced/revanced-cli/compare/v2.10.0...v2.10.1) (2022-09-09)
|
||||||
|
|
||||||
|
# [2.10.0](https://github.com/revanced/revanced-cli/compare/v2.9.10...v2.10.0) (2022-09-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Patch Options CLI implementation ([#132](https://github.com/revanced/revanced-cli/issues/132)) ([3f5345a](https://github.com/revanced/revanced-cli/commit/3f5345af6e45bfb6c91d52fc089ab18d81fdc998))
|
||||||
|
|
||||||
|
## [2.9.10](https://github.com/revanced/revanced-cli/compare/v2.9.9...v2.9.10) (2022-09-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* don't print same patch multiple times ([f4b0469](https://github.com/revanced/revanced-cli/commit/f4b04698d8c1717824e86f91da5e01c5021612da))
|
||||||
|
|
||||||
|
## [2.9.9](https://github.com/revanced/revanced-cli/compare/v2.9.8...v2.9.9) (2022-09-08)
|
||||||
|
|
||||||
|
## [2.9.8](https://github.com/revanced/revanced-cli/compare/v2.9.7...v2.9.8) (2022-09-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* broken deprecation message ([e3e74ac](https://github.com/revanced/revanced-cli/commit/e3e74ac0e9a844f9d717a499bca09e575dd90435))
|
||||||
|
|
||||||
|
## [2.9.7](https://github.com/revanced/revanced-cli/compare/v2.9.6...v2.9.7) (2022-09-08)
|
||||||
|
|
||||||
|
## [2.9.6](https://github.com/revanced/revanced-cli/compare/v2.9.5...v2.9.6) (2022-09-07)
|
||||||
|
|
||||||
|
## [2.9.5](https://github.com/revanced/revanced-cli/compare/v2.9.4...v2.9.5) (2022-09-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* mount bind revanced.apk from magisk's mirror ([372470c](https://github.com/revanced/revanced-cli/commit/372470c77b82e8601ca523e87a2cfd44f79d0e31))
|
||||||
|
|
||||||
|
## [2.9.4](https://github.com/revanced/revanced-cli/compare/v2.9.3...v2.9.4) (2022-08-31)
|
||||||
|
|
||||||
|
## [2.9.3](https://github.com/revanced/revanced-cli/compare/v2.9.2...v2.9.3) (2022-08-14)
|
||||||
|
|
||||||
## [2.9.2](https://github.com/revanced/revanced-cli/compare/v2.9.1...v2.9.2) (2022-08-07)
|
## [2.9.2](https://github.com/revanced/revanced-cli/compare/v2.9.1...v2.9.2) (2022-08-07)
|
||||||
|
|
||||||
## [2.9.1](https://github.com/revanced/revanced-cli/compare/v2.9.0...v2.9.1) (2022-08-04)
|
## [2.9.1](https://github.com/revanced/revanced-cli/compare/v2.9.0...v2.9.1) (2022-08-04)
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib"))
|
|
||||||
implementation(kotlin("reflect"))
|
implementation(kotlin("reflect"))
|
||||||
|
|
||||||
implementation("app.revanced:revanced-patcher:3.3.2")
|
implementation("app.revanced:revanced-patcher:6.0.0")
|
||||||
implementation("info.picocli:picocli:4.6.3")
|
implementation("info.picocli:picocli:4.6.3")
|
||||||
implementation("com.android.tools.build:apksig:7.2.1")
|
implementation("com.android.tools.build:apksig:7.2.1")
|
||||||
implementation("com.github.revanced:jadb:master-SNAPSHOT") // updated fork
|
implementation("com.github.revanced:jadb:master-SNAPSHOT") // updated fork
|
||||||
implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
|
implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
|
||||||
|
implementation("cc.ekblad:4koma:1.1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 2.9.2
|
version = 2.15.0
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import app.revanced.patcher.PatcherOptions
|
|||||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.description
|
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||||
import app.revanced.patcher.util.patch.impl.JarPatchBundle
|
import app.revanced.patcher.util.patch.PatchBundle
|
||||||
|
import app.revanced.utils.OptionsLoader
|
||||||
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
|
||||||
@@ -51,6 +52,9 @@ internal object MainCommand : Runnable {
|
|||||||
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true)
|
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true)
|
||||||
var patchBundles = arrayOf<String>()
|
var patchBundles = arrayOf<String>()
|
||||||
|
|
||||||
|
@Option(names = ["--options"], description = ["Configuration file for all patch options"])
|
||||||
|
var options: File = File("options.toml")
|
||||||
|
|
||||||
@ArgGroup(exclusive = false)
|
@ArgGroup(exclusive = false)
|
||||||
var listingArgs: ListingArgs? = null
|
var listingArgs: ListingArgs? = null
|
||||||
|
|
||||||
@@ -88,9 +92,6 @@ internal object MainCommand : Runnable {
|
|||||||
@Option(names = ["-i", "--include"], description = ["Include patches"])
|
@Option(names = ["-i", "--include"], description = ["Include patches"])
|
||||||
var includedPatches = arrayOf<String>()
|
var includedPatches = arrayOf<String>()
|
||||||
|
|
||||||
@Option(names = ["-r", "--resource-patcher"], description = ["Disable patching resources"])
|
|
||||||
var disableResourcePatching: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["--experimental"], description = ["Disable patch version compatibility patch"])
|
@Option(names = ["--experimental"], description = ["Disable patch version compatibility patch"])
|
||||||
var experimental: Boolean = false
|
var experimental: Boolean = false
|
||||||
|
|
||||||
@@ -123,26 +124,22 @@ internal object MainCommand : Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (args.patchArgs?.listingArgs?.listOnly == true) {
|
if (args.patchArgs?.listingArgs?.listOnly == true) return printListOfPatches()
|
||||||
printListOfPatches()
|
if (args.uninstall) return uninstall()
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.uninstall) {
|
|
||||||
uninstall()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val pArgs = this.args.patchArgs?.patchingArgs ?: return
|
val pArgs = this.args.patchArgs?.patchingArgs ?: return
|
||||||
|
val outputFile = File(pArgs.outputPath) // the file to write to
|
||||||
|
|
||||||
// the file to write to
|
val allPatches = args.patchArgs!!.patchBundles.flatMap { bundle ->
|
||||||
val outputFile = File(pArgs.outputPath)
|
PatchBundle.Jar(bundle).loadPatches()
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionsLoader.init(args.patchArgs!!.options, allPatches)
|
||||||
|
|
||||||
val patcher = app.revanced.patcher.Patcher(
|
val patcher = app.revanced.patcher.Patcher(
|
||||||
PatcherOptions(
|
PatcherOptions(
|
||||||
args.inputFile,
|
args.inputFile.also { if (!it.exists()) return logger.error("Input file ${args.inputFile} does not exist.") },
|
||||||
pArgs.cacheDirectory,
|
pArgs.cacheDirectory,
|
||||||
!pArgs.disableResourcePatching,
|
|
||||||
pArgs.aaptPath,
|
pArgs.aaptPath,
|
||||||
pArgs.cacheDirectory,
|
pArgs.cacheDirectory,
|
||||||
PatcherLogger
|
PatcherLogger
|
||||||
@@ -151,13 +148,13 @@ internal object MainCommand : Runnable {
|
|||||||
|
|
||||||
// prepare adb
|
// prepare adb
|
||||||
val adb: Adb? = args.deploy?.let {
|
val adb: Adb? = args.deploy?.let {
|
||||||
Adb(outputFile, patcher.data.packageMetadata.packageName, args.deploy!!, !pArgs.mount)
|
Adb(outputFile, patcher.context.packageMetadata.packageName, args.deploy!!, !pArgs.mount)
|
||||||
}
|
}
|
||||||
|
|
||||||
val patchedFile = File(pArgs.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk")
|
val patchedFile = File(pArgs.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk")
|
||||||
|
|
||||||
// start the patcher
|
// start the patcher
|
||||||
Patcher.start(patcher, patchedFile)
|
Patcher.start(patcher, patchedFile, allPatches)
|
||||||
|
|
||||||
val cacheDirectory = File(pArgs.cacheDirectory)
|
val cacheDirectory = File(pArgs.cacheDirectory)
|
||||||
|
|
||||||
@@ -209,25 +206,22 @@ internal object MainCommand : Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun uninstall() {
|
private fun uninstall() {
|
||||||
// temporarily get package name using Patcher method
|
val adb: Adb? = args.deploy?.let {
|
||||||
// fix: abstract options in patcher
|
Adb(
|
||||||
val patcher = app.revanced.patcher.Patcher(
|
File("placeholder_file"),
|
||||||
PatcherOptions(
|
app.revanced.patcher.Patcher(PatcherOptions(args.inputFile, "")).context.packageMetadata.packageName,
|
||||||
args.inputFile,
|
args.deploy!!,
|
||||||
"uninstaller-cache",
|
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
|
||||||
File("uninstaller-cache").deleteRecursively()
|
|
||||||
|
|
||||||
val adb: Adb? = args.deploy?.let {
|
|
||||||
Adb(File("placeholder_file"), patcher.data.packageMetadata.packageName, args.deploy!!, false)
|
|
||||||
}
|
}
|
||||||
adb?.uninstall()
|
adb?.uninstall()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun printListOfPatches() {
|
private fun printListOfPatches() {
|
||||||
for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
|
val logged = mutableListOf<String>()
|
||||||
|
for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in PatchBundle.Jar(patchBundlePath)
|
||||||
|
.loadPatches()) {
|
||||||
|
if (patch.patchName in logged) continue
|
||||||
for (compatiblePackage in patch.compatiblePackages!!) {
|
for (compatiblePackage in patch.compatiblePackages!!) {
|
||||||
val packageEntryStr = buildString {
|
val packageEntryStr = buildString {
|
||||||
// Add package if flag is set
|
// Add package if flag is set
|
||||||
@@ -250,8 +244,9 @@ internal object MainCommand : Runnable {
|
|||||||
append("\t")
|
append("\t")
|
||||||
append(compatibleVersions)
|
append(compatibleVersions)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logged.add(patch.patchName)
|
||||||
logger.info(packageEntryStr)
|
logger.info(packageEntryStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package app.revanced.cli.patcher
|
|||||||
|
|
||||||
import app.revanced.cli.command.MainCommand.args
|
import app.revanced.cli.command.MainCommand.args
|
||||||
import app.revanced.cli.command.MainCommand.logger
|
import app.revanced.cli.command.MainCommand.logger
|
||||||
|
import app.revanced.patcher.data.Context
|
||||||
|
import app.revanced.patcher.patch.Patch
|
||||||
import app.revanced.utils.filesystem.ZipFileSystemUtils
|
import app.revanced.utils.filesystem.ZipFileSystemUtils
|
||||||
import app.revanced.utils.patcher.addPatchesFiltered
|
import app.revanced.utils.patcher.addPatchesFiltered
|
||||||
import app.revanced.utils.patcher.applyPatchesVerbose
|
import app.revanced.utils.patcher.applyPatchesVerbose
|
||||||
@@ -10,14 +12,17 @@ import java.io.File
|
|||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
internal object Patcher {
|
internal object Patcher {
|
||||||
internal fun start(patcher: app.revanced.patcher.Patcher, output: File) {
|
internal fun start(
|
||||||
|
patcher: app.revanced.patcher.Patcher,
|
||||||
|
output: File,
|
||||||
|
allPatches: List<Class<out Patch<Context>>>
|
||||||
|
) {
|
||||||
val inputFile = args.inputFile
|
val inputFile = args.inputFile
|
||||||
val args = args.patchArgs?.patchingArgs!!
|
|
||||||
|
|
||||||
// merge files like necessary integrations
|
// merge files like necessary integrations
|
||||||
patcher.mergeFiles()
|
patcher.mergeFiles()
|
||||||
// add patches, but filter incompatible or excluded patches
|
// add patches, but filter incompatible or excluded patches
|
||||||
patcher.addPatchesFiltered()
|
patcher.addPatchesFiltered(allPatches)
|
||||||
// apply patches
|
// apply patches
|
||||||
patcher.applyPatchesVerbose()
|
patcher.applyPatchesVerbose()
|
||||||
|
|
||||||
@@ -33,10 +38,10 @@ internal object Patcher {
|
|||||||
outputFileSystem.write(it.name, it.stream.readAllBytes())
|
outputFileSystem.write(it.name, it.stream.readAllBytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.disableResourcePatching) {
|
result.resourceFile?.let {
|
||||||
logger.info("Writing resources...")
|
logger.info("Writing resources...")
|
||||||
|
|
||||||
ZipFileSystemUtils(result.resourceFile!!).use { resourceFileSystem ->
|
ZipFileSystemUtils(it).use { resourceFileSystem ->
|
||||||
val resourceFiles = resourceFileSystem.getFile(File.separator)
|
val resourceFiles = resourceFileSystem.getFile(File.separator)
|
||||||
outputFileSystem.writePathRecursively(resourceFiles)
|
outputFileSystem.writePathRecursively(resourceFiles)
|
||||||
}
|
}
|
||||||
|
|||||||
77
src/main/kotlin/app/revanced/utils/OptionsLoader.kt
Normal file
77
src/main/kotlin/app/revanced/utils/OptionsLoader.kt
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package app.revanced.utils
|
||||||
|
|
||||||
|
import app.revanced.cli.command.MainCommand.logger
|
||||||
|
import app.revanced.patcher.Patcher
|
||||||
|
import app.revanced.patcher.data.Context
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.options
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||||
|
import app.revanced.patcher.patch.Patch
|
||||||
|
import cc.ekblad.toml.encodeToString
|
||||||
|
import cc.ekblad.toml.model.TomlValue
|
||||||
|
import cc.ekblad.toml.serialization.from
|
||||||
|
import cc.ekblad.toml.tomlMapper
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
private typealias PatchList = List<Class<out Patch<Context>>>
|
||||||
|
private typealias OptionsMap = MutableMap<String, MutableMap<String, Any>>
|
||||||
|
|
||||||
|
object OptionsLoader {
|
||||||
|
@JvmStatic
|
||||||
|
private val mapper = tomlMapper {}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun init(file: File, patches: PatchList) {
|
||||||
|
if (!file.exists()) file.createNewFile()
|
||||||
|
val map = mapper.decodeWithDefaults(generateDefaults(patches), TomlValue.from(file.toPath()))
|
||||||
|
readAndSet(map, patches)
|
||||||
|
save(map, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readAndSet(map: OptionsMap, patches: PatchList) {
|
||||||
|
for ((patchName, options) in map) {
|
||||||
|
val patch = patches.find { it.patchName == patchName } ?: continue
|
||||||
|
val patchOptions = patch.options ?: continue
|
||||||
|
for ((key, value) in options) {
|
||||||
|
if (value == "null") { // backwards compatibility, subject to removal
|
||||||
|
options.remove(key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
patchOptions[key] = value
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logger.error("Error while setting option $key for patch $patchName: ${e.message}")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun save(map: OptionsMap, file: File) {
|
||||||
|
val toml = mapper.encodeToString(map)
|
||||||
|
file.writeText(
|
||||||
|
"""
|
||||||
|
# A list of options for each patch.
|
||||||
|
# This file does not contain all options by default.
|
||||||
|
# Run the CLI with the "--list --with-options" flags to see all available options.
|
||||||
|
# You can also run the CLI with the aforementioned flags and a patch name to see all available options for that patch.
|
||||||
|
# To set an option, add a line with the format "option = value" or set the value if the option already exists.
|
||||||
|
# To reset an option to its default value, delete the line.
|
||||||
|
# To reset all options to their default values, delete this file.
|
||||||
|
#
|
||||||
|
# This file was generated by ReVanced Patcher version ${Patcher.version}.
|
||||||
|
""".trimIndent() + "\n\n$toml"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateDefaults(patches: PatchList) = buildMap {
|
||||||
|
for (patch in patches) {
|
||||||
|
val options = patch.options ?: continue
|
||||||
|
if (!options.iterator().hasNext()) continue
|
||||||
|
put(patch.patchName, buildMap {
|
||||||
|
for (option in options) {
|
||||||
|
put(option.key, option.value ?: continue)
|
||||||
|
}
|
||||||
|
} as MutableMap)
|
||||||
|
}
|
||||||
|
} as MutableMap
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ internal object Constants {
|
|||||||
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 | grep AndroidRuntime"
|
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 = "pm resolve-activity --brief $PLACEHOLDER | tail -n 1 | xargs am start -n && kill ${'$'}($COMMAND_PID_OF $PLACEHOLDER)"
|
||||||
|
|
||||||
// default mount file name
|
// default mount file name
|
||||||
private const val NAME_MOUNT_SCRIPT = "mount_revanced_$PLACEHOLDER.sh"
|
private const val NAME_MOUNT_SCRIPT = "mount_revanced_$PLACEHOLDER.sh"
|
||||||
@@ -35,7 +35,7 @@ internal object Constants {
|
|||||||
|
|
||||||
// unmount command
|
// unmount command
|
||||||
internal const val COMMAND_UMOUNT =
|
internal const val COMMAND_UMOUNT =
|
||||||
"stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' ) && umount -l ${'$'}stock_path"
|
"grep $PLACEHOLDER /proc/mounts | while read -r line; do echo ${'$'}line | cut -d \" \" -f 2 | sed 's/apk.*/apk/' | xargs -r umount -l; done"
|
||||||
|
|
||||||
// install mount script & set permissions
|
// install mount script & set permissions
|
||||||
internal const val COMMAND_INSTALL_MOUNT = "mv $PATH_INIT_PUSH $PATH_MOUNT && $COMMAND_CHMOD_MOUNT $PATH_MOUNT"
|
internal const val COMMAND_INSTALL_MOUNT = "mv $PATH_INIT_PUSH $PATH_MOUNT && $COMMAND_CHMOD_MOUNT $PATH_MOUNT"
|
||||||
@@ -44,12 +44,14 @@ internal object Constants {
|
|||||||
internal val CONTENT_MOUNT_SCRIPT =
|
internal val CONTENT_MOUNT_SCRIPT =
|
||||||
"""
|
"""
|
||||||
#!/system/bin/sh
|
#!/system/bin/sh
|
||||||
|
MAGISKTMP="${'$'}(magisk --path)" || MAGISKTMP=/sbin
|
||||||
|
MIRROR="${'$'}MAGISKTMP/.magisk/mirror"
|
||||||
while [ "${'$'}(getprop sys.boot_completed | tr -d '\r')" != "1" ]; do sleep 1; done
|
while [ "${'$'}(getprop sys.boot_completed | tr -d '\r')" != "1" ]; do sleep 1; done
|
||||||
|
|
||||||
base_path="$PATH_REVANCED_APP"
|
base_path="$PATH_REVANCED_APP"
|
||||||
stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' )
|
stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' )
|
||||||
|
|
||||||
chcon u:object_r:apk_data_file:s0 ${'$'}base_path
|
chcon u:object_r:apk_data_file:s0 ${'$'}base_path
|
||||||
mount -o bind ${'$'}base_path ${'$'}stock_path
|
mount -o bind ${'$'}MIRROR${'$'}base_path ${'$'}stock_path
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,64 +4,69 @@ import app.revanced.cli.command.MainCommand
|
|||||||
import app.revanced.cli.command.MainCommand.args
|
import app.revanced.cli.command.MainCommand.args
|
||||||
import app.revanced.cli.command.MainCommand.logger
|
import app.revanced.cli.command.MainCommand.logger
|
||||||
import app.revanced.patcher.Patcher
|
import app.revanced.patcher.Patcher
|
||||||
import app.revanced.patcher.data.Data
|
import app.revanced.patcher.data.Context
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.deprecated
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.include
|
import app.revanced.patcher.extensions.PatchExtensions.include
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||||
import app.revanced.patcher.patch.Patch
|
import app.revanced.patcher.patch.Patch
|
||||||
import app.revanced.patcher.util.patch.impl.JarPatchBundle
|
|
||||||
|
|
||||||
fun Patcher.addPatchesFiltered() {
|
fun Patcher.addPatchesFiltered(allPatches: List<Class<out Patch<Context>>>) {
|
||||||
val packageName = this.data.packageMetadata.packageName
|
val packageName = this.context.packageMetadata.packageName
|
||||||
val packageVersion = this.data.packageMetadata.packageVersion
|
val packageVersion = this.context.packageMetadata.packageVersion
|
||||||
|
|
||||||
args.patchArgs?.patchBundles!!.forEach { bundle ->
|
val includedPatches = mutableListOf<Class<out Patch<Context>>>()
|
||||||
val includedPatches = mutableListOf<Class<out Patch<Data>>>()
|
allPatches.forEach patchLoop@{ patch ->
|
||||||
JarPatchBundle(bundle).loadPatches().forEach patch@{ patch ->
|
val compatiblePackages = patch.compatiblePackages
|
||||||
val compatiblePackages = patch.compatiblePackages
|
val patchName = patch.patchName
|
||||||
val patchName = patch.patchName
|
|
||||||
|
|
||||||
val prefix = "Skipping $patchName"
|
val prefix = "Skipping $patchName, reason"
|
||||||
|
|
||||||
val args = MainCommand.args.patchArgs?.patchingArgs!!
|
val args = MainCommand.args.patchArgs?.patchingArgs!!
|
||||||
|
|
||||||
if (args.excludedPatches.contains(patchName)) {
|
if (args.excludedPatches.contains(patchName)) {
|
||||||
logger.info("$prefix: Explicitly excluded")
|
logger.info("$prefix: manually excluded")
|
||||||
return@patch
|
return@patchLoop
|
||||||
} else if ((!patch.include || args.defaultExclude) && !args.includedPatches.contains(patchName)) {
|
} else if ((!patch.include || args.defaultExclude) && !args.includedPatches.contains(patchName)) {
|
||||||
logger.info("$prefix: Not explicitly included")
|
logger.info("$prefix: excluded by default")
|
||||||
return@patch
|
return@patchLoop
|
||||||
}
|
|
||||||
|
|
||||||
if (compatiblePackages == null) logger.warn("$prefix: Missing compatibility annotation. Continuing.")
|
|
||||||
else {
|
|
||||||
if (!compatiblePackages.any { it.name == packageName }) {
|
|
||||||
logger.warn("$prefix: Incompatible with $packageName. This patch is only compatible with ${
|
|
||||||
compatiblePackages.joinToString(
|
|
||||||
", "
|
|
||||||
) { it.name }
|
|
||||||
}")
|
|
||||||
return@patch
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(args.experimental || compatiblePackages.any { it.versions.isEmpty() || it.versions.any { version -> version == packageVersion } })) {
|
|
||||||
val compatibleWith = compatiblePackages.map { _package ->
|
|
||||||
"${_package.name}: ${_package.versions.joinToString(", ")}"
|
|
||||||
}.joinToString(";")
|
|
||||||
logger.warn("$prefix: Incompatible with version $packageVersion. This patch is only compatible with version $compatibleWith")
|
|
||||||
return@patch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.trace("Adding $patchName")
|
|
||||||
includedPatches.add(patch)
|
|
||||||
}
|
}
|
||||||
this.addPatches(includedPatches)
|
|
||||||
|
patch.deprecated?.let { (reason, replacement) ->
|
||||||
|
logger.warn("$prefix: deprecated: $reason")
|
||||||
|
if (replacement != null) logger.warn("Either use ${replacement.java.patchName} instead or include it manually")
|
||||||
|
return@patchLoop
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compatiblePackages == null) logger.warn("$prefix: Missing compatibility annotation. Continuing.")
|
||||||
|
else {
|
||||||
|
if (!compatiblePackages.any { it.name == packageName }) {
|
||||||
|
logger.warn("$prefix: incompatible with $packageName. This patch is only compatible with ${
|
||||||
|
compatiblePackages.joinToString(
|
||||||
|
", "
|
||||||
|
) { it.name }
|
||||||
|
}")
|
||||||
|
return@patchLoop
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(args.experimental || compatiblePackages.any { it.versions.isEmpty() || it.versions.any { version -> version == packageVersion } })) {
|
||||||
|
val compatibleWith = compatiblePackages.joinToString(";") { _package ->
|
||||||
|
"${_package.name}: ${_package.versions.joinToString(", ")}"
|
||||||
|
}
|
||||||
|
logger.warn("$prefix: incompatible with version $packageVersion. This patch is only compatible with version $compatibleWith")
|
||||||
|
return@patchLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.trace("Adding $patchName")
|
||||||
|
includedPatches.add(patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.addPatches(includedPatches)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Patcher.applyPatchesVerbose() {
|
fun Patcher.applyPatchesVerbose() {
|
||||||
this.applyPatches().forEach { (patch, result) ->
|
this.executePatches().forEach { (patch, result) ->
|
||||||
if (result.isSuccess) {
|
if (result.isSuccess) {
|
||||||
logger.info("$patch succeeded")
|
logger.info("$patch succeeded")
|
||||||
return@forEach
|
return@forEach
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
package app.revanced.utils.signing.align.zip.structures
|
package app.revanced.utils.signing.align.zip.structures
|
||||||
|
|
||||||
import app.revanced.utils.signing.align.zip.getUShort
|
import app.revanced.utils.signing.align.zip.*
|
||||||
import app.revanced.utils.signing.align.zip.putUInt
|
|
||||||
import app.revanced.utils.signing.align.zip.putUShort
|
|
||||||
import app.revanced.utils.signing.align.zip.readUIntLE
|
|
||||||
import app.revanced.utils.signing.align.zip.readUShortLE
|
|
||||||
import java.io.DataInput
|
import java.io.DataInput
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.ByteOrder
|
import java.nio.ByteOrder
|
||||||
|
|||||||
Reference in New Issue
Block a user