mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-07 09:53:55 +01:00
Compare commits
20 Commits
v2.155.0
...
v2.157.0-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
246a6ce927 | ||
|
|
225726feeb | ||
|
|
f0b384bbfe | ||
|
|
160191b5cb | ||
|
|
bc06b4dfda | ||
|
|
c6e0e79cd5 | ||
|
|
53ab837489 | ||
|
|
1a94209bfb | ||
|
|
c30bf18745 | ||
|
|
068f18cd5b | ||
|
|
06105f4c87 | ||
|
|
5359965a0b | ||
|
|
3881fda3f4 | ||
|
|
cc43f356b5 | ||
|
|
939c084e31 | ||
|
|
b888eafce1 | ||
|
|
df3316b804 | ||
|
|
68f941deda | ||
|
|
0b18ed8f7f | ||
|
|
1f1519ca33 |
4
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
4
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
@@ -36,7 +36,7 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. Capture crash logs by running `logcat | grep AndroidRuntime`.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
@@ -70,4 +70,4 @@ body:
|
||||
- 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
|
||||
required: true
|
||||
|
||||
55
CHANGELOG.md
55
CHANGELOG.md
@@ -1,3 +1,58 @@
|
||||
# [2.157.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.157.0-dev.1...v2.157.0-dev.2) (2023-01-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **music:** update patches compatibility to v5.40.51 ([#1541](https://github.com/revanced/revanced-patches/issues/1541)) ([13143cb](https://github.com/revanced/revanced-patches/commit/13143cb5260f8793d246633a6a506bdc9f3a3ce7))
|
||||
|
||||
# [2.157.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.156.0...v2.157.0-dev.1) (2023-01-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* parse any kind of patch version ([66cd88f](https://github.com/revanced/revanced-patches/commit/66cd88f4d8a9161a4c51b70f2384dcee92fe2aea))
|
||||
* **twitter/hide-views-stats:** constrain to last working version ([#1522](https://github.com/revanced/revanced-patches/issues/1522)) ([bf45817](https://github.com/revanced/revanced-patches/commit/bf45817677fd058f9b255dbef5c1ca9aaec95531))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **finanzonline:** `remove-bootloader-detection` patch ([3952138](https://github.com/revanced/revanced-patches/commit/39521386c2296f46479e31c39ab245c2778ebd65))
|
||||
* **finanzonline:** `remove-root-detection` patch ([1d46d63](https://github.com/revanced/revanced-patches/commit/1d46d63fdcf3cbce53a7719f4490225368c4d5ae))
|
||||
* **youtube/microg-support:** check if Vanced MicroG is running in the background ([#1531](https://github.com/revanced/revanced-patches/issues/1531)) ([81934ef](https://github.com/revanced/revanced-patches/commit/81934efb39b8ed9b0a523ffd7c4d841227ac141f))
|
||||
* **youtube:** `open-links-externally` patch ([#1524](https://github.com/revanced/revanced-patches/issues/1524)) ([caf3d70](https://github.com/revanced/revanced-patches/commit/caf3d70c30bc440923c0e76e7331010905f6e729))
|
||||
|
||||
# [2.156.0](https://github.com/revanced/revanced-patches/compare/v2.155.0...v2.156.0) (2023-01-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **reddit/general-reddit-ads:** specify last version that works correctly ([#1495](https://github.com/revanced/revanced-patches/issues/1495)) ([2a3bedd](https://github.com/revanced/revanced-patches/commit/2a3bedd5608d2f23b174c4227ac167e44e54215e))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* explain how to capture crash logs [skip ci] ([f938ba8](https://github.com/revanced/revanced-patches/commit/f938ba81ec98f06f508dbdceeabd29a0ea7bf1af))
|
||||
* **id-austria:** `remove-root-detection` patch ([3cf77cd](https://github.com/revanced/revanced-patches/commit/3cf77cdb4ebbd128d29eedefa1ee35289e3c8058))
|
||||
* **id-austria:** `spoof-signature` patch ([355a847](https://github.com/revanced/revanced-patches/commit/355a847b1ccd69c4ab2c356395c97b4871e53f1f))
|
||||
* **nova-launcher:** `unlock-prime` patch ([#1463](https://github.com/revanced/revanced-patches/issues/1463)) ([cf710b2](https://github.com/revanced/revanced-patches/commit/cf710b27740cce4b9a0fbdf03a494eb8c65246da))
|
||||
|
||||
# [2.156.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.155.1-dev.1...v2.156.0-dev.1) (2023-01-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* explain how to capture crash logs [skip ci] ([f938ba8](https://github.com/revanced/revanced-patches/commit/f938ba81ec98f06f508dbdceeabd29a0ea7bf1af))
|
||||
* **id-austria:** `remove-root-detection` patch ([3cf77cd](https://github.com/revanced/revanced-patches/commit/3cf77cdb4ebbd128d29eedefa1ee35289e3c8058))
|
||||
* **id-austria:** `spoof-signature` patch ([355a847](https://github.com/revanced/revanced-patches/commit/355a847b1ccd69c4ab2c356395c97b4871e53f1f))
|
||||
* **nova-launcher:** `unlock-prime` patch ([#1463](https://github.com/revanced/revanced-patches/issues/1463)) ([cf710b2](https://github.com/revanced/revanced-patches/commit/cf710b27740cce4b9a0fbdf03a494eb8c65246da))
|
||||
|
||||
## [2.155.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.155.0...v2.155.1-dev.1) (2023-01-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **reddit/general-reddit-ads:** specify last version that works correctly ([#1495](https://github.com/revanced/revanced-patches/issues/1495)) ([2a3bedd](https://github.com/revanced/revanced-patches/commit/2a3bedd5608d2f23b174c4227ac167e44e54215e))
|
||||
|
||||
# [2.155.0](https://github.com/revanced/revanced-patches/compare/v2.154.0...v2.155.0) (2023-01-15)
|
||||
|
||||
|
||||
|
||||
35
README.md
35
README.md
@@ -47,6 +47,7 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `minimized-playback` | Enables minimized and background playback. | 17.49.37 |
|
||||
| `old-quality-layout` | Enables the original video quality flyout in the video player settings | 17.49.37 |
|
||||
| `open-links-directly` | Bypasses https://youtube.com/redirect URLs. | 17.49.37 |
|
||||
| `open-links-externally` | Open links outside of the app directly in your browser. | 17.49.37 |
|
||||
| `premium-heading` | Shows premium branding on the home screen. | all |
|
||||
| `remember-playback-rate` | Adds the ability to remember the playback rate you chose in the video playback rate flyout. | 17.49.37 |
|
||||
| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.49.37 |
|
||||
@@ -130,7 +131,7 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `dynamic-color` | Replaces the default Twitter Blue with the users Material You palette. | all |
|
||||
| `hide-views-stats` | Hides the view stats under tweets. | all |
|
||||
| `hide-views-stats` | Hides the view stats under tweets. | 9.69.1-release.0 |
|
||||
| `monochrome-icon` | Adds a monochrome icon. | all |
|
||||
| `timeline-ads` | Removes ads from the Twitter timeline. Might require clearing app data to remove already cached ads. | all |
|
||||
</details>
|
||||
@@ -150,10 +151,28 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | all |
|
||||
| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | 2022.43.0 |
|
||||
| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all |
|
||||
</details>
|
||||
|
||||
### [📦 `at.gv.bmf.bmf2go`](https://play.google.com/store/apps/details?id=at.gv.bmf.bmf2go)
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `remove-bootloader-detection` | Removes the check for an unlocked bootloader. | 2.2.0 |
|
||||
| `remove-root-detection` | Removes the check for root permissions | 2.2.0 |
|
||||
</details>
|
||||
|
||||
### [📦 `at.gv.oe.app`](https://play.google.com/store/apps/details?id=at.gv.oe.app)
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `remove-root-detection` | Removes the check for root permissions and unlocked bootloader. | 2.5.2 |
|
||||
| `spoof-signature` | Spoofs the signature of the app. | 2.5.2 |
|
||||
</details>
|
||||
|
||||
### [📦 `com.vanced.android.youtube`](https://play.google.com/store/apps/details?id=com.vanced.android.youtube)
|
||||
<details>
|
||||
|
||||
@@ -202,7 +221,15 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all |
|
||||
</details>
|
||||
|
||||
### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx)
|
||||
### [📦 `com.teslacoilsw.launcher`](https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher)
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `unlock-prime` | Unlocks Nova Prime and all functions of the app. | all |
|
||||
</details>
|
||||
|
||||
### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android)
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
@@ -210,7 +237,7 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `unlock-pro` | Unlocks all pro features. | all |
|
||||
</details>
|
||||
|
||||
### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android)
|
||||
### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx)
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|
||||
@@ -20,10 +20,10 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("app.revanced:revanced-patcher:6.4.1")
|
||||
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
||||
implementation("app.revanced:revanced-patcher:6.4.2")
|
||||
implementation("app.revanced:multidexlib2:2.5.3-a3836654")
|
||||
// Required for meta
|
||||
implementation("com.google.code.gson:gson:2.10")
|
||||
implementation("com.google.code.gson:gson:2.10.1")
|
||||
}
|
||||
|
||||
tasks {
|
||||
@@ -53,7 +53,7 @@ tasks {
|
||||
dependsOn(build)
|
||||
|
||||
classpath = sourceSets["main"].runtimeClasspath
|
||||
mainClass.set("app.revanced.meta.Meta")
|
||||
mainClass.set("app.revanced.meta.PatchesFileGenerator")
|
||||
}
|
||||
// Dummy task to fix the Gradle semantic-release plugin.
|
||||
// Remove this if you forked it to support building only.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
kotlin.code.style = official
|
||||
version = 2.155.0
|
||||
version = 2.157.0-dev.2
|
||||
|
||||
File diff suppressed because one or more lines are too long
70
src/main/kotlin/app/revanced/meta/JsonGenerator.kt
Normal file
70
src/main/kotlin/app/revanced/meta/JsonGenerator.kt
Normal file
@@ -0,0 +1,70 @@
|
||||
package app.revanced.meta
|
||||
|
||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||
import app.revanced.patcher.extensions.PatchExtensions.dependencies
|
||||
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||
import app.revanced.patcher.extensions.PatchExtensions.include
|
||||
import app.revanced.patcher.extensions.PatchExtensions.options
|
||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||
import app.revanced.patcher.extensions.PatchExtensions.version
|
||||
import app.revanced.patcher.patch.PatchOption
|
||||
import com.google.gson.GsonBuilder
|
||||
import java.io.File
|
||||
|
||||
internal class JsonGenerator : PatchesFileGenerator {
|
||||
override fun generate(bundle: PatchBundlePatches) {
|
||||
val patches = bundle.map {
|
||||
JsonPatch(
|
||||
it.patchName,
|
||||
it.description ?: "This patch has no description.",
|
||||
it.version ?: "0.0.0",
|
||||
!it.include,
|
||||
it.options?.map { option ->
|
||||
JsonPatch.Option(
|
||||
option.key,
|
||||
option.title,
|
||||
option.description,
|
||||
option.required,
|
||||
option.let { listOption ->
|
||||
if (listOption is PatchOption.ListOption<*>) {
|
||||
listOption.options.toMutableList().toTypedArray()
|
||||
} else null
|
||||
}
|
||||
)
|
||||
}?.toTypedArray() ?: emptyArray(),
|
||||
it.dependencies?.map { dep ->
|
||||
dep.java.patchName
|
||||
}?.toTypedArray() ?: emptyArray(),
|
||||
it.compatiblePackages?.map { pkg ->
|
||||
JsonPatch.CompatiblePackage(pkg.name, pkg.versions)
|
||||
}?.toTypedArray() ?: emptyArray()
|
||||
)
|
||||
}
|
||||
|
||||
val json = File("patches.json")
|
||||
json.writeText(GsonBuilder().serializeNulls().create().toJson(patches))
|
||||
}
|
||||
|
||||
private class JsonPatch(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val version: String,
|
||||
val excluded: Boolean,
|
||||
val options: Array<Option>,
|
||||
val dependencies: Array<String>,
|
||||
val compatiblePackages: Array<CompatiblePackage>,
|
||||
) {
|
||||
class CompatiblePackage(
|
||||
val name: String,
|
||||
val versions: Array<String>,
|
||||
)
|
||||
|
||||
class Option(
|
||||
val key: String,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val required: Boolean,
|
||||
val choices: Array<*>?,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package app.revanced.meta
|
||||
|
||||
import app.revanced.meta.json.generateJson
|
||||
import app.revanced.meta.readme.generateText
|
||||
import app.revanced.patcher.data.Context
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.util.patch.PatchBundle
|
||||
import java.io.File
|
||||
|
||||
typealias Bundle = List<Class<out Patch<Context>>>
|
||||
|
||||
object Meta {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
val patches = accumulatePatches()
|
||||
if (patches.isEmpty()) throw IllegalStateException("No patches found")
|
||||
|
||||
generateText(patches)
|
||||
generateJson(patches)
|
||||
}
|
||||
}
|
||||
|
||||
fun accumulatePatches() = PatchBundle.Jar(
|
||||
File("build/libs/").listFiles()!!.first {
|
||||
it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar")
|
||||
}.absolutePath
|
||||
).loadPatches()
|
||||
25
src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt
Normal file
25
src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
package app.revanced.meta
|
||||
|
||||
import app.revanced.patcher.data.Context
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.util.patch.PatchBundle
|
||||
import java.io.File
|
||||
|
||||
typealias PatchBundlePatches = List<Class<out Patch<Context>>>
|
||||
|
||||
internal interface PatchesFileGenerator {
|
||||
fun generate(bundle: PatchBundlePatches)
|
||||
|
||||
private companion object {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) = PatchBundle.Jar(
|
||||
File("build/libs/").listFiles()!!.first {
|
||||
it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar")
|
||||
}.absolutePath
|
||||
).loadPatches().also {
|
||||
if (it.isEmpty()) throw IllegalStateException("No patches found")
|
||||
}.let { bundle ->
|
||||
arrayOf(JsonGenerator(), ReadmeGenerator()).forEach { it.generate(bundle) }
|
||||
}
|
||||
}
|
||||
}
|
||||
69
src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt
Normal file
69
src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt
Normal file
@@ -0,0 +1,69 @@
|
||||
package app.revanced.meta
|
||||
|
||||
import app.revanced.patcher.data.Context
|
||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import java.io.File
|
||||
|
||||
internal class ReadmeGenerator : PatchesFileGenerator {
|
||||
private companion object {
|
||||
private const val TABLE_HEADER =
|
||||
"| \uD83D\uDC8A Patch | \uD83D\uDCDC Description | \uD83C\uDFF9 Target Version |\n" +
|
||||
"|:--------:|:--------------:|:-----------------:|"
|
||||
}
|
||||
|
||||
override fun generate(bundle: PatchBundlePatches) {
|
||||
val output = StringBuilder()
|
||||
|
||||
mutableMapOf<String, MutableList<Class<out Patch<Context>>>>()
|
||||
.apply {
|
||||
for (patch in bundle) {
|
||||
patch.compatiblePackages?.forEach { pkg ->
|
||||
if (!contains(pkg.name)) put(pkg.name, mutableListOf())
|
||||
this[pkg.name]!!.add(patch)
|
||||
}
|
||||
}
|
||||
}
|
||||
.entries
|
||||
.sortedByDescending { it.value.size }
|
||||
.forEach { (`package`, patches) ->
|
||||
val mostCommonVersion = buildMap {
|
||||
patches.forEach { patch ->
|
||||
patch.compatiblePackages?.single { compatiblePackage -> compatiblePackage.name == `package` }?.versions?.let {
|
||||
it.forEach { version -> merge(version, 1, Integer::sum) }
|
||||
}
|
||||
}
|
||||
}.let { commonMap ->
|
||||
commonMap.maxByOrNull { it.value }?.value?.let {
|
||||
// This is not foolproof, because for example v1.0.0-dev.0 will be returned instead of v1.0.0-release.
|
||||
// Unfortunately this can not be solved easily because versioning can be complex.
|
||||
commonMap.entries.filter { mostCommon -> mostCommon.value == it }.maxBy { it.key }.key
|
||||
} ?: "all"
|
||||
}
|
||||
|
||||
output.apply {
|
||||
appendLine("### [\uD83D\uDCE6 `${`package`}`](https://play.google.com/store/apps/details?id=${`package`})")
|
||||
appendLine("<details>\n")
|
||||
appendLine(TABLE_HEADER)
|
||||
patches.forEach { patch ->
|
||||
val recommendedPatchVersion = if (
|
||||
patch.compatiblePackages?.single { it.name == `package` }?.versions?.isNotEmpty() == true
|
||||
) mostCommonVersion else "all"
|
||||
|
||||
appendLine(
|
||||
"| `${patch.patchName}` " +
|
||||
"| ${patch.description} " +
|
||||
"| $recommendedPatchVersion |"
|
||||
)
|
||||
}
|
||||
appendLine("</details>\n")
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder(File("README-template.md").readText())
|
||||
.replace(Regex("\\{\\{\\s?table\\s?}}"), output.toString())
|
||||
.let(File("README.md")::writeText)
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package app.revanced.meta.json
|
||||
|
||||
import app.revanced.meta.Bundle
|
||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||
import app.revanced.patcher.extensions.PatchExtensions.dependencies
|
||||
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||
import app.revanced.patcher.extensions.PatchExtensions.include
|
||||
import app.revanced.patcher.extensions.PatchExtensions.options
|
||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||
import app.revanced.patcher.extensions.PatchExtensions.version
|
||||
import app.revanced.patcher.patch.PatchOption
|
||||
import com.google.gson.GsonBuilder
|
||||
import java.io.File
|
||||
|
||||
private val gson = GsonBuilder().serializeNulls().create()
|
||||
|
||||
fun generateJson(bundle: Bundle) {
|
||||
val patches = bundle.map {
|
||||
JsonPatch(
|
||||
it.patchName,
|
||||
it.description ?: "This patch has no description.",
|
||||
it.version ?: "0.0.0",
|
||||
!it.include,
|
||||
it.options?.map { option ->
|
||||
Option(
|
||||
option.key,
|
||||
option.title,
|
||||
option.description,
|
||||
option.required,
|
||||
option.let { lo ->
|
||||
if (lo is PatchOption.ListOption<*>) {
|
||||
lo.options.toMutableList().toTypedArray()
|
||||
} else null
|
||||
}
|
||||
)
|
||||
}?.toTypedArray() ?: emptyArray(),
|
||||
it.dependencies?.map { dep ->
|
||||
dep.java.patchName
|
||||
}?.toTypedArray() ?: emptyArray(),
|
||||
it.compatiblePackages?.map { pkg ->
|
||||
CompatiblePackage(pkg.name, pkg.versions)
|
||||
}?.toTypedArray() ?: emptyArray()
|
||||
)
|
||||
}
|
||||
|
||||
val json = File("patches.json")
|
||||
json.writeText(gson.toJson(patches))
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
@file:Suppress("ArrayInDataClass") // We don't need it here.
|
||||
|
||||
package app.revanced.meta.json
|
||||
|
||||
data class JsonPatch(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val version: String,
|
||||
val excluded: Boolean,
|
||||
val options: Array<Option>,
|
||||
val dependencies: Array<String>,
|
||||
val compatiblePackages: Array<CompatiblePackage>,
|
||||
)
|
||||
|
||||
data class CompatiblePackage(
|
||||
val name: String,
|
||||
val versions: Array<String>,
|
||||
)
|
||||
|
||||
data class Option(
|
||||
val key: String,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val required: Boolean,
|
||||
val choices: Array<*>?,
|
||||
)
|
||||
@@ -1,10 +0,0 @@
|
||||
package app.revanced.meta.readme
|
||||
|
||||
import app.revanced.patcher.data.Context
|
||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||
import app.revanced.patcher.patch.Patch
|
||||
|
||||
internal fun Class<out Patch<Context>>.getLatestVersion() =
|
||||
this.compatiblePackages?.first()?.versions?.map {
|
||||
SemanticVersion.fromString(it)
|
||||
}?.maxWithOrNull(SemanticVersionComparator)
|
||||
@@ -1,42 +0,0 @@
|
||||
package app.revanced.meta.readme
|
||||
|
||||
import app.revanced.meta.Bundle
|
||||
import app.revanced.patcher.data.Context
|
||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import java.io.File
|
||||
|
||||
private const val TABLE_HEADER =
|
||||
"| \uD83D\uDC8A Patch | \uD83D\uDCDC Description | \uD83C\uDFF9 Target Version |\n" + "|:--------:|:--------------:|:-----------------:|"
|
||||
|
||||
private val TABLE_REGEX = Regex("\\{\\{\\s?table\\s?}}")
|
||||
|
||||
fun generateText(bundle: Bundle) {
|
||||
val output = StringBuilder()
|
||||
val packages = mutableMapOf<String, MutableList<Class<out Patch<Context>>>>()
|
||||
|
||||
for (patch in bundle) {
|
||||
patch.compatiblePackages?.forEach { pkg ->
|
||||
if (!packages.contains(pkg.name)) packages[pkg.name] = mutableListOf()
|
||||
packages[pkg.name]!!.add(patch)
|
||||
}
|
||||
}
|
||||
|
||||
for (pkg in packages.entries.sortedByDescending { it.value.size }) {
|
||||
output.appendLine("### [\uD83D\uDCE6 `${pkg.key}`](https://play.google.com/store/apps/details?id=${pkg.key})")
|
||||
output.appendLine("<details>\n")
|
||||
|
||||
output.appendLine(TABLE_HEADER)
|
||||
pkg.value.forEach { output.appendLine("| `${it.patchName}` | ${it.description} | ${it.getLatestVersion() ?: "all"} |") }
|
||||
|
||||
output.appendLine("</details>\n")
|
||||
}
|
||||
|
||||
val readmeTemplate = Template(File("README-template.md").readText())
|
||||
readmeTemplate.replaceVariable(TABLE_REGEX, output.toString())
|
||||
|
||||
val readme = File("README.md")
|
||||
readme.writeText(readmeTemplate.toString())
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package app.revanced.meta.readme
|
||||
|
||||
data class SemanticVersion(val major: Int, val minor: Int, val patch: Int) {
|
||||
companion object {
|
||||
fun fromString(version: String): SemanticVersion {
|
||||
val parts = version.split(".")
|
||||
if (parts.count() != 3) throw IllegalArgumentException("Invalid semantic version")
|
||||
val versionNumbers = parts.map { it.toInt() }
|
||||
return SemanticVersion(versionNumbers[0], versionNumbers[1], versionNumbers[2])
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = "$major.$minor.$patch"
|
||||
}
|
||||
|
||||
object SemanticVersionComparator : Comparator<SemanticVersion> {
|
||||
override fun compare(a: SemanticVersion, b: SemanticVersion): Int = when {
|
||||
a.major != b.major -> a.major - b.major
|
||||
a.minor != b.minor -> a.minor - b.minor
|
||||
else -> a.patch - b.patch
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package app.revanced.meta.readme
|
||||
|
||||
class Template(template: String) {
|
||||
val result = StringBuilder(template)
|
||||
|
||||
fun replaceVariable(regex: Regex, value: String) {
|
||||
val range = regex.find(result)!!.range
|
||||
result.replace(range.first, range.last + 1, value)
|
||||
}
|
||||
|
||||
override fun toString(): String = result.toString()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.finanzonline.detection.bootloader.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object BootStateFingerprint : MethodFingerprint(
|
||||
"Z",
|
||||
access = AccessFlags.PUBLIC.value,
|
||||
strings = listOf("Boot state of device: %s"),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("/AttestationHelper;")
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.finanzonline.detection.bootloader.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object BootloaderDetectionFingerprint : MethodFingerprint(
|
||||
"Z",
|
||||
access = AccessFlags.PUBLIC.value,
|
||||
strings = listOf("Creation of attestation key succeeded", "Creation of attestation key failed"),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("/AttestationHelper;")
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
package app.revanced.patches.finanzonline.detection.bootloader.patch
|
||||
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.BootStateFingerprint
|
||||
import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.BootloaderDetectionFingerprint
|
||||
import app.revanced.patches.finanzonline.detection.shared.annotations.DetectionCompatibility
|
||||
|
||||
|
||||
@Patch
|
||||
@Name("remove-bootloader-detection")
|
||||
@Description("Removes the check for an unlocked bootloader.")
|
||||
@DetectionCompatibility
|
||||
@Version("0.0.1")
|
||||
class BootloaderDetectionPatch : BytecodePatch(
|
||||
listOf(BootloaderDetectionFingerprint, BootStateFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
arrayOf(BootloaderDetectionFingerprint, BootStateFingerprint).forEach { fingerprint ->
|
||||
fingerprint.result?.mutableMethod?.addInstruction(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
) ?: return fingerprint.toErrorResult()
|
||||
}
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.finanzonline.detection.root.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
object RootDetectionFingerprint : MethodFingerprint(
|
||||
"L",
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass == "Lat/gv/bmf/bmf2go/tools/utils/z;"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,34 @@
|
||||
package app.revanced.patches.finanzonline.detection.root.patch
|
||||
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.finanzonline.detection.root.fingerprints.RootDetectionFingerprint
|
||||
import app.revanced.patches.finanzonline.detection.shared.annotations.DetectionCompatibility
|
||||
|
||||
@Patch
|
||||
@Name("remove-root-detection")
|
||||
@Description("Removes the check for root permissions")
|
||||
@DetectionCompatibility
|
||||
@Version("0.0.1")
|
||||
class RootDetectionPatch : BytecodePatch(
|
||||
listOf(RootDetectionFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
RootDetectionFingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
|
||||
return-object v0
|
||||
"""
|
||||
) ?: return RootDetectionFingerprint.toErrorResult()
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.finanzonline.detection.shared.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("at.gv.bmf.bmf2go", arrayOf("2.2.0"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class DetectionCompatibility
|
||||
@@ -0,0 +1,12 @@
|
||||
package app.revanced.patches.idaustria.detection.root.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object RootDetectionFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
access = AccessFlags.PUBLIC.value,
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
package app.revanced.patches.idaustria.detection.root.patch
|
||||
|
||||
import app.revanced.patcher.annotation.*
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.idaustria.detection.root.fingerprints.RootDetectionFingerprint
|
||||
import app.revanced.patches.idaustria.detection.shared.annotations.DetectionCompatibility
|
||||
|
||||
@Patch
|
||||
@Name("remove-root-detection")
|
||||
@Description("Removes the check for root permissions and unlocked bootloader.")
|
||||
@DetectionCompatibility
|
||||
@Version("0.0.1")
|
||||
class RootDetectionPatch : BytecodePatch(
|
||||
listOf(RootDetectionFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
RootDetectionFingerprint.result!!.mutableMethod.addInstructions(0, "return-void")
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.idaustria.detection.shared.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("at.gv.oe.app", arrayOf("2.5.2"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class DetectionCompatibility
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.idaustria.detection.signature.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object SpoofSignatureFingerprint : MethodFingerprint(
|
||||
"L",
|
||||
parameters = listOf("L"),
|
||||
access = AccessFlags.PRIVATE.value,
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("/SL2Step1Task;") && methodDef.name == "getPubKey"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,45 @@
|
||||
package app.revanced.patches.idaustria.detection.signature.patch
|
||||
|
||||
import app.revanced.patcher.annotation.*
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.idaustria.detection.shared.annotations.DetectionCompatibility
|
||||
import app.revanced.patches.idaustria.detection.signature.fingerprints.SpoofSignatureFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("spoof-signature")
|
||||
@Description("Spoofs the signature of the app.")
|
||||
@DetectionCompatibility
|
||||
@Version("0.0.1")
|
||||
class SpoofSignaturePatch : BytecodePatch(
|
||||
listOf(SpoofSignatureFingerprint)
|
||||
) {
|
||||
companion object {
|
||||
const val EXPECTED_SIGNATURE = "OpenSSLRSAPublicKey{modulus=ac3e6fd6050aa7e0d6010ae58190404cd89a56935b44f6fee" +
|
||||
"067c149768320026e10b24799a1339e414605e448e3f264444a327b9ae292be2b62ad567dd1800dbed4a88f718a33dc6db6b" +
|
||||
"f5178aa41aa0efff8a3409f5ca95dbfccd92c7b4298966df806ea7a0204a00f0e745f6d9f13bdf24f3df715d7b62c1600906" +
|
||||
"15de1c8a956b9286764985a3b3c060963c435fb9481a5543aaf0671fc2dba6c5c2b17d1ef1d85137f14dc9bbdf3490288087" +
|
||||
"324cd48341cce64fabf6a9b55d1a7bf23b2fcdff451fd85bf0c7feb0a5e884d7c5c078e413149566a12a686e6efa70ae5161" +
|
||||
"a0201307692834cda336c55157fef125e67c01c1359886f94742105596b42a790404bbcda5dad6a65f115aaff5e45ef3c28b" +
|
||||
"2316ff6cef07aa49a45aa58c07bf258051b13ef449ccb37a3679afd5cfb9132f70bb9d931a937897544f90c3bcc80ed012e9" +
|
||||
"f6ba020b8cdc23f8c29ac092b88f0e370ff9434e4f0f359e614ae0868dc526fa41e4b7596533e8d10279b66e923ecd9f0b20" +
|
||||
"0def55be2c1f6f9c72c92fb45d7e0a9ac571cb38f0a9a37bb33ea06f223fde8c7a92e8c47769e386f9799776e8f110c21df2" +
|
||||
"77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" +
|
||||
"bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}"
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SpoofSignatureFingerprint.result!!.mutableMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$EXPECTED_SIGNATURE"
|
||||
return-object v0
|
||||
"""
|
||||
)
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -22,7 +22,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -25,7 +25,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
|
||||
"5.34.51",
|
||||
"5.36.51",
|
||||
"5.38.53",
|
||||
"5.39.52"
|
||||
"5.39.52",
|
||||
"5.40.51"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.nova.prime.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[
|
||||
Package("com.teslacoilsw.launcher")
|
||||
]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class UnlockPrimeCompatibility
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.nova.prime.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object UnlockPrimeFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
opcodes = listOf(
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.CONST_STRING,
|
||||
Opcode.CONST_4,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT
|
||||
),
|
||||
strings = listOf("1")
|
||||
)
|
||||
@@ -0,0 +1,50 @@
|
||||
package app.revanced.patches.nova.prime.patch
|
||||
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.nova.prime.annotations.UnlockPrimeCompatibility
|
||||
import app.revanced.patches.nova.prime.fingerprints.UnlockPrimeFingerprint
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction11x
|
||||
|
||||
@Patch
|
||||
@Name("unlock-prime")
|
||||
@Description("Unlocks Nova Prime and all functions of the app.")
|
||||
@UnlockPrimeCompatibility
|
||||
@Version("0.0.1")
|
||||
class UnlockPrimePatch : BytecodePatch(
|
||||
listOf(
|
||||
UnlockPrimeFingerprint
|
||||
)
|
||||
) {
|
||||
private companion object {
|
||||
// Any value except 0 unlocks prime, but 512 is needed for a protection mechanism
|
||||
// which would reset the preferences if the value on disk had changed after a restart.
|
||||
const val PRIME_STATUS: Int = 512
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
UnlockPrimeFingerprint.result?.apply {
|
||||
val insertIndex = scanResult.patternScanResult!!.endIndex + 1
|
||||
|
||||
val primeStatusRegister =
|
||||
(mutableMethod.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA
|
||||
|
||||
mutableMethod.addInstruction(
|
||||
insertIndex,
|
||||
"""
|
||||
const/16 v$primeStatusRegister, $PRIME_STATUS
|
||||
"""
|
||||
)
|
||||
} ?: UnlockPrimeFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,11 @@ package app.revanced.patches.reddit.ad.general.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.reddit.frontpage")])
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.reddit.frontpage", arrayOf("2022.43.0")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class GeneralAdsCompatibility
|
||||
|
||||
@@ -3,7 +3,11 @@ package app.revanced.patches.twitter.layout.hideviews.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.twitter.android")])
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.twitter.android", arrayOf("9.69.1-release.0")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class HideViewsCompatibility
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf("17.49.37")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class OpenLinksExternallyCompatibility
|
||||
@@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object BindSessionServiceFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
opcodes = listOf(
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("android.support.customtabs.action.CustomTabsService")
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object GetCustomTabPackageNameFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
opcodes = listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("android.support.customtabs.action.CustomTabsService")
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object InitializeCustomTabSupportFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
opcodes = listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("android.support.customtabs.action.CustomTabsService")
|
||||
)
|
||||
@@ -0,0 +1,65 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.patch
|
||||
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.links.open.annotations.OpenLinksExternallyCompatibility
|
||||
import app.revanced.patches.youtube.misc.links.open.fingerprints.BindSessionServiceFingerprint
|
||||
import app.revanced.patches.youtube.misc.links.open.fingerprints.GetCustomTabPackageNameFingerprint
|
||||
import app.revanced.patches.youtube.misc.links.open.fingerprints.InitializeCustomTabSupportFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
||||
|
||||
@Patch
|
||||
@Name("open-links-externally")
|
||||
@Description("Open links outside of the app directly in your browser.")
|
||||
@OpenLinksExternallyCompatibility
|
||||
@Version("0.0.1")
|
||||
class OpenLinksExternallyPatch : BytecodePatch(
|
||||
listOf(
|
||||
GetCustomTabPackageNameFingerprint,
|
||||
BindSessionServiceFingerprint,
|
||||
InitializeCustomTabSupportFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_enable_external_browser",
|
||||
StringResource("revanced_enable_external_browser_title", "Open links in browser"),
|
||||
true,
|
||||
StringResource("revanced_enable_external_browser_summary_on", "Opening links externally"),
|
||||
StringResource("revanced_enable_external_browser_summary_off", "Opening links in app")
|
||||
)
|
||||
)
|
||||
|
||||
arrayOf(
|
||||
GetCustomTabPackageNameFingerprint,
|
||||
BindSessionServiceFingerprint,
|
||||
InitializeCustomTabSupportFingerprint
|
||||
).forEach {
|
||||
val result = it.result ?: return it.toErrorResult()
|
||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex + 1
|
||||
with(result.mutableMethod) {
|
||||
val register = (implementation!!.instructions[insertIndex - 1] as Instruction21c).registerA
|
||||
addInstructions(
|
||||
insertIndex, """
|
||||
invoke-static {v$register}, Lapp/revanced/integrations/patches/OpenLinksExternallyPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="microg_not_installed_warning">Vanced MicroG is not installed. Please install it.</string>
|
||||
<string name="microg_not_running_warning">Vanced MicroG is failing to run. Please follow the "Don't kill my app" guide for Vanced MicroG.</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user