mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-22 02:13:58 +00:00
Compare commits
32 Commits
v2.174.0-d
...
v2.174.0-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a83e0dc257 | ||
|
|
5ea4d3c2a6 | ||
|
|
f4ae7fd9d7 | ||
|
|
b6539922fe | ||
|
|
a697b16aa3 | ||
|
|
ab22794ef2 | ||
|
|
cd6988a688 | ||
|
|
74ad4fa5ea | ||
|
|
382c441de5 | ||
|
|
7953a1a07b | ||
|
|
ac0ed24ef2 | ||
|
|
489663c890 | ||
|
|
599e089c12 | ||
|
|
0d54b73958 | ||
|
|
943f6de55b | ||
|
|
7649e54c22 | ||
|
|
671c822fe9 | ||
|
|
56727bbe68 | ||
|
|
5ff5d804e2 | ||
|
|
9ca1f853e0 | ||
|
|
d229095087 | ||
|
|
bc38b9ebc2 | ||
|
|
3d79d5b7f0 | ||
|
|
b2de406844 | ||
|
|
35cd7780d0 | ||
|
|
6951e4a0e9 | ||
|
|
9bfcf99a22 | ||
|
|
56d3cf258c | ||
|
|
81a5d37bc3 | ||
|
|
c50f703551 | ||
|
|
85516401be | ||
|
|
311f5d80fc |
87
CHANGELOG.md
87
CHANGELOG.md
@@ -1,3 +1,90 @@
|
|||||||
|
# [2.174.0-dev.17](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.16...v2.174.0-dev.17) (2023-05-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/remember-video-quality:** fix default video quality/speed being applied when resuming app. ([#2112](https://github.com/revanced/revanced-patches/issues/2112)) ([f68a41c](https://github.com/revanced/revanced-patches/commit/f68a41ce9f9a78818d3f28b069e70b8c66125f53))
|
||||||
|
|
||||||
|
# [2.174.0-dev.16](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.15...v2.174.0-dev.16) (2023-05-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* check for opcode type `CONST` ([e5bb63c](https://github.com/revanced/revanced-patches/commit/e5bb63c7ab4427b6116de4a999be306e0f3cf12e))
|
||||||
|
|
||||||
|
# [2.174.0-dev.15](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.14...v2.174.0-dev.15) (2023-05-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **messenger:** add `disable-switching-emoji-to-sticker-in-message-input-field` patch ([#2099](https://github.com/revanced/revanced-patches/issues/2099)) ([ac5532a](https://github.com/revanced/revanced-patches/commit/ac5532a65c353b1964d9b7d990341fc7362e510d))
|
||||||
|
|
||||||
|
# [2.174.0-dev.14](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.13...v2.174.0-dev.14) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/hide-player-overlay:** make it toggleable in settings ([#2044](https://github.com/revanced/revanced-patches/issues/2044)) ([f693d55](https://github.com/revanced/revanced-patches/commit/f693d55caf1e0b72bb1f4c39b1eeb59436191e02))
|
||||||
|
|
||||||
|
# [2.174.0-dev.13](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.12...v2.174.0-dev.13) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* account fo breaking changes from ReVanced Patcher ([#2103](https://github.com/revanced/revanced-patches/issues/2103)) ([5be25cd](https://github.com/revanced/revanced-patches/commit/5be25cde4b34d58ced35a7edbb499477b538b748))
|
||||||
|
|
||||||
|
# [2.174.0-dev.12](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.11...v2.174.0-dev.12) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **readme-generator:** attempt sorting versions with `FlexVer` ([#2059](https://github.com/revanced/revanced-patches/issues/2059)) ([a54c464](https://github.com/revanced/revanced-patches/commit/a54c464522fa2a6a2d2525c8cb0ec961c2cc771c))
|
||||||
|
|
||||||
|
# [2.174.0-dev.11](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.10...v2.174.0-dev.11) (2023-05-07)
|
||||||
|
|
||||||
|
# [2.174.0-dev.10](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.9...v2.174.0-dev.10) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* incorrect instruction offsets ([42a5a38](https://github.com/revanced/revanced-patches/commit/42a5a387da3c53c579234a44c124ab0ba26117cb))
|
||||||
|
* incorrect smali syntax ([4e74a80](https://github.com/revanced/revanced-patches/commit/4e74a800c311d7acb2c2ddb492b43747db8a8def))
|
||||||
|
|
||||||
|
# [2.174.0-dev.9](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.8...v2.174.0-dev.9) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* incorrect cast of instruction ([fb94a1c](https://github.com/revanced/revanced-patches/commit/fb94a1cb48e8952981e2f9146eb90ee92a517b2e))
|
||||||
|
|
||||||
|
# [2.174.0-dev.8](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.7...v2.174.0-dev.8) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/integrations:** allow playback of embedded videos ([#2092](https://github.com/revanced/revanced-patches/issues/2092)) ([8a43d75](https://github.com/revanced/revanced-patches/commit/8a43d75e2db63c47bb9ad1b75027df0868c094e5))
|
||||||
|
|
||||||
|
# [2.174.0-dev.7](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.6...v2.174.0-dev.7) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **syncforreddit:** add `disable-ads` patch ([#2066](https://github.com/revanced/revanced-patches/issues/2066)) ([c1de5d6](https://github.com/revanced/revanced-patches/commit/c1de5d6e433263b9a17305fa1c65807921594731))
|
||||||
|
|
||||||
|
# [2.174.0-dev.6](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.5...v2.174.0-dev.6) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** `hide-load-more-button` patch ([#2078](https://github.com/revanced/revanced-patches/issues/2078)) ([7170802](https://github.com/revanced/revanced-patches/commit/71708022a06453f6f56c19d686fc505286523391))
|
||||||
|
|
||||||
|
# [2.174.0-dev.5](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.4...v2.174.0-dev.5) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **spotify/disable-capture-restriction:** make compatible with latest versions ([#2095](https://github.com/revanced/revanced-patches/issues/2095)) ([e48f127](https://github.com/revanced/revanced-patches/commit/e48f1278da2a9d82e70be41fa2c4c480c574816b))
|
||||||
|
|
||||||
# [2.174.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.3...v2.174.0-dev.4) (2023-05-07)
|
# [2.174.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.174.0-dev.3...v2.174.0-dev.4) (2023-05-07)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
The official ReVanced Patches.
|
The official ReVanced Patches.
|
||||||
|
|
||||||
|
## 📋 List of patches in this repository
|
||||||
|
|
||||||
{{ table }}
|
{{ table }}
|
||||||
|
|
||||||
> Looking for the JSON variant of this? [Click here](patches.json).
|
> Looking for the JSON variant of this? [Click here](patches.json).
|
||||||
@@ -64,7 +66,6 @@ Example:
|
|||||||
"description": "Enables a custom theme.",
|
"description": "Enables a custom theme.",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"excluded": false,
|
"excluded": false,
|
||||||
"deprecated": false,
|
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"key": "theme",
|
"key": "theme",
|
||||||
@@ -91,7 +92,6 @@ Example:
|
|||||||
"description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).",
|
"description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"excluded": false,
|
"excluded": false,
|
||||||
"deprecated": false,
|
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"key": "appName",
|
"key": "appName",
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
The official ReVanced Patches.
|
The official ReVanced Patches.
|
||||||
|
|
||||||
|
## 📋 List of patches in this repository
|
||||||
|
|
||||||
### [📦 `com.google.android.youtube`](https://play.google.com/store/apps/details?id=com.google.android.youtube)
|
### [📦 `com.google.android.youtube`](https://play.google.com/store/apps/details?id=com.google.android.youtube)
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ The official ReVanced Patches.
|
|||||||
| `hide-get-premium` | Hides advertisement for YouTube Premium under the video player. | 18.16.37 |
|
| `hide-get-premium` | Hides advertisement for YouTube Premium under the video player. | 18.16.37 |
|
||||||
| `hide-info-cards` | Hides info cards in videos. | 18.16.37 |
|
| `hide-info-cards` | Hides info cards in videos. | 18.16.37 |
|
||||||
| `hide-player-buttons` | Adds the option to hide video player previous and next buttons. | all |
|
| `hide-player-buttons` | Adds the option to hide video player previous and next buttons. | all |
|
||||||
| `hide-player-overlay` | Hides the dark player overlay when player controls are visible. | all |
|
| `hide-player-overlay` | Hides the dark background overlay from the player when player controls are visible. | all |
|
||||||
| `hide-seekbar` | Hides the seekbar. | 18.16.37 |
|
| `hide-seekbar` | Hides the seekbar. | 18.16.37 |
|
||||||
| `hide-timestamp` | Hides timestamp in video player. | 18.16.37 |
|
| `hide-timestamp` | Hides timestamp in video player. | 18.16.37 |
|
||||||
| `hide-video-action-buttons` | Adds the options to hide action buttons under a video. | 18.16.37 |
|
| `hide-video-action-buttons` | Adds the options to hide action buttons under a video. | 18.16.37 |
|
||||||
@@ -156,6 +158,15 @@ The official ReVanced Patches.
|
|||||||
| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all |
|
| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all |
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### [📦 `com.facebook.orca`](https://play.google.com/store/apps/details?id=com.facebook.orca)
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|
|:--------:|:--------------:|:-----------------:|
|
||||||
|
| `disable-switching-emoji-to-sticker-in-message-input-field` | Disables switching from emoji to sticker search mode in message input field | all |
|
||||||
|
| `hide-inbox-ads` | Hides ads in inbox. | all |
|
||||||
|
</details>
|
||||||
|
|
||||||
### [📦 `at.gv.bmf.bmf2go`](https://play.google.com/store/apps/details?id=at.gv.bmf.bmf2go)
|
### [📦 `at.gv.bmf.bmf2go`](https://play.google.com/store/apps/details?id=at.gv.bmf.bmf2go)
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@@ -174,6 +185,14 @@ The official ReVanced Patches.
|
|||||||
| `spoof-signature` | Spoofs the signature of the app. | all |
|
| `spoof-signature` | Spoofs the signature of the app. | all |
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### [📦 `com.laurencedawson.reddit_sync`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync)
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|
|:--------:|:--------------:|:-----------------:|
|
||||||
|
| `disable-ads` | Disables ads. | all |
|
||||||
|
</details>
|
||||||
|
|
||||||
### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit)
|
### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit)
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@@ -206,14 +225,6 @@ The official ReVanced Patches.
|
|||||||
| `hide-ads` | Removes general ads. | all |
|
| `hide-ads` | Removes general ads. | all |
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### [📦 `com.facebook.orca`](https://play.google.com/store/apps/details?id=com.facebook.orca)
|
|
||||||
<details>
|
|
||||||
|
|
||||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
|
||||||
|:--------:|:--------------:|:-----------------:|
|
|
||||||
| `hide-inbox-ads` | Hides ads in inbox. | all |
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android)
|
### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android)
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@@ -428,7 +439,6 @@ Example:
|
|||||||
"description": "Enables a custom theme.",
|
"description": "Enables a custom theme.",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"excluded": false,
|
"excluded": false,
|
||||||
"deprecated": false,
|
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"key": "theme",
|
"key": "theme",
|
||||||
@@ -455,7 +465,6 @@ Example:
|
|||||||
"description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).",
|
"description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"excluded": false,
|
"excluded": false,
|
||||||
"deprecated": false,
|
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"key": "appName",
|
"key": "appName",
|
||||||
|
|||||||
@@ -17,13 +17,26 @@ repositories {
|
|||||||
password = githubPassword
|
password = githubPassword
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Required for FlexVer-Java
|
||||||
|
maven {
|
||||||
|
url = uri("https://repo.sleeping.town")
|
||||||
|
content {
|
||||||
|
includeGroup("com.unascribed")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("app.revanced:revanced-patcher:7.1.0")
|
implementation("app.revanced:revanced-patcher:7.1.1")
|
||||||
implementation("app.revanced:multidexlib2:2.5.3-a3836654")
|
implementation("app.revanced:multidexlib2:2.5.3-a3836654")
|
||||||
// Required for meta
|
// Required for meta
|
||||||
implementation("com.google.code.gson:gson:2.10.1")
|
implementation("com.google.code.gson:gson:2.10.1")
|
||||||
|
// Required for FlexVer-Java
|
||||||
|
implementation("com.unascribed:flexver-java:1.0.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(11)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 2.174.0-dev.4
|
version = 2.174.0-dev.17
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -5,6 +5,7 @@ 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.patch.Patch
|
import app.revanced.patcher.patch.Patch
|
||||||
|
import com.unascribed.flexver.FlexVerComparator
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal class ReadmeGenerator : PatchesFileGenerator {
|
internal class ReadmeGenerator : PatchesFileGenerator {
|
||||||
@@ -37,9 +38,8 @@ internal class ReadmeGenerator : PatchesFileGenerator {
|
|||||||
}
|
}
|
||||||
}.let { commonMap ->
|
}.let { commonMap ->
|
||||||
commonMap.maxByOrNull { it.value }?.value?.let {
|
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.
|
commonMap.entries.filter { mostCommon -> mostCommon.value == it }
|
||||||
// Unfortunately this can not be solved easily because versioning can be complex.
|
.maxOfWith(FlexVerComparator::compare, Map.Entry<String, Int>::key)
|
||||||
commonMap.entries.filter { mostCommon -> mostCommon.value == it }.maxBy { it.key }.key
|
|
||||||
} ?: "all"
|
} ?: "all"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ChangePackageNamePatch : ResourcePatch {
|
|||||||
if (!packageName.matches(packageNameRegex))
|
if (!packageName.matches(packageNameRegex))
|
||||||
return PatchResultError("Invalid package name")
|
return PatchResultError("Invalid package name")
|
||||||
|
|
||||||
var originalPackageName = ""
|
var originalPackageName: String
|
||||||
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element
|
val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element
|
||||||
originalPackageName = manifest.getAttribute("package")
|
originalPackageName = manifest.getAttribute("package")
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package app.revanced.patches.messenger.inputfield.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
object SwitchMessangeInputEmojiButtonFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf("L", "Z"),
|
||||||
|
strings = listOf("afterTextChanged", "expression_search"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.CONST_STRING,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.CONST_STRING,
|
||||||
|
Opcode.GOTO
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package app.revanced.patches.messenger.inputfield.patch
|
||||||
|
|
||||||
|
import app.revanced.extensions.toErrorResult
|
||||||
|
import app.revanced.patcher.annotation.*
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.extensions.replaceInstruction
|
||||||
|
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.messenger.inputfield.fingerprints.SwitchMessangeInputEmojiButtonFingerprint
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("disable-switching-emoji-to-sticker-in-message-input-field")
|
||||||
|
@Description("Disables switching from emoji to sticker search mode in message input field")
|
||||||
|
@Compatibility([Package("com.facebook.orca")])
|
||||||
|
@Version("0.0.1")
|
||||||
|
class DisableSwitchingEmojiToStickerInMessageInputField : BytecodePatch(listOf(SwitchMessangeInputEmojiButtonFingerprint)) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
SwitchMessangeInputEmojiButtonFingerprint.result?.let {
|
||||||
|
val setStringIndex = it.scanResult.patternScanResult!!.startIndex + 2
|
||||||
|
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetRegister = instruction<OneRegisterInstruction>(setStringIndex).registerA
|
||||||
|
|
||||||
|
replaceInstruction(
|
||||||
|
setStringIndex,
|
||||||
|
"const-string v$targetRegister, \"expression\""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw SwitchMessangeInputEmojiButtonFingerprint.toErrorResult()
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import app.revanced.patcher.patch.BytecodePatch
|
|||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
import org.jf.dexlib2.iface.Method
|
import org.jf.dexlib2.iface.Method
|
||||||
|
|
||||||
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
|
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
|
||||||
@@ -24,10 +25,21 @@ abstract class AbstractIntegrationsPatch(
|
|||||||
* @see MethodFingerprint
|
* @see MethodFingerprint
|
||||||
*/
|
*/
|
||||||
abstract class IntegrationsFingerprint(
|
abstract class IntegrationsFingerprint(
|
||||||
|
returnType: String? = null,
|
||||||
|
access: Int? = null,
|
||||||
|
parameters: Iterable<String>? = null,
|
||||||
|
opcodes: Iterable<Opcode?>? = null,
|
||||||
strings: Iterable<String>? = null,
|
strings: Iterable<String>? = null,
|
||||||
customFingerprint: ((methodDef: Method) -> Boolean)? = null,
|
customFingerprint: ((methodDef: Method) -> Boolean)? = null,
|
||||||
private val contextRegisterResolver: (Method) -> Int = object : RegisterResolver {}
|
private val contextRegisterResolver: (Method) -> Int = object : RegisterResolver {}
|
||||||
) : MethodFingerprint(strings = strings, customFingerprint = customFingerprint) {
|
) : MethodFingerprint(
|
||||||
|
returnType,
|
||||||
|
access,
|
||||||
|
parameters,
|
||||||
|
opcodes,
|
||||||
|
strings,
|
||||||
|
customFingerprint
|
||||||
|
) {
|
||||||
fun invoke(integrationsDescriptor: String): PatchResult {
|
fun invoke(integrationsDescriptor: String): PatchResult {
|
||||||
result?.mutableMethod?.let { method ->
|
result?.mutableMethod?.let { method ->
|
||||||
val contextRegister = contextRegisterResolver(method)
|
val contextRegister = contextRegisterResolver(method)
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ class VerticalScrollPatch : BytecodePatch(
|
|||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
CanScrollVerticallyFingerprint.result?.let {
|
CanScrollVerticallyFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
val moveResultIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
val moveResultRegister = instruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
val moveResultRegister = instruction<OneRegisterInstruction>(moveResultIndex).registerA
|
||||||
|
|
||||||
|
val insertIndex = moveResultIndex + 1
|
||||||
addInstruction(
|
addInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"const/4 v$moveResultRegister, 0x0"
|
"const/4 v$moveResultRegister, 0x0"
|
||||||
|
|||||||
@@ -8,18 +8,13 @@ import app.revanced.patcher.extensions.instruction
|
|||||||
import app.revanced.patcher.extensions.replaceInstruction
|
import app.revanced.patcher.extensions.replaceInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
import app.revanced.patches.spotify.audio.annotation.DisableCaptureRestrictionCompatibility
|
import app.revanced.patches.spotify.audio.annotation.DisableCaptureRestrictionCompatibility
|
||||||
import app.revanced.patches.spotify.audio.fingerprints.DisableCaptureRestrictionAudioDriverFingerprint
|
import app.revanced.patches.spotify.audio.fingerprints.DisableCaptureRestrictionAudioDriverFingerprint
|
||||||
import app.revanced.patches.spotify.audio.resource.patch.DisableCaptureRestrictionResourcePatch
|
import app.revanced.patches.spotify.audio.resource.patch.DisableCaptureRestrictionResourcePatch
|
||||||
import org.jf.dexlib2.Opcode
|
|
||||||
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
|
||||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
|
||||||
import org.jf.dexlib2.iface.reference.MethodReference
|
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@Name("disable-capture-restriction")
|
@Name("disable-capture-restriction")
|
||||||
@@ -35,51 +30,16 @@ class DisableCaptureRestrictionBytecodePatch : BytecodePatch(
|
|||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
val method = DisableCaptureRestrictionAudioDriverFingerprint.result!!.mutableMethod
|
val method = DisableCaptureRestrictionAudioDriverFingerprint.result!!.mutableMethod
|
||||||
|
|
||||||
var invokePosition: Int? = null
|
method.apply {
|
||||||
var invokeParamRegister: Int? = null
|
// Replace constant
|
||||||
|
val original = instruction(0) as OneRegisterInstruction
|
||||||
// Find INVOKE_VIRTUAL opcode with call to AudioAttributesBuilder.setAllowedCapturePolicy(I)
|
replaceInstruction(
|
||||||
for ((index, instruction) in method.implementation!!.instructions.withIndex()) {
|
0,
|
||||||
if(instruction.opcode != Opcode.INVOKE_VIRTUAL)
|
"const/4 v${original.registerA}, $ALLOW_CAPTURE_BY_ALL"
|
||||||
continue
|
|
||||||
|
|
||||||
val methodName = ((instruction as ReferenceInstruction).reference as MethodReference).name
|
|
||||||
if (methodName != "setAllowedCapturePolicy")
|
|
||||||
continue
|
|
||||||
|
|
||||||
// Store register of the integer parameter for setAllowedCapturePolicy
|
|
||||||
invokeParamRegister = (instruction as FiveRegisterInstruction).registerD
|
|
||||||
invokePosition = index
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if(invokePosition == null || invokeParamRegister == null)
|
|
||||||
return PatchResultError("Cannot find setAllowedCapturePolicy method call")
|
|
||||||
|
|
||||||
// Walk back to the const/4 instruction that sets the parameter register
|
|
||||||
var matchFound = false
|
|
||||||
for (index in invokePosition downTo 0) {
|
|
||||||
val instruction = method.instruction(index)
|
|
||||||
if(instruction.opcode != Opcode.CONST_4)
|
|
||||||
continue
|
|
||||||
|
|
||||||
val register = (instruction as OneRegisterInstruction).registerA
|
|
||||||
if(register != invokeParamRegister)
|
|
||||||
continue
|
|
||||||
|
|
||||||
// Replace parameter value
|
|
||||||
method.replaceInstruction(
|
|
||||||
index, "const/4 v$register, $ALLOW_CAPTURE_BY_ALL"
|
|
||||||
)
|
)
|
||||||
matchFound = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (matchFound)
|
return PatchResultSuccess()
|
||||||
PatchResultSuccess()
|
|
||||||
else
|
|
||||||
PatchResultError("Const instruction not found")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
|||||||
@@ -1,10 +1,27 @@
|
|||||||
package app.revanced.patches.spotify.audio.fingerprints
|
package app.revanced.patches.spotify.audio.fingerprints
|
||||||
|
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import org.jf.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
object DisableCaptureRestrictionAudioDriverFingerprint : MethodFingerprint(
|
object DisableCaptureRestrictionAudioDriverFingerprint : MethodFingerprint(
|
||||||
|
"L",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.SYNTHETIC or AccessFlags.BRIDGE,
|
||||||
|
listOf("L"),
|
||||||
|
listOf(
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.RETURN_OBJECT
|
||||||
|
),
|
||||||
customFingerprint = { methodDef ->
|
customFingerprint = { methodDef ->
|
||||||
methodDef.definingClass == "Lcom/spotify/playback/playbacknative/AudioDriver;" && methodDef.name == "constructAudioAttributes"
|
// Check for method call to AudioAttributes$Builder.setAllowedCapturePolicy Android API
|
||||||
|
methodDef.implementation?.instructions?.any {
|
||||||
|
((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "setAllowedCapturePolicy"
|
||||||
|
} == true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package app.revanced.patches.syncforreddit.ads.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("com.laurencedawson.reddit_sync")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
internal annotation class DisableAdsCompatibility
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package app.revanced.patches.syncforreddit.ads.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
object IsAdsEnabledFingerprint : MethodFingerprint(
|
||||||
|
returnType = "Z",
|
||||||
|
access = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
strings = listOf("SyncIapHelper")
|
||||||
|
)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package app.revanced.patches.syncforreddit.ads.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.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.syncforreddit.ads.annotations.DisableAdsCompatibility
|
||||||
|
import app.revanced.patches.syncforreddit.ads.fingerprints.IsAdsEnabledFingerprint
|
||||||
|
import app.revanced.patches.syncforreddit.detection.piracy.patch.DisablePiracyDetectionPatch
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("disable-ads")
|
||||||
|
@DependsOn([DisablePiracyDetectionPatch::class])
|
||||||
|
@Description("Disables ads.")
|
||||||
|
@Version("0.0.1")
|
||||||
|
@DisableAdsCompatibility
|
||||||
|
class DisableAdsPatch : BytecodePatch(listOf(IsAdsEnabledFingerprint)) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
IsAdsEnabledFingerprint.result?.mutableMethod?.apply {
|
||||||
|
addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x0
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
} ?: return IsAdsEnabledFingerprint.toErrorResult()
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package app.revanced.patches.syncforreddit.detection.piracy.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
|
||||||
|
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import org.jf.dexlib2.iface.reference.TypeReference
|
||||||
|
|
||||||
|
object PiracyDetectionFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
access = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.NEW_INSTANCE,
|
||||||
|
Opcode.INVOKE_DIRECT,
|
||||||
|
Opcode.NEW_INSTANCE,
|
||||||
|
Opcode.INVOKE_DIRECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL
|
||||||
|
),
|
||||||
|
customFingerprint = { method ->
|
||||||
|
method.implementation?.instructions?.any {
|
||||||
|
if (it.opcode != Opcode.NEW_INSTANCE) return@any false
|
||||||
|
|
||||||
|
val reference = (it as ReferenceInstruction).reference
|
||||||
|
|
||||||
|
reference.toString() == "Lcom/github/javiersantos/piracychecker/PiracyChecker;"
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package app.revanced.patches.syncforreddit.detection.piracy.patch
|
||||||
|
|
||||||
|
import app.revanced.extensions.toErrorResult
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
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.patches.syncforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint
|
||||||
|
|
||||||
|
@Description("Disables detection of modified versions.")
|
||||||
|
@Version("0.0.1")
|
||||||
|
class DisablePiracyDetectionPatch : BytecodePatch(listOf(PiracyDetectionFingerprint)) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
PiracyDetectionFingerprint.result?.mutableMethod?.apply {
|
||||||
|
addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
return-void
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
} ?: return PiracyDetectionFingerprint.toErrorResult()
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ class UnlockProPatch : BytecodePatch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val setThemeMethod = SetThemeFingerprint.result!!.mutableMethod
|
val setThemeMethod = SetThemeFingerprint.result!!.mutableMethod
|
||||||
setThemeMethod.removeInstructions(0, 9)
|
setThemeMethod.removeInstructions(0, 10)
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class UnlockPaidWidgetsPatch : BytecodePatch(
|
|||||||
fingerprint.result?.mutableMethod ?: return fingerprint.toErrorResult()
|
fingerprint.result?.mutableMethod ?: return fingerprint.toErrorResult()
|
||||||
}.forEach { method ->
|
}.forEach { method ->
|
||||||
method.apply {
|
method.apply {
|
||||||
removeInstructions(4, 2)
|
removeInstructions(4, 3)
|
||||||
addInstructions(
|
addInstructions(
|
||||||
implementation?.instructions?.size!!, """
|
implementation?.instructions?.size!!, """
|
||||||
const/4 v1, 0x0
|
const/4 v1, 0x0
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class HideViewsBytecodePatch : BytecodePatch(
|
|||||||
TweetStatsContainerConstructorFingerprint,
|
TweetStatsContainerConstructorFingerprint,
|
||||||
returnFingerprint
|
returnFingerprint
|
||||||
) { patternScanResult, method ->
|
) { patternScanResult, method ->
|
||||||
method.removeInstructions(patternScanResult.endIndex - 3, 2)
|
method.removeInstructions(patternScanResult.endIndex - 3, 3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,13 +80,13 @@ class HideViewsBytecodePatch : BytecodePatch(
|
|||||||
TweetStatsContainerWrapperConstructorFingerprint,
|
TweetStatsContainerWrapperConstructorFingerprint,
|
||||||
wrapperReturnFingerprint
|
wrapperReturnFingerprint
|
||||||
) { patternScanResult, method ->
|
) { patternScanResult, method ->
|
||||||
method.removeInstructions(patternScanResult.startIndex - 4, 3)
|
method.removeInstructions(patternScanResult.startIndex - 4, 4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeViewDelegateBinderSubscription() {
|
private fun removeViewDelegateBinderSubscription() {
|
||||||
transformMethod(TweetStatsViewDelegateBinderFingerprint) { result, method ->
|
transformMethod(TweetStatsViewDelegateBinderFingerprint) { result, method ->
|
||||||
method.removeInstructions(result.scanResult.patternScanResult!!.startIndex - 4, 9)
|
method.removeInstructions(result.scanResult.patternScanResult!!.startIndex - 4, 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,16 +12,12 @@ import app.revanced.patcher.patch.annotations.Patch
|
|||||||
import app.revanced.patches.youtube.layout.buttons.player.background.annotations.PlayerButtonBackgroundCompatibility
|
import app.revanced.patches.youtube.layout.buttons.player.background.annotations.PlayerButtonBackgroundCompatibility
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
@Patch
|
@Patch(false)
|
||||||
@Name("remove-player-button-background")
|
@Name("remove-player-button-background")
|
||||||
@Description("Removes the background from the video player buttons.")
|
@Description("Removes the background from the video player buttons.")
|
||||||
@PlayerButtonBackgroundCompatibility
|
@PlayerButtonBackgroundCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class PlayerButtonBackgroundPatch : ResourcePatch {
|
class PlayerButtonBackgroundPatch : ResourcePatch {
|
||||||
private companion object {
|
|
||||||
const val RESOURCE_FILE_PATH = "res/drawable/player_button_circle_background.xml"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext): PatchResult {
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
context.xmlEditor[RESOURCE_FILE_PATH].use { editor ->
|
context.xmlEditor[RESOURCE_FILE_PATH].use { editor ->
|
||||||
editor.file.doRecursively node@{ node ->
|
editor.file.doRecursively node@{ node ->
|
||||||
@@ -35,4 +31,8 @@ class PlayerButtonBackgroundPatch : ResourcePatch {
|
|||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val RESOURCE_FILE_PATH = "res/drawable/player_button_circle_background.xml"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class CommentsPatch : BytecodePatch(
|
|||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static {v$shortsCommentsButtonRegister, Lapp/revanced/integrations/patches/HideShortsCommentsButtonPatch;->hideShortsCommentsButton(Landroid/view/View;)V
|
invoke-static { v$shortsCommentsButtonRegister }, Lapp/revanced/integrations/patches/HideShortsCommentsButtonPatch;->hideShortsCommentsButton(Landroid/view/View;)V
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hide.loadmorebutton.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf(
|
||||||
|
"17.49.37",
|
||||||
|
"18.03.36",
|
||||||
|
"18.03.42",
|
||||||
|
"18.04.35",
|
||||||
|
"18.04.41",
|
||||||
|
"18.05.32",
|
||||||
|
"18.05.35",
|
||||||
|
"18.05.40",
|
||||||
|
"18.08.37",
|
||||||
|
"18.15.40",
|
||||||
|
"18.16.37"
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
internal annotation class HideLoadMoreButtonCompatibility
|
||||||
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
object HideLoadMoreButtonFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
parameters = listOf("L", "L", "L", "L"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any {
|
||||||
|
if (it.opcode != Opcode.CONST) return@any false
|
||||||
|
|
||||||
|
val literal = (it as WideLiteralInstruction).wideLiteral
|
||||||
|
|
||||||
|
literal == HideLoadMoreButtonResourcePatch.expandButtonDownId
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.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.extensions.instruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints.HideLoadMoreButtonFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("hide-load-more-button")
|
||||||
|
@Description("Hides the button under videos that loads similar videos.")
|
||||||
|
@DependsOn([HideLoadMoreButtonResourcePatch::class])
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideLoadMoreButtonPatch : BytecodePatch(listOf(HideLoadMoreButtonFingerprint)) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
HideLoadMoreButtonFingerprint.result?.let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val moveRegisterIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val viewRegister = instruction<OneRegisterInstruction>(moveRegisterIndex).registerA
|
||||||
|
|
||||||
|
val insertIndex = moveRegisterIndex + 1
|
||||||
|
addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"invoke-static { v$viewRegister }, " +
|
||||||
|
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideLoadMoreButton(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: return HideLoadMoreButtonFingerprint.toErrorResult()
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/patches/HideLoadMoreButtonPatch;"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
|
import app.revanced.patches.youtube.layout.hide.loadmorebutton.annotations.HideLoadMoreButtonCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
|
||||||
|
@Name("hide-load-more-button-resource-patch")
|
||||||
|
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
|
||||||
|
@HideLoadMoreButtonCompatibility
|
||||||
|
class HideLoadMoreButtonResourcePatch : ResourcePatch {
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_load_more_button",
|
||||||
|
StringResource("revanced_hide_load_more_button_title", "Hide Load More button"),
|
||||||
|
true,
|
||||||
|
StringResource("revanced_hide_load_more_button_summary_on", "Load More button is hidden"),
|
||||||
|
StringResource("revanced_hide_load_more_button_summary_off", "Load More button is shown")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
expandButtonDownId = ResourceMappingPatch.resourceMappings.single {
|
||||||
|
it.type == "layout" && it.name == "expand_button_down"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal companion object {
|
||||||
|
var expandButtonDownId: Long = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
object CreatePlayerOverviewFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
access = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any {
|
||||||
|
if (it.opcode != Opcode.CONST) return@any false
|
||||||
|
|
||||||
|
val literal = (it as WideLiteralInstruction).wideLiteral
|
||||||
|
|
||||||
|
literal == HidePlayerOverlayResourcePatch.scrimOverlayId
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.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.extensions.instruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HidePlayerOverlayPatchCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints.CreatePlayerOverviewFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("hide-player-overlay")
|
||||||
|
@Description("Hides the dark background overlay from the player when player controls are visible.")
|
||||||
|
@DependsOn([HidePlayerOverlayResourcePatch::class])
|
||||||
|
@HidePlayerOverlayPatchCompatibility
|
||||||
|
@Version("0.0.2")
|
||||||
|
class HidePlayerOverlayPatch : BytecodePatch(listOf(CreatePlayerOverviewFingerprint)) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
CreatePlayerOverviewFingerprint.result?.let { result ->
|
||||||
|
result.mutableMethod.apply {
|
||||||
|
val viewRegisterIndex = implementation!!.instructions.indexOfFirst {
|
||||||
|
val literal = (it as? WideLiteralInstruction)?.wideLiteral
|
||||||
|
|
||||||
|
literal == HidePlayerOverlayResourcePatch.scrimOverlayId
|
||||||
|
} + 3
|
||||||
|
val viewRegister = instruction<OneRegisterInstruction>(viewRegisterIndex).registerA
|
||||||
|
|
||||||
|
val insertIndex = viewRegisterIndex + 1
|
||||||
|
addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"invoke-static { v$viewRegister }, " +
|
||||||
|
"$INTEGRATIONS_CLASS_DESCRIPTOR->hidePlayerOverlay(Landroid/widget/ImageView;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: return CreatePlayerOverviewFingerprint.toErrorResult()
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/HidePlayerOverlayPatch;"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.layout.hide.player.overlay.patch
|
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Description
|
|
||||||
import app.revanced.patcher.annotation.Name
|
|
||||||
import app.revanced.patcher.annotation.Version
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
|
||||||
import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HidePlayerOverlayPatchCompatibility
|
|
||||||
|
|
||||||
@Patch(false)
|
|
||||||
@Name("hide-player-overlay")
|
|
||||||
@Description("Hides the dark player overlay when player controls are visible.")
|
|
||||||
@HidePlayerOverlayPatchCompatibility
|
|
||||||
@Version("0.0.1")
|
|
||||||
class HidePlayerOverlayPatch : ResourcePatch {
|
|
||||||
override fun execute(context: ResourceContext): PatchResult {
|
|
||||||
val attributes = arrayOf("height", "width")
|
|
||||||
|
|
||||||
context.xmlEditor[RESOURCE_FILE_PATH].use { editor ->
|
|
||||||
editor.file.getElementsByTagName("FrameLayout").item(0).childNodes.apply {
|
|
||||||
for (i in 1 until length) {
|
|
||||||
val view = item(i)
|
|
||||||
if (
|
|
||||||
view.attributes.getNamedItem("android:id")
|
|
||||||
?.nodeValue
|
|
||||||
?.endsWith("scrim_overlay") == true
|
|
||||||
) {
|
|
||||||
attributes.forEach {
|
|
||||||
view.attributes.getNamedItem("android:layout_$it").nodeValue = "0.0dip"
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return PatchResultSuccess()
|
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
const val RESOURCE_FILE_PATH = "res/layout/youtube_controls_overlay.xml"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
|
import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HidePlayerOverlayPatchCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
import jdk.jfr.Name
|
||||||
|
|
||||||
|
@Name("hide-player-overlay-resource-patch")
|
||||||
|
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
|
||||||
|
@HidePlayerOverlayPatchCompatibility
|
||||||
|
class HidePlayerOverlayResourcePatch : ResourcePatch {
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_player_overlay",
|
||||||
|
StringResource("revanced_hide_player_overlay_title", "Hide background overlay in player"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_player_overlay_summary_on", "Background overlay is hidden"),
|
||||||
|
StringResource("revanced_hide_player_overlay_summary_off", "Background overlay is shown")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
scrimOverlayId = ResourceMappingPatch.resourceMappings.single {
|
||||||
|
it.type == "id" && it.name == "scrim_overlay"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal companion object {
|
||||||
|
var scrimOverlayId: Long = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.integrations.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
object EmbeddedPlayerControlsOverlayFingerprint : IntegrationsFingerprint(
|
||||||
|
access = AccessFlags.PRIVATE or AccessFlags.CONSTRUCTOR,
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf("L", "L", "L"),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.startsWith("Lcom/google/android/apps/youtube/embeddedplayer/service/ui/overlays/controlsoverlay/remoteloaded/")
|
||||||
|
},
|
||||||
|
contextRegisterResolver = { it.implementation!!.registerCount - it.parameters.size }
|
||||||
|
)
|
||||||
@@ -5,6 +5,7 @@ import app.revanced.patcher.patch.annotations.RequiresIntegrations
|
|||||||
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch
|
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
|
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
|
||||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint
|
import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.fingerprints.EmbeddedPlayerControlsOverlayFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.ServiceFingerprint
|
import app.revanced.patches.youtube.misc.integrations.fingerprints.ServiceFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerFingerprint
|
import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerFingerprint
|
||||||
|
|
||||||
@@ -13,5 +14,5 @@ import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePla
|
|||||||
@RequiresIntegrations
|
@RequiresIntegrations
|
||||||
class IntegrationsPatch : AbstractIntegrationsPatch(
|
class IntegrationsPatch : AbstractIntegrationsPatch(
|
||||||
"Lapp/revanced/integrations/utils/ReVancedUtils;",
|
"Lapp/revanced/integrations/utils/ReVancedUtils;",
|
||||||
listOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint),
|
listOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint, EmbeddedPlayerControlsOverlayFingerprint),
|
||||||
)
|
)
|
||||||
@@ -160,24 +160,32 @@ class VideoInformationPatch : BytecodePatch(
|
|||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/VideoInformation;"
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/VideoInformation;"
|
||||||
|
|
||||||
private lateinit var playerInitMethod: MutableMethod
|
private lateinit var playerInitMethod: MutableMethod
|
||||||
|
private var playerInitInsertIndex = 4
|
||||||
|
|
||||||
private lateinit var timeMethod: MutableMethod
|
private lateinit var timeMethod: MutableMethod
|
||||||
|
private var timeInitInsertIndex = 2
|
||||||
|
|
||||||
private lateinit var highPrecisionTimeMethod: MutableMethod
|
private lateinit var highPrecisionTimeMethod: MutableMethod
|
||||||
|
private var highPrecisionInsertIndex = 0
|
||||||
|
|
||||||
private fun MutableMethod.insert(insert: InsertIndex, register: String, descriptor: String) =
|
private fun MutableMethod.insert(insertIndex: Int, register: String, descriptor: String) =
|
||||||
addInstruction(insert.index, "invoke-static { $register }, $descriptor")
|
addInstruction(insertIndex, "invoke-static { $register }, $descriptor")
|
||||||
|
|
||||||
private fun MutableMethod.insertTimeHook(insert: InsertIndex, descriptor: String) =
|
private fun MutableMethod.insertTimeHook(insertIndex: Int, descriptor: String) =
|
||||||
insert(insert, "p1, p2", descriptor)
|
insert(insertIndex, "p1, p2", descriptor)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook the player controller.
|
* Hook the player controller. Called when a video is opened or the current video is changed.
|
||||||
|
*
|
||||||
|
* Note: This hook is called very early and is called before the video id, video time, video length,
|
||||||
|
* and many other data fields are set.
|
||||||
*
|
*
|
||||||
* @param targetMethodClass The descriptor for the class to invoke when the player controller is created.
|
* @param targetMethodClass The descriptor for the class to invoke when the player controller is created.
|
||||||
* @param targetMethodName The name of the static method to invoke when the player controller is created.
|
* @param targetMethodName The name of the static method to invoke when the player controller is created.
|
||||||
*/
|
*/
|
||||||
internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) =
|
internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) =
|
||||||
playerInitMethod.insert(
|
playerInitMethod.insert(
|
||||||
InsertIndex.CREATE,
|
playerInitInsertIndex++,
|
||||||
"v0",
|
"v0",
|
||||||
"$targetMethodClass->$targetMethodName(Ljava/lang/Object;)V"
|
"$targetMethodClass->$targetMethodName(Ljava/lang/Object;)V"
|
||||||
)
|
)
|
||||||
@@ -191,7 +199,7 @@ class VideoInformationPatch : BytecodePatch(
|
|||||||
*/
|
*/
|
||||||
internal fun videoTimeHook(targetMethodClass: String, targetMethodName: String) =
|
internal fun videoTimeHook(targetMethodClass: String, targetMethodName: String) =
|
||||||
timeMethod.insertTimeHook(
|
timeMethod.insertTimeHook(
|
||||||
InsertIndex.TIME,
|
timeInitInsertIndex++,
|
||||||
"$targetMethodClass->$targetMethodName(J)V"
|
"$targetMethodClass->$targetMethodName(J)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -205,16 +213,10 @@ class VideoInformationPatch : BytecodePatch(
|
|||||||
*/
|
*/
|
||||||
internal fun highPrecisionTimeHook(targetMethodClass: String, targetMethodName: String) =
|
internal fun highPrecisionTimeHook(targetMethodClass: String, targetMethodName: String) =
|
||||||
highPrecisionTimeMethod.insertTimeHook(
|
highPrecisionTimeMethod.insertTimeHook(
|
||||||
InsertIndex.HIGH_PRECISION_TIME,
|
highPrecisionInsertIndex++,
|
||||||
"$targetMethodClass->$targetMethodName(J)V"
|
"$targetMethodClass->$targetMethodName(J)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class InsertIndex(internal val index: Int) {
|
|
||||||
CREATE(4),
|
|
||||||
TIME(2),
|
|
||||||
HIGH_PRECISION_TIME(0),
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) =
|
private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) =
|
||||||
instructions[instructions.indexOfFirst { it.opcode == opcode } + offset].reference
|
instructions[instructions.indexOfFirst { it.opcode == opcode } + offset].reference
|
||||||
|
|
||||||
|
|||||||
@@ -20,16 +20,16 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource
|
|||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch
|
||||||
import app.revanced.patches.youtube.misc.video.quality.annotations.RememberVideoQualityCompatibility
|
import app.revanced.patches.youtube.misc.video.quality.annotations.RememberVideoQualityCompatibility
|
||||||
import app.revanced.patches.youtube.misc.video.quality.fingerprints.SetQualityByIndexMethodClassFieldReferenceFingerprint
|
import app.revanced.patches.youtube.misc.video.quality.fingerprints.SetQualityByIndexMethodClassFieldReferenceFingerprint
|
||||||
import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualityItemOnClickParentFingerprint
|
import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualityItemOnClickParentFingerprint
|
||||||
import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualitySetterFingerprint
|
import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualitySetterFingerprint
|
||||||
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
|
||||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import org.jf.dexlib2.iface.reference.FieldReference
|
import org.jf.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@DependsOn([IntegrationsPatch::class, VideoIdPatch::class, SettingsPatch::class])
|
@DependsOn([IntegrationsPatch::class, VideoInformationPatch::class, SettingsPatch::class])
|
||||||
@Name("remember-video-quality")
|
@Name("remember-video-quality")
|
||||||
@Description("Adds the ability to remember the video quality you chose in the video quality flyout.")
|
@Description("Adds the ability to remember the video quality you chose in the video quality flyout.")
|
||||||
@RememberVideoQualityCompatibility
|
@RememberVideoQualityCompatibility
|
||||||
@@ -114,7 +114,7 @@ class RememberVideoQualityPatch : BytecodePatch(
|
|||||||
* Conveniently, at this point the video quality is overridden to the remembered playback speed.
|
* Conveniently, at this point the video quality is overridden to the remembered playback speed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V")
|
VideoInformationPatch.onCreateHook(INTEGRATIONS_CLASS_DESCRIPTOR, "newVideoStarted")
|
||||||
|
|
||||||
// Inject a call to set the remembered quality once a video loads.
|
// Inject a call to set the remembered quality once a video loads.
|
||||||
VideoQualitySetterFingerprint.result?.also {
|
VideoQualitySetterFingerprint.result?.also {
|
||||||
|
|||||||
@@ -23,12 +23,11 @@ import app.revanced.patches.youtube.misc.video.information.patch.VideoInformatio
|
|||||||
import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch.Companion.reference
|
import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch.Companion.reference
|
||||||
import app.revanced.patches.youtube.misc.video.speed.remember.annotation.RememberPlaybackSpeedCompatibility
|
import app.revanced.patches.youtube.misc.video.speed.remember.annotation.RememberPlaybackSpeedCompatibility
|
||||||
import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint
|
import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint
|
||||||
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@Name("remember-playback-speed")
|
@Name("remember-playback-speed")
|
||||||
@Description("Adds the ability to remember the playback speed you chose in the video playback speed flyout.")
|
@Description("Adds the ability to remember the playback speed you chose in the video playback speed flyout.")
|
||||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoIdPatch::class, VideoInformationPatch::class])
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoInformationPatch::class])
|
||||||
@RememberPlaybackSpeedCompatibility
|
@RememberPlaybackSpeedCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class RememberPlaybackSpeedPatch : BytecodePatch(
|
class RememberPlaybackSpeedPatch : BytecodePatch(
|
||||||
@@ -77,8 +76,7 @@ class RememberPlaybackSpeedPatch : BytecodePatch(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
VideoIdPatch.injectCall("${INTEGRATIONS_CLASS_DESCRIPTOR}->newVideoLoaded(Ljava/lang/String;)V")
|
VideoInformationPatch.onCreateHook(INTEGRATIONS_CLASS_DESCRIPTOR, "newVideoStarted")
|
||||||
|
|
||||||
VideoInformationPatch.userSelectedPlaybackSpeedHook(
|
VideoInformationPatch.userSelectedPlaybackSpeedHook(
|
||||||
INTEGRATIONS_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
|
INTEGRATIONS_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user