diff --git a/.idea/misc.xml b/.idea/misc.xml
index f1854e4b..e086a70c 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,5 +4,5 @@
-
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd011408..bce13d4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,89 @@
+# [2.179.0-dev.12](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.11...v2.179.0-dev.12) (2023-07-01)
+
+
+### Features
+
+* **baconreader:** add `change-oauth-client-id` patch ([#2535](https://github.com/revanced/revanced-patches/issues/2535)) ([6f5e007](https://github.com/revanced/revanced-patches/commit/6f5e007a78dc5e1ed3935a3436ac1de7eb719ea1))
+
+# [2.179.0-dev.11](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.10...v2.179.0-dev.11) (2023-07-01)
+
+# [2.179.0-dev.10](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.9...v2.179.0-dev.10) (2023-06-30)
+
+
+### Features
+
+* **redditisfun/change-oauth-client-id:** add compatibility for paid versions ([#2536](https://github.com/revanced/revanced-patches/issues/2536)) ([e739d2f](https://github.com/revanced/revanced-patches/commit/e739d2fa16bbd0125db82c0758928addbd9950c9))
+
+# [2.179.0-dev.9](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.8...v2.179.0-dev.9) (2023-06-30)
+
+
+### Features
+
+* **redditisfun:** add `change-oauth-client-id` patch ([14809cd](https://github.com/revanced/revanced-patches/commit/14809cd4510ad9514b4a4820187a81681669374c))
+
+# [2.179.0-dev.8](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.7...v2.179.0-dev.8) (2023-06-29)
+
+
+### Features
+
+* **reddit:** add `disable-screenshot-popup` patch ([#2387](https://github.com/revanced/revanced-patches/issues/2387)) ([473e051](https://github.com/revanced/revanced-patches/commit/473e0512314dfa9790cf83b4cfcc7505058d3a51))
+
+# [2.179.0-dev.7](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.6...v2.179.0-dev.7) (2023-06-28)
+
+
+### Bug Fixes
+
+* **youtube:** improve patching speed ([#2514](https://github.com/revanced/revanced-patches/issues/2514)) ([77bb761](https://github.com/revanced/revanced-patches/commit/77bb761b0bb38613ad9d5017c881396afa471558))
+
+# [2.179.0-dev.6](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.5...v2.179.0-dev.6) (2023-06-27)
+
+
+### Bug Fixes
+
+* **syncforreddit/change-oauth-client-id:** add dev edition ([#2516](https://github.com/revanced/revanced-patches/issues/2516)) ([7c7294b](https://github.com/revanced/revanced-patches/commit/7c7294b750f54390dd2308de63cc09545010b17f))
+
+# [2.179.0-dev.5](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.4...v2.179.0-dev.5) (2023-06-27)
+
+
+### Bug Fixes
+
+* **relayforreddit/change-oauth-client-id:** change client id instead of developer key ([#2508](https://github.com/revanced/revanced-patches/issues/2508)) ([4befb44](https://github.com/revanced/revanced-patches/commit/4befb4414638c5936f99d8d63d73c729efc773a5))
+
+# [2.179.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.3...v2.179.0-dev.4) (2023-06-27)
+
+# [2.179.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.2...v2.179.0-dev.3) (2023-06-26)
+
+
+### Bug Fixes
+
+* **enable-android-debugging:** remove json options ([#2497](https://github.com/revanced/revanced-patches/issues/2497)) ([3e25f5f](https://github.com/revanced/revanced-patches/commit/3e25f5f8df24a585dc1097aa16877841f0c6b74a))
+
+# [2.179.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.1...v2.179.0-dev.2) (2023-06-25)
+
+
+### Features
+
+* **relayforreddit:** add `change-oauth-client-id` patch ([#2491](https://github.com/revanced/revanced-patches/issues/2491)) ([fe66f40](https://github.com/revanced/revanced-patches/commit/fe66f4089d6365564c8097d3c7a1bc842c343194))
+
+# [2.179.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.178.1-dev.1...v2.179.0-dev.1) (2023-06-24)
+
+
+### Bug Fixes
+
+* **syncforreddit:** use correct overriding method signature ([#2483](https://github.com/revanced/revanced-patches/issues/2483)) ([f9770cf](https://github.com/revanced/revanced-patches/commit/f9770cf1babce61cd32f6ca9140103419d8d094d))
+
+
+### Features
+
+* **infinityforreddit:** add `change-oauth-client-id` patch ([#2452](https://github.com/revanced/revanced-patches/issues/2452)) ([9efd790](https://github.com/revanced/revanced-patches/commit/9efd7904acc6dc70f45c6c0f835c839473d9205f))
+
+## [2.178.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.178.0...v2.178.1-dev.1) (2023-06-23)
+
+
+### Bug Fixes
+
+* **youtube/client-spoof:** update settings text for known side effects of spoof signature ([#2476](https://github.com/revanced/revanced-patches/issues/2476)) ([6756f80](https://github.com/revanced/revanced-patches/commit/6756f80e3e0c09376a1fd613d28644bdaa24da57))
+
# [2.178.0](https://github.com/revanced/revanced-patches/compare/v2.177.0...v2.178.0) (2023-06-21)
diff --git a/README.md b/README.md
index 9fb2eecf..e68698ef 100644
--- a/README.md
+++ b/README.md
@@ -128,6 +128,17 @@ The official ReVanced Patches.
| `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | 15.4.1 |
+### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `disable-screenshot-popup` | Disables the popup that shows up when taking a screenshot. | all |
+| `hide-ads` | Removes ads from the Reddit. | all |
+| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all |
+| `sanitize-sharing-links` | Removes (tracking) query parameters from the URLs when sharing links. | all |
+
+
### [📦 `com.twitter.android`](https://play.google.com/store/apps/details?id=com.twitter.android)
@@ -149,16 +160,6 @@ The official ReVanced Patches.
| `hide-inbox-ads` | Hides ads in inbox. | all |
-### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage)
-
-
-| 💊 Patch | 📜 Description | 🏹 Target Version |
-|:--------:|:--------------:|:-----------------:|
-| `hide-ads` | Removes ads from the Reddit. | all |
-| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all |
-| `sanitize-sharing-links` | Removes (tracking) query parameters from the URLs when sharing links. | all |
-
-
### [📦 `com.laurencedawson.reddit_sync`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync)
@@ -204,12 +205,60 @@ The official ReVanced Patches.
| `spoof-signature` | Spoofs the signature of the app. | all |
+### [📦 `ml.docilealligator.infinityforreddit`](https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+
+
+### [📦 `free.reddit.news`](https://play.google.com/store/apps/details?id=free.reddit.news)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+
+
+### [📦 `reddit.news`](https://play.google.com/store/apps/details?id=reddit.news)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+
+
+### [📦 `com.onelouder.baconreader`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+
+
### [📦 `com.rubenmayayo.reddit`](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit)
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
-| `change-oauth-client-id` | Changes the OAuth client ID in Boost for Reddit. | all |
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+
+
+### [📦 `com.andrewshu.android.reddit`](https://play.google.com/store/apps/details?id=com.andrewshu.android.reddit)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+
+
+### [📦 `com.andrewshu.android.redditdonation`](https://play.google.com/store/apps/details?id=com.andrewshu.android.redditdonation)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
### [📦 `com.laurencedawson.reddit_sync.pro`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.pro)
@@ -220,6 +269,14 @@ The official ReVanced Patches.
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+### [📦 `com.laurencedawson.reddit_sync.dev`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.dev)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `change-oauth-client-id` | Changes the OAuth client ID. | all |
+
+
### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit)
@@ -236,14 +293,6 @@ The official ReVanced Patches.
| `enable-on-demand` | Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads. | all |
-### [📦 `com.vanced.android.youtube`](https://play.google.com/store/apps/details?id=com.vanced.android.youtube)
-
-
-| 💊 Patch | 📜 Description | 🏹 Target Version |
-|:--------:|:--------------:|:-----------------:|
-| `hide-ads` | Removes general ads. | all |
-
-
### [📦 `com.nis.app`](https://play.google.com/store/apps/details?id=com.nis.app)
@@ -252,6 +301,14 @@ The official ReVanced Patches.
| `hide-ads` | Removes ads from Inshorts. | all |
+### [📦 `com.vanced.android.youtube`](https://play.google.com/store/apps/details?id=com.vanced.android.youtube)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `hide-ads` | Removes general ads. | all |
+
+
### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android)
@@ -340,12 +397,20 @@ The official ReVanced Patches.
| `unlock-prime` | Unlocks Nova Prime and all functions of the app. | all |
-### [📦 `com.candylink.openvpn`](https://play.google.com/store/apps/details?id=com.candylink.openvpn)
+### [📦 `org.totschnig.myexpenses`](https://play.google.com/store/apps/details?id=org.totschnig.myexpenses)
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
-| `unlock-pro` | Unlocks premium features. | all |
+| `unlock-pro` | Unlocks all professional features. | 3.4.9 |
+
+
+### [📦 `ginlemon.iconpackstudio`](https://play.google.com/store/apps/details?id=ginlemon.iconpackstudio)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `unlock-pro` | Unlocks all pro features. | all |
### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator)
@@ -356,7 +421,7 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks pro features. | 4.6377 |
-### [📦 `com.wakdev.apps.nfctools.se`](https://play.google.com/store/apps/details?id=com.wakdev.apps.nfctools.se)
+### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android)
| 💊 Patch | 📜 Description | 🏹 Target Version |
@@ -364,7 +429,15 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks all pro features. | all |
-### [📦 `ginlemon.iconpackstudio`](https://play.google.com/store/apps/details?id=ginlemon.iconpackstudio)
+### [📦 `com.vsco.cam`](https://play.google.com/store/apps/details?id=com.vsco.cam)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `unlock-pro` | Unlocks pro features. | all |
+
+
+### [📦 `com.wakdev.apps.nfctools.se`](https://play.google.com/store/apps/details?id=com.wakdev.apps.nfctools.se)
| 💊 Patch | 📜 Description | 🏹 Target Version |
@@ -380,28 +453,12 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks pro features. | all |
-### [📦 `com.vsco.cam`](https://play.google.com/store/apps/details?id=com.vsco.cam)
+### [📦 `com.candylink.openvpn`](https://play.google.com/store/apps/details?id=com.candylink.openvpn)
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
-| `unlock-pro` | Unlocks pro features. | all |
-
-
-### [📦 `org.totschnig.myexpenses`](https://play.google.com/store/apps/details?id=org.totschnig.myexpenses)
-
-
-| 💊 Patch | 📜 Description | 🏹 Target Version |
-|:--------:|:--------------:|:-----------------:|
-| `unlock-pro` | Unlocks all professional features. | 3.4.9 |
-
-
-### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx)
-
-
-| 💊 Patch | 📜 Description | 🏹 Target Version |
-|:--------:|:--------------:|:-----------------:|
-| `unlock-pro` | Unlocks all pro features. | all |
+| `unlock-pro` | Unlocks premium features. | all |
### [📦 `tv.trakt.trakt`](https://play.google.com/store/apps/details?id=tv.trakt.trakt)
@@ -412,7 +469,7 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks pro features. | all |
-### [📦 `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)
| 💊 Patch | 📜 Description | 🏹 Target Version |
diff --git a/build.gradle.kts b/build.gradle.kts
index 0328d2f2..44d0470c 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -27,7 +27,7 @@ repositories {
}
dependencies {
- implementation("app.revanced:revanced-patcher:11.0.0")
+ implementation("app.revanced:revanced-patcher:11.0.3")
implementation("app.revanced:multidexlib2:2.5.3-a3836654")
// Required for meta
implementation("com.google.code.gson:gson:2.10.1")
diff --git a/gradle.properties b/gradle.properties
index f7590f8d..1a40b4a9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
kotlin.code.style = official
-version = 2.178.0
+version = 2.179.0-dev.12
diff --git a/patches.json b/patches.json
index 9bc89cc0..84267603 100644
--- a/patches.json
+++ b/patches.json
@@ -1 +1 @@
-[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID in Boost for Reddit.","version":"0.0.1","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID.","version":"0.0.1","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[{"key":"debuggable","title":"App debugging","description":"Whether to make the app debuggable on Android.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings","enable-android-debugging"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldQualityLayoutResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]}]
\ No newline at end of file
+[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"auto-claim-channel-points","description":"Automatically claim Channel Points.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID.","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID.","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"free.reddit.news","versions":[]},{"name":"reddit.news","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID.","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.onelouder.baconreader","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID.","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID.","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":[]},{"name":"com.andrewshu.android.redditdonation","versions":[]}]},{"name":"change-oauth-client-id","description":"Changes the OAuth client ID.","version":"0.0.0","excluded":false,"options":[{"key":"client-id","title":"OAuth client ID","description":"The Reddit OAuth client ID.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]},{"name":"com.laurencedawson.reddit_sync.pro","versions":[]},{"name":"com.laurencedawson.reddit_sync.dev","versions":[]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-signature-verification"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-ads","description":"Disables ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["DisablePiracyDetectionPatch"],"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-screenshot-popup","description":"Disables the popup that shows up when taking a screenshot.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"disable-switching-emoji-to-sticker-in-message-input-field","description":"Disables switching from emoji to sticker search mode in message input field","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-typing-indicator","description":"Disables the indicator while typing a message","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"external-downloads","description":"Adds support to download and save YouTube videos using an external app.","version":"0.0.1","excluded":false,"options":[],"dependencies":["external-downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from the Reddit.","version":"0.0.2","excluded":false,"options":[],"dependencies":["hide-subreddit-banner","hide-comment-ads"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-get-premium","HideAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-filter-bar","description":"Hides the filter bar in video feeds.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFilterBarResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-layout-components","description":"Hides general layout components.","version":"0.0.1","excluded":false,"options":[],"dependencies":["LithoFilterPatch","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-load-more-button","description":"Hides the button under videos that loads similar videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["hide-load-more-button-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-player-overlay","description":"Hides the dark background overlay from the player when player controls are visible.","version":"0.0.2","excluded":false,"options":[],"dependencies":["HidePlayerOverlayResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","SeekbarColorBytecodePatch","SeekbarPreferencesPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-shorts-components","description":"Hides components from YouTube Shorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","LithoFilterPatch","HideShortsComponentsResourcePatch","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"navigation-buttons","description":"Adds options to hide or change navigation buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","OldQualityLayoutResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-information","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-badge-tab","description":"Removes the badge tab from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-debugging-detection","description":"Removes the USB and wireless debugging checks.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.scb.phone","versions":[]}]},{"name":"remove-device-restrictions","description":"Removes restrictions from using the app on any device.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":[]}]},{"name":"remove-notification-badge","description":"Removes the red notification badge from the activity tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":[]}]},{"name":"remove-player-controls-background","description":"Removes the background from the video player controls.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":[]}]},{"name":"remove-screen-capture-restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":["remove-screen-capture-restriction-resource-patch"],"compatiblePackages":[]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"sanitize-sharing-links","description":"Removes (tracking) query parameters from the URLs when sharing links.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","EnableSeekbarTappingResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1"]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["litho-color-hook","SeekbarColorBytecodePatch","ThemeResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.20.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.vsco.cam","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.candylink.openvpn","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"tv.trakt.trakt","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"vanced-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"video-speed","description":"Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["custom-video-speed","remember-playback-speed"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35"]}]}]
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/extensions/Extensions.kt b/src/main/kotlin/app/revanced/extensions/Extensions.kt
index df0f5205..e90fbdcf 100644
--- a/src/main/kotlin/app/revanced/extensions/Extensions.kt
+++ b/src/main/kotlin/app/revanced/extensions/Extensions.kt
@@ -57,17 +57,28 @@ internal fun MutableMethod.injectHideViewCall(
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V"
)
-internal fun MutableMethod.findIndexForIdResource(resourceName: String): Int {
+internal fun Method.findIndexForIdResource(resourceName: String): Int {
fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == resourceName
}.id
- val resourceId = getIdResourceId(resourceName)
- return implementation!!.instructions.indexOfFirst {
- if (it.opcode != Opcode.CONST) return@indexOfFirst false
+ return indexOfFirstConstantInstructionValue(getIdResourceId(resourceName))
+}
- val literal = (it as WideLiteralInstruction).wideLiteral
+/**
+ * @return the first constant instruction with the value, or -1 if not found.
+ */
+fun Method.indexOfFirstConstantInstructionValue(constantValue: Long): Int {
+ return implementation?.let {
+ it.instructions.indexOfFirst { instruction ->
+ instruction.opcode == Opcode.CONST && (instruction as WideLiteralInstruction).wideLiteral == constantValue
+ }
+ } ?: -1
+}
- return@indexOfFirst resourceId == literal
- }
-}
\ No newline at end of file
+/**
+ * @return if the method contains a constant with the given value.
+ */
+fun Method.containsConstantInstructionValue(constantValue: Long): Boolean {
+ return indexOfFirstConstantInstructionValue(constantValue) >= 0
+}
diff --git a/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/EnableAndroidDebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/EnableAndroidDebuggingPatch.kt
index 88199d03..af75803d 100644
--- a/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/EnableAndroidDebuggingPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/EnableAndroidDebuggingPatch.kt
@@ -14,29 +14,17 @@ import org.w3c.dom.Element
@Version("0.0.1")
class EnableAndroidDebuggingPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
- if (debuggable == true) {
- context.xmlEditor["AndroidManifest.xml"].use { dom ->
- val applicationNode = dom
- .file
- .getElementsByTagName("application")
- .item(0) as Element
+ context.xmlEditor["AndroidManifest.xml"].use { dom ->
+ val applicationNode = dom
+ .file
+ .getElementsByTagName("application")
+ .item(0) as Element
- // set application as debuggable
- applicationNode.setAttribute("android:debuggable", "true")
- }
+ // set application as debuggable
+ applicationNode.setAttribute("android:debuggable", "true")
}
return PatchResultSuccess()
}
- companion object : OptionsContainer() {
- var debuggable: Boolean? by option(
- PatchOption.BooleanOption(
- key = "debuggable",
- default = false,
- title = "App debugging",
- description = "Whether to make the app debuggable on Android.",
- )
- )
- }
}
diff --git a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt
index f0a26158..3c68e6a3 100644
--- a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt
@@ -1,10 +1,9 @@
package app.revanced.patches.music.misc.androidauto.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
-import app.revanced.patches.music.misc.androidauto.patch.BypassCertificateChecksPatch
-
object CheckCertificateFingerprint : MethodFingerprint(
- "Z",
- strings = listOf("No match") // Unique in combination with boolean return type
+ returnType = "Z",
+ parameters = listOf("Ljava/lang/String;"),
+ strings = listOf("X509", "Failed to get public key.", "Failed to get certificate.")
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt
index 27bc8842..75607e79 100644
--- a/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt
@@ -1,19 +1,21 @@
package app.revanced.patches.reddit.customclients
import android.os.Environment
+import app.revanced.extensions.toErrorResult
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.*
import java.io.File
abstract class AbstractChangeOAuthClientIdPatch(
private val redirectUri: String,
private val options: ChangeOAuthClientIdOptionsContainer,
- private val fingerprint: MethodFingerprint,
-) : BytecodePatch(listOf(fingerprint)) {
+ private val fingerprints: List
+) : BytecodePatch(fingerprints) {
override fun execute(context: BytecodeContext): PatchResult {
if (options.clientId == null) {
- // Test if on Android
+ // Ensure device runs Android.
try {
Class.forName("android.os.Environment")
} catch (e: ClassNotFoundException) {
@@ -36,10 +38,10 @@ abstract class AbstractChangeOAuthClientIdPatch(
}.let { options.clientId = it.readText().trim() }
}
- return fingerprint.patch(context)
+ return fingerprints.map { it.result ?: throw it.toErrorResult() }.patch(context)
}
- abstract fun MethodFingerprint.patch(context: BytecodeContext): PatchResult
+ abstract fun List.patch(context: BytecodeContext): PatchResult
companion object Options {
open class ChangeOAuthClientIdOptionsContainer : OptionsContainer() {
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/ChangeOAuthClientIdPatchAnnotation.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/ChangeOAuthClientIdPatchAnnotation.kt
new file mode 100644
index 00000000..270fc340
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/ChangeOAuthClientIdPatchAnnotation.kt
@@ -0,0 +1,11 @@
+package app.revanced.patches.reddit.customclients
+
+import app.revanced.patcher.annotation.Description
+import app.revanced.patcher.annotation.Name
+import app.revanced.patcher.patch.annotations.Patch
+
+@Target(AnnotationTarget.CLASS)
+@Patch
+@Name("change-oauth-client-id")
+@Description("Changes the OAuth client ID.")
+annotation class ChangeOAuthClientIdPatchAnnotation
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/GetAuthorizationUrlFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/GetAuthorizationUrlFingerprint.kt
new file mode 100644
index 00000000..870d569c
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/GetAuthorizationUrlFingerprint.kt
@@ -0,0 +1,7 @@
+package app.revanced.patches.reddit.customclients.baconreader.api.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+
+object GetAuthorizationUrlFingerprint: MethodFingerprint(
+ strings = listOf("client_id=zACVn0dSFGdWqQ"),
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/GetClientIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/GetClientIdFingerprint.kt
new file mode 100644
index 00000000..8049f362
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/GetClientIdFingerprint.kt
@@ -0,0 +1,12 @@
+package app.revanced.patches.reddit.customclients.baconreader.api.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+
+object GetClientIdFingerprint : MethodFingerprint(
+ strings = listOf("client_id=zACVn0dSFGdWqQ"),
+ customFingerprint = custom@{ methodDef, classDef ->
+ if (!classDef.type.endsWith("RedditOAuth;")) return@custom false
+
+ methodDef.name == "getAuthorizeUrl"
+ }
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/RequestTokenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/RequestTokenFingerprint.kt
new file mode 100644
index 00000000..4e4eddac
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/fingerprints/RequestTokenFingerprint.kt
@@ -0,0 +1,7 @@
+package app.revanced.patches.reddit.customclients.baconreader.api.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+
+object RequestTokenFingerprint : MethodFingerprint(
+ strings = listOf("zACVn0dSFGdWqQ", "kDm2tYpu9DqyWFFyPlNcXGEni4k"), // App ID and secret.
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/patch/ChangeOAuthClientIdPatch.kt
new file mode 100644
index 00000000..e7e65332
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/baconreader/api/patch/ChangeOAuthClientIdPatch.kt
@@ -0,0 +1,47 @@
+package app.revanced.patches.reddit.customclients.baconreader.api.patch
+
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
+import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
+import app.revanced.patches.reddit.customclients.baconreader.api.fingerprints.GetAuthorizationUrlFingerprint
+import app.revanced.patches.reddit.customclients.baconreader.api.fingerprints.RequestTokenFingerprint
+import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
+
+
+@ChangeOAuthClientIdPatchAnnotation
+@Compatibility([Package("com.onelouder.baconreader")])
+class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
+ "http://baconreader.com/auth", Options, listOf(GetAuthorizationUrlFingerprint, RequestTokenFingerprint)
+) {
+
+ override fun List.patch(context: BytecodeContext): PatchResult {
+ fun MethodFingerprintResult.patch(replacementString: String) {
+ val clientIdIndex = scanResult.stringsScanResult!!.matches.first().index
+
+ mutableMethod.apply {
+ val clientIdRegister = getInstruction(clientIdIndex).registerA
+ replaceInstruction(
+ clientIdIndex,
+ "const-string v$clientIdRegister, \"$replacementString\""
+ )
+ }
+ }
+
+ // Patch client id in authorization url.
+ first().patch("client_id=$clientId")
+
+ // Patch client id for access token request.
+ last().patch(clientId!!)
+
+ return PatchResultSuccess()
+ }
+
+ companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
+}
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt
index 1f8004d1..f088f2e3 100644
--- a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt
@@ -1,34 +1,29 @@
package app.revanced.patches.reddit.customclients.boostforreddit.api.patch
-import app.revanced.extensions.toErrorResult
-import app.revanced.patcher.annotation.*
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
-import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
+import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint
-@Patch
-@Name("change-oauth-client-id")
-@Description("Changes the OAuth client ID in Boost for Reddit.")
+@ChangeOAuthClientIdPatchAnnotation
@Compatibility([Package("com.rubenmayayo.reddit")])
-@Version("0.0.1")
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
- "http://rubenmayayo.com",
- Options,
- GetClientIdFingerprint
+ "http://rubenmayayo.com", Options, listOf(GetClientIdFingerprint)
) {
- override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult {
- result?.mutableMethod?.addInstructions(
+ override fun List.patch(context: BytecodeContext): PatchResult {
+ first().mutableMethod.addInstructions(
0,
- """
+ """
const-string v0, "$clientId"
return-object v0
"""
- ) ?: return toErrorResult()
+ )
return PatchResultSuccess()
}
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/AbstractClientIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/AbstractClientIdFingerprint.kt
new file mode 100644
index 00000000..9099dfef
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/AbstractClientIdFingerprint.kt
@@ -0,0 +1,12 @@
+package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+
+abstract class AbstractClientIdFingerprint(classTypeSuffix: String, methodName: String) : MethodFingerprint(
+ strings = listOf("NOe2iKrPPzwscA"),
+ customFingerprint = custom@{ methodDef, classDef ->
+ if (!classDef.type.endsWith(classTypeSuffix)) return@custom false
+
+ methodDef.name == methodName
+ }
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/GetHTTPBasicAuthHeaderFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/GetHTTPBasicAuthHeaderFingerprint.kt
new file mode 100644
index 00000000..3bff5626
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/GetHTTPBasicAuthHeaderFingerprint.kt
@@ -0,0 +1,6 @@
+package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
+
+object GetHTTPBasicAuthHeaderFingerprint : AbstractClientIdFingerprint(
+ "APIUtils;",
+ "getHTTPBasicAuthHeader"
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt
new file mode 100644
index 00000000..740fd318
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt
@@ -0,0 +1,6 @@
+package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
+
+object LoginActivityOnCreateFingerprint : AbstractClientIdFingerprint(
+ "LoginActivity;",
+ "onCreate"
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/patch/ChangeOAuthClientIdPatch.kt
new file mode 100644
index 00000000..36d136b9
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/patch/ChangeOAuthClientIdPatch.kt
@@ -0,0 +1,41 @@
+package app.revanced.patches.reddit.customclients.infinityforreddit.api.patch
+
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
+import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
+import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.GetHTTPBasicAuthHeaderFingerprint
+import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.LoginActivityOnCreateFingerprint
+import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
+
+@ChangeOAuthClientIdPatchAnnotation
+@Compatibility([Package("ml.docilealligator.infinityforreddit")])
+class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
+ "infinity://localhost",
+ Options,
+ listOf(GetHTTPBasicAuthHeaderFingerprint, LoginActivityOnCreateFingerprint)
+) {
+ override fun List.patch(context: BytecodeContext): PatchResult {
+ forEach {
+ val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index
+ it.mutableMethod.apply {
+ val oAuthClientIdRegister = getInstruction(clientIdIndex).registerA
+
+ replaceInstruction(
+ clientIdIndex,
+ "const-string v$oAuthClientIdRegister, \"$clientId\""
+ )
+ }
+ }
+
+ return PatchResultSuccess()
+ }
+
+ companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
+}
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/fingerprints/AbstractClientIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/fingerprints/AbstractClientIdFingerprint.kt
new file mode 100644
index 00000000..fe166b91
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/fingerprints/AbstractClientIdFingerprint.kt
@@ -0,0 +1,7 @@
+package app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+
+abstract class AbstractClientIdFingerprint(string: String) : MethodFingerprint(
+ strings = listOfNotNull("yyOCBp.RHJhDKd", string),
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/fingerprints/BasicAuthorizationFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/fingerprints/BasicAuthorizationFingerprint.kt
new file mode 100644
index 00000000..9e4b3530
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/redditisfun/api/fingerprints/BasicAuthorizationFingerprint.kt
@@ -0,0 +1,5 @@
+package app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints
+
+object BasicAuthorizationFingerprint : AbstractClientIdFingerprint(
+ string = "fJOxVwBUyo*=f:.patch(context: BytecodeContext): PatchResult {
+ /**
+ * Replaces a one register instruction with a const-string instruction
+ * at the index returned by [getReplacementIndex].
+ *
+ * @param string The string to replace the instruction with.
+ * @param getReplacementIndex A function that returns the index of the instruction to replace
+ * using the [StringMatch] list from the [MethodFingerprintResult].
+ */
+ fun MethodFingerprintResult.replaceWith(
+ string: String,
+ getReplacementIndex: List.() -> Int,
+ ) = mutableMethod.apply {
+ val replacementIndex = scanResult.stringsScanResult!!.matches.getReplacementIndex()
+ val clientIdRegister = getInstruction(replacementIndex).registerA
+
+ replaceInstruction(replacementIndex, "const-string v$clientIdRegister, \"$string\"")
+ }
+
+ // Patch OAuth authorization.
+ first().replaceWith(clientId!!) { first().index + 4 }
+
+ // Path basic authorization.
+ last().replaceWith("$clientId:") { last().index + 7 }
+
+ return PatchResultSuccess()
+ }
+
+ companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
+}
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/AbstractClientIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/AbstractClientIdFingerprint.kt
new file mode 100644
index 00000000..8cb5161f
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/AbstractClientIdFingerprint.kt
@@ -0,0 +1,7 @@
+package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+
+abstract class AbstractClientIdFingerprint(string: String) : MethodFingerprint(
+ strings = listOfNotNull("dj-xCIZQYiLbEg", string),
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetLoggedInBearerTokenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetLoggedInBearerTokenFingerprint.kt
new file mode 100644
index 00000000..9ba4ec62
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetLoggedInBearerTokenFingerprint.kt
@@ -0,0 +1,3 @@
+package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
+
+object GetLoggedInBearerTokenFingerprint : AbstractClientIdFingerprint("authorization_code")
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetLoggedOutBearerTokenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetLoggedOutBearerTokenFingerprint.kt
new file mode 100644
index 00000000..74e479c5
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetLoggedOutBearerTokenFingerprint.kt
@@ -0,0 +1,3 @@
+package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
+
+object GetLoggedOutBearerTokenFingerprint : AbstractClientIdFingerprint("https://oauth.reddit.com/grants/installed_client")
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetRefreshTokenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetRefreshTokenFingerprint.kt
new file mode 100644
index 00000000..492a5554
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/GetRefreshTokenFingerprint.kt
@@ -0,0 +1,3 @@
+package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
+
+object GetRefreshTokenFingerprint : AbstractClientIdFingerprint("refresh_token")
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/LoginActivityClientIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/LoginActivityClientIdFingerprint.kt
new file mode 100644
index 00000000..ba260ee1
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/fingerprints/LoginActivityClientIdFingerprint.kt
@@ -0,0 +1,3 @@
+package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
+
+object LoginActivityClientIdFingerprint : AbstractClientIdFingerprint("&duration=permanent")
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/patch/ChangeOAuthClientIdPatch.kt
new file mode 100644
index 00000000..2bdeed0b
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/relayforreddit/api/patch/ChangeOAuthClientIdPatch.kt
@@ -0,0 +1,48 @@
+package app.revanced.patches.reddit.customclients.relayforreddit.api.patch
+
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
+import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
+import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.GetLoggedInBearerTokenFingerprint
+import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.GetLoggedOutBearerTokenFingerprint
+import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.LoginActivityClientIdFingerprint
+import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.GetRefreshTokenFingerprint
+import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
+
+@ChangeOAuthClientIdPatchAnnotation
+@Compatibility([Package("free.reddit.news"), Package("reddit.news")])
+class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
+ "dbrady://relay",
+ Options,
+ listOf(
+ LoginActivityClientIdFingerprint,
+ GetLoggedInBearerTokenFingerprint,
+ GetLoggedOutBearerTokenFingerprint,
+ GetRefreshTokenFingerprint
+ )
+) {
+ override fun List.patch(context: BytecodeContext): PatchResult {
+ forEach {
+ val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index
+ it.mutableMethod.apply {
+ val clientIdRegister = getInstruction(clientIdIndex).registerA
+
+ it.mutableMethod.replaceInstruction(
+ clientIdIndex,
+ "const-string v$clientIdRegister, \"$clientId\""
+ )
+ }
+ }
+
+ return PatchResultSuccess()
+ }
+
+ companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
+}
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt
index e7ceb004..08a3b7da 100644
--- a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt
@@ -1,17 +1,18 @@
package app.revanced.patches.reddit.customclients.syncforreddit.api.patch
import app.revanced.extensions.toErrorResult
-import app.revanced.patcher.annotation.*
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
-import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
+import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetBearerTokenFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@@ -19,47 +20,50 @@ import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.StringReference
import java.util.*
-@Patch
-@Name("change-oauth-client-id")
-@Description("Changes the OAuth client ID.")
-@Compatibility([Package("com.laurencedawson.reddit_sync"), Package("com.laurencedawson.reddit_sync.pro")])
-@Version("0.0.1")
+@ChangeOAuthClientIdPatchAnnotation
+@Compatibility(
+ [
+ Package("com.laurencedawson.reddit_sync"),
+ Package("com.laurencedawson.reddit_sync.pro"),
+ Package("com.laurencedawson.reddit_sync.dev")
+ ]
+)
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
- "http://redditsync/auth",
- Options,
- GetAuthorizationStringFingerprint,
+ "http://redditsync/auth", Options, listOf(GetAuthorizationStringFingerprint)
) {
- override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult {
- result?.also { result ->
- GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
- val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
- addInstructions(
- 0,
- """
+ override fun List.patch(context: BytecodeContext): PatchResult {
+ forEach { fingerprintResult ->
+ fingerprintResult.also { result ->
+ GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
+ val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
+ addInstructions(
+ 0,
+ """
const-string v0, "Basic $auth"
return-object v0
"""
- )
- } ?: return GetBearerTokenFingerprint.toErrorResult()
- }?.let {
- val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index
+ )
+ } ?: return GetBearerTokenFingerprint.toErrorResult()
+ }.let {
+ val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index
- it.mutableMethod.apply {
- val authorizationStringInstruction = getInstruction(occurrenceIndex)
- val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
- val reference = authorizationStringInstruction.reference as StringReference
+ it.mutableMethod.apply {
+ val authorizationStringInstruction = getInstruction(occurrenceIndex)
+ val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
+ val reference = authorizationStringInstruction.reference as StringReference
- val newAuthorizationUrl = reference.string.replace(
- "client_id=.*?&".toRegex(),
- "client_id=$clientId&"
- )
+ val newAuthorizationUrl = reference.string.replace(
+ "client_id=.*?&".toRegex(),
+ "client_id=$clientId&"
+ )
- replaceInstruction(
- occurrenceIndex,
- "const-string v$targetRegister, \"$newAuthorizationUrl\""
- )
+ replaceInstruction(
+ occurrenceIndex,
+ "const-string v$targetRegister, \"$newAuthorizationUrl\""
+ )
+ }
}
- } ?: return toErrorResult()
+ }
return PatchResultSuccess()
}
diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/annotations/DisableScreenshotPopupCompatibility.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/annotations/DisableScreenshotPopupCompatibility.kt
new file mode 100644
index 00000000..d0620b56
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/annotations/DisableScreenshotPopupCompatibility.kt
@@ -0,0 +1,8 @@
+package app.revanced.patches.reddit.layout.disablescreenshotpopup.annotations
+
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
+
+@Compatibility([Package("com.reddit.frontpage")])
+@Target(AnnotationTarget.CLASS)
+internal annotation class DisableScreenshotPopupCompatibility
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/fingerprints/DisableScreenshotPopupFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/fingerprints/DisableScreenshotPopupFingerprint.kt
new file mode 100644
index 00000000..de74945c
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/fingerprints/DisableScreenshotPopupFingerprint.kt
@@ -0,0 +1,14 @@
+package app.revanced.patches.reddit.layout.disablescreenshotpopup.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+
+object DisableScreenshotPopupFingerprint : MethodFingerprint(
+ "V",
+ parameters = listOf("Landroidx/compose/runtime/", "I"),
+ customFingerprint = custom@{ methodDef, classDef ->
+ if (!classDef.type.endsWith("\$ScreenshotTakenBannerKt\$lambda-1\$1;"))
+ return@custom false
+
+ methodDef.name == "invoke"
+ }
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/patch/DisableScreenshotPopupPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/patch/DisableScreenshotPopupPatch.kt
new file mode 100644
index 00000000..6c6c652b
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/reddit/layout/disablescreenshotpopup/patch/DisableScreenshotPopupPatch.kt
@@ -0,0 +1,30 @@
+package app.revanced.patches.reddit.layout.disablescreenshotpopup.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.InstructionExtensions.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.reddit.layout.disablescreenshotpopup.annotations.DisableScreenshotPopupCompatibility
+import app.revanced.patches.reddit.layout.disablescreenshotpopup.fingerprints.DisableScreenshotPopupFingerprint
+
+@Patch
+@Name("disable-screenshot-popup")
+@Description("Disables the popup that shows up when taking a screenshot.")
+@DisableScreenshotPopupCompatibility
+@Version("0.0.1")
+class DisableScreenshotPopupPatch : BytecodePatch(
+ listOf(DisableScreenshotPopupFingerprint)
+) {
+ override fun execute(context: BytecodeContext): PatchResult {
+ DisableScreenshotPopupFingerprint.result?.mutableMethod?.addInstruction(0, "return-void")
+ ?: return DisableScreenshotPopupFingerprint.toErrorResult()
+
+ return PatchResultSuccess()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/patches/scbeasy/detection/debugging/patch/RemoveDebuggingDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/scbeasy/detection/debugging/patch/RemoveDebuggingDetectionPatch.kt
index 5d335f9e..3ece29f9 100644
--- a/src/main/kotlin/app/revanced/patches/scbeasy/detection/debugging/patch/RemoveDebuggingDetectionPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/scbeasy/detection/debugging/patch/RemoveDebuggingDetectionPatch.kt
@@ -4,7 +4,7 @@ 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.InstructionExtensions.addInstructionsWithLabels
+import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
@@ -21,7 +21,7 @@ class RemoveDebuggingDetectionPatch : BytecodePatch(
listOf(DebuggingDetectionFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
- DebuggingDetectionFingerprint.result!!.mutableMethod.addInstructionsWithLabels(
+ DebuggingDetectionFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, 0x0
diff --git a/src/main/kotlin/app/revanced/patches/shared/fingerprints/WatchWhileActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/WatchWhileActivityFingerprint.kt
index eefe790f..9aec2409 100644
--- a/src/main/kotlin/app/revanced/patches/shared/fingerprints/WatchWhileActivityFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/shared/fingerprints/WatchWhileActivityFingerprint.kt
@@ -1,10 +1,13 @@
package app.revanced.patches.shared.fingerprints
-
+import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.AccessFlags
object WatchWhileActivityFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
+ parameters = listOf(),
customFingerprint = { methodDef, _ ->
- methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == ""
+ methodDef.definingClass.endsWith("WatchWhileActivity;")
}
)
diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/fingerprints/CanScrollVerticallyFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/fingerprints/CanScrollVerticallyFingerprint.kt
index 3301d2b3..c5858108 100644
--- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/fingerprints/CanScrollVerticallyFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/fingerprints/CanScrollVerticallyFingerprint.kt
@@ -1,11 +1,14 @@
package app.revanced.patches.shared.misc.fix.verticalscroll.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 CanScrollVerticallyFingerprint : MethodFingerprint(
- "Z",
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "Z",
parameters = emptyList(),
opcodes = listOf(
Opcode.MOVE_RESULT,
diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/resource/patch/AbstractSettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/settings/resource/patch/AbstractSettingsResourcePatch.kt
index 41ff3739..a86ed1be 100644
--- a/src/main/kotlin/app/revanced/patches/shared/settings/resource/patch/AbstractSettingsResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/shared/settings/resource/patch/AbstractSettingsResourcePatch.kt
@@ -14,6 +14,7 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources
import org.w3c.dom.Node
+import java.io.Closeable
/**
* Abstract settings resource patch
@@ -24,7 +25,7 @@ import org.w3c.dom.Node
abstract class AbstractSettingsResourcePatch(
private val preferenceFileName: String,
private val sourceDirectory: String,
-) : ResourcePatch {
+) : ResourcePatch, Closeable {
override fun execute(context: ResourceContext): PatchResult {
/*
* used for self-restart
diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/patch/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/patch/SettingsPatch.kt
index 8b60e9fd..c4a134f8 100644
--- a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/patch/SettingsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/patch/SettingsPatch.kt
@@ -53,6 +53,7 @@ class SettingsPatch : BytecodePatch(
} - 6
+ // fixme: instead use Method.indexOfFirstConstantInstructionValue()
val copyrightPolicyIndex = instructions.indexOfFirst {
(it as? WideLiteralInstruction)?.wideLiteral == copyrightPolicyLabelId
} + 2
diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/bytecode/patch/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/bytecode/patch/SettingsPatch.kt
index 767b5c8e..18b2386b 100644
--- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/bytecode/patch/SettingsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/bytecode/patch/SettingsPatch.kt
@@ -29,6 +29,7 @@ import app.revanced.patches.twitch.misc.settings.fingerprints.SettingsMenuItemEn
import app.revanced.patches.twitch.misc.settings.resource.patch.SettingsResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.immutable.ImmutableField
+import java.io.Closeable
@Patch
@DependsOn([IntegrationsPatch::class, SettingsResourcePatch::class])
@@ -43,7 +44,7 @@ class SettingsPatch : BytecodePatch(
MenuGroupsUpdatedFingerprint,
MenuGroupsOnClickFingerprint
)
-) {
+), Closeable {
override fun execute(context: BytecodeContext): PatchResult {
// Hook onCreate to handle fragment creation
SettingsActivityOnCreateFingerprint.result?.apply {
diff --git a/src/main/kotlin/app/revanced/patches/vsco/misc/pro/patch/UnlockProPatch.kt b/src/main/kotlin/app/revanced/patches/vsco/misc/pro/patch/UnlockProPatch.kt
index e58773e9..67e6fe1d 100644
--- a/src/main/kotlin/app/revanced/patches/vsco/misc/pro/patch/UnlockProPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/vsco/misc/pro/patch/UnlockProPatch.kt
@@ -3,7 +3,7 @@ package app.revanced.patches.vsco.misc.pro.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.*
import app.revanced.patcher.data.BytecodeContext
-import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
+import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
@@ -22,7 +22,7 @@ class UnlockProPatch : BytecodePatch(
override fun execute(context: BytecodeContext): PatchResult {
RevCatSubscriptionFingerprint.result?.mutableMethod?.apply {
// Set isSubscribed to true.
- addInstructionsWithLabels(
+ addInstruction(
0,
"""
const p1, 0x1
diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt
index 18af00c4..0f32e3e6 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt
@@ -1,9 +1,14 @@
package app.revanced.patches.youtube.ad.getpremium.bytecode.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 GetPremiumViewFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf("I", "I"),
opcodes = listOf(
Opcode.ADD_INT_2ADDR,
Opcode.ADD_INT_2ADDR,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/AccessibilityPlayerProgressTimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/AccessibilityPlayerProgressTimeFingerprint.kt
index d6d0653a..8b2f5243 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/AccessibilityPlayerProgressTimeFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/AccessibilityPlayerProgressTimeFingerprint.kt
@@ -1,23 +1,12 @@
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.interaction.seekbar.patch.EnableSeekbarTappingResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
-import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-
-object AccessibilityPlayerProgressTimeFingerprint : MethodFingerprint(
+object AccessibilityPlayerProgressTimeFingerprint : LiteralValueFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- if (instruction.opcode != Opcode.CONST) return@any false
-
- val wideLiteral = (instruction as WideLiteralInstruction).wideLiteral
-
- EnableSeekbarTappingResourcePatch.accessibilityPlayerProgressTime == wideLiteral
- } ?: false
- }
+ literal = EnableSeekbarTappingResourcePatch.accessibilityPlayerProgressTime
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/fingerprints/SwipeControlsHostActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/fingerprints/SwipeControlsHostActivityFingerprint.kt
index 368ba1fd..ad6de5cc 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/fingerprints/SwipeControlsHostActivityFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/fingerprints/SwipeControlsHostActivityFingerprint.kt
@@ -1,10 +1,13 @@
package app.revanced.patches.youtube.interaction.swipecontrols.fingerprints
-
+import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.AccessFlags
object SwipeControlsHostActivityFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
+ parameters = listOf(),
customFingerprint = { methodDef, _ ->
- methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;" && methodDef.name == ""
+ methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;"
}
)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt
index e65c2b74..1b1cd108 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt
@@ -1,13 +1,10 @@
package app.revanced.patches.youtube.layout.autocaptions.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-
-@FuzzyPatternScanMethod(3)
object StartVideoInformerFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_STATIC,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt
index d42965f7..48d98f4f 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt
@@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object SubtitleButtonControllerFingerprint : MethodFingerprint(
- "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
+ returnType = "V",
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ parameters = listOf("Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleTrack;"),
+ opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.RETURN_VOID,
@@ -16,5 +19,8 @@ object SubtitleButtonControllerFingerprint : MethodFingerprint(
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
- )
+ ),
+ customFingerprint = { methodDef, _ ->
+ methodDef.definingClass.endsWith("SubtitleButtonController;")
+ }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt
index a011e60c..66ac4f61 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt
@@ -14,5 +14,8 @@ object SubtitleTrackFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT,
Opcode.RETURN,
),
- strings = listOf("DISABLE_CAPTIONS_OPTION")
+ strings = listOf("DISABLE_CAPTIONS_OPTION"),
+ customFingerprint = { methodDef, _ ->
+ methodDef.definingClass.endsWith("SubtitleTrack;")
+ }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt
index 788c3b3d..007d97e5 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt
@@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.buttons.autoplay.patch
+import app.revanced.extensions.findIndexForIdResource
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
@@ -23,7 +24,6 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.reference.MethodReference
@Patch
@@ -48,15 +48,8 @@ class HideAutoplayButtonPatch : BytecodePatch(
LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions
- // resolve the offsets such as ...
- val autoNavPreviewStubId = ResourceMappingPatch.resourceMappings.single {
- it.name == "autonav_preview_stub"
- }.id
-
- // where to insert the branch instructions and ...
- val insertIndex = layoutGenMethodInstructions.indexOfFirst {
- (it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId
- }
+ // resolve the offsets of where to insert the branch instructions and ...
+ val insertIndex = findIndexForIdResource("autonav_preview_stub")
// where to branch away
val branchIndex =
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt
index 33d38404..1b224115 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt
@@ -1,15 +1,13 @@
package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.buttons.navigation.patch.ResolvePivotBarFingerprintsPatch
-import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
+import app.revanced.util.patch.LiteralValueFingerprint
+import org.jf.dexlib2.AccessFlags
-object InitializeButtonsFingerprint : MethodFingerprint(
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any {
- it.opcode == Opcode.CONST && (it as WideLiteralInstruction).wideLiteral ==
- ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId
- } == true
- }
+object InitializeButtonsFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf(),
+ literal = ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/fingerprints/PlayerControlsVisibilityModelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/fingerprints/PlayerControlsVisibilityModelFingerprint.kt
index 37f90e60..bf9d48e4 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/fingerprints/PlayerControlsVisibilityModelFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/fingerprints/PlayerControlsVisibilityModelFingerprint.kt
@@ -5,5 +5,5 @@ import org.jf.dexlib2.Opcode
object PlayerControlsVisibilityModelFingerprint : MethodFingerprint(
opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE),
- strings = listOf("hasNext", "hasPrevious", "Missing required properties:")
+ strings = listOf("Missing required properties:", "hasNext", "hasPrevious")
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/fingerprints/AlbumCardsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/fingerprints/AlbumCardsFingerprint.kt
index 9382220c..6d8cad5c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/fingerprints/AlbumCardsFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/fingerprints/AlbumCardsFingerprint.kt
@@ -1,11 +1,13 @@
package app.revanced.patches.youtube.layout.hide.albumcards.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.albumcards.resource.patch.AlbumCardsResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object AlbumCardsFingerprint : MethodFingerprint(
+object AlbumCardsFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST,
@@ -14,10 +16,5 @@ object AlbumCardsFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == AlbumCardsResourcePatch.albumCardId
- } == true
- }
+ literal = AlbumCardsResourcePatch.albumCardId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt
index eb54fbdb..16ae7019 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt
@@ -1,11 +1,13 @@
package app.revanced.patches.youtube.layout.hide.breakingnews.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch.BreakingNewsResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object BreakingNewsFingerprint : MethodFingerprint(
+object BreakingNewsFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
@@ -14,10 +16,5 @@ object BreakingNewsFingerprint : MethodFingerprint(
Opcode.CHECK_CAST,
Opcode.IPUT_OBJECT,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == BreakingNewsResourcePatch.horizontalCardListId
- } == true
- }
+ literal = BreakingNewsResourcePatch.horizontalCardListId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt
index 1ed36722..30dc121c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt
@@ -1,20 +1,17 @@
package app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object CrowdfundingBoxFingerprint : MethodFingerprint(
+object CrowdfundingBoxFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == CrowdfundingBoxResourcePatch.crowdfundingBoxId
- } == true
- }
+ literal = CrowdfundingBoxResourcePatch.crowdfundingBoxId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutCircleFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutCircleFingerprint.kt
index 55521394..5469dc11 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutCircleFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutCircleFingerprint.kt
@@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object LayoutCircleFingerprint : MethodFingerprint(
+object LayoutCircleFingerprint : LiteralValueFingerprint(
+ returnType = "Landroid/view/View;",
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
@@ -13,10 +13,5 @@ object LayoutCircleFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutCircle
- } == true
- }
+ literal = HideEndscreenCardsResourcePatch.layoutCircle
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutIconFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutIconFingerprint.kt
index 603bebdd..90350f4c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutIconFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutIconFingerprint.kt
@@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object LayoutIconFingerprint : MethodFingerprint(
+object LayoutIconFingerprint : LiteralValueFingerprint(
+ returnType = "Landroid/view/View;",
opcodes = listOf(
Opcode.CONST_4,
Opcode.CONST,
@@ -13,10 +13,5 @@ object LayoutIconFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutIcon
- } == true
- }
+ literal = HideEndscreenCardsResourcePatch.layoutIcon
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutVideoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutVideoFingerprint.kt
index 01307ad6..22c9b07b 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutVideoFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutVideoFingerprint.kt
@@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object LayoutVideoFingerprint : MethodFingerprint(
+object LayoutVideoFingerprint : LiteralValueFingerprint(
+ returnType = "Landroid/view/View;",
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
@@ -13,10 +13,5 @@ object LayoutVideoFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutVideo
- } == true
- }
+ literal = HideEndscreenCardsResourcePatch.layoutVideo
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/FilterBarHeightFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/FilterBarHeightFingerprint.kt
index 6178c4c8..7307754d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/FilterBarHeightFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/FilterBarHeightFingerprint.kt
@@ -1,14 +1,19 @@
package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
-import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch.Companion.filterBarHeightId
+import app.revanced.patcher.extensions.or
+import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-object FilterBarHeightFingerprint : LiteralOpcodesFingerprint(
+object FilterBarHeightFingerprint : LiteralValueFingerprint(
+ returnType = "V",
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IPUT
),
- filterBarHeightId
+ literal = HideFilterBarResourcePatch.filterBarHeightId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/LiteralOpcodesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/LiteralOpcodesFingerprint.kt
deleted file mode 100644
index 3189e17e..00000000
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/LiteralOpcodesFingerprint.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
-
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
-import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-
-
-abstract class LiteralOpcodesFingerprint(opcodes: List, literal: Long) : MethodFingerprint(
- opcodes = opcodes,
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- if (instruction.opcode != Opcode.CONST) return@any false
-
- val wideLiteral = (instruction as WideLiteralInstruction).wideLiteral
-
- literal == wideLiteral
- } ?: false
- }
-)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/RelatedChipCloudFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/RelatedChipCloudFingerprint.kt
index be0ef5ce..a5d47dbd 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/RelatedChipCloudFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/RelatedChipCloudFingerprint.kt
@@ -1,13 +1,18 @@
package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
-import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch.Companion.relatedChipCloudMarginId
+import app.revanced.patcher.extensions.or
+import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-object RelatedChipCloudFingerprint : LiteralOpcodesFingerprint(
+object RelatedChipCloudFingerprint : LiteralValueFingerprint(
+ returnType = "V",
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT
),
- relatedChipCloudMarginId
+ literal = HideFilterBarResourcePatch.relatedChipCloudMarginId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/SearchResultsChipBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/SearchResultsChipBarFingerprint.kt
index 82deee68..9dc8f935 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/SearchResultsChipBarFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/fingerprints/SearchResultsChipBarFingerprint.kt
@@ -1,9 +1,14 @@
package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
-import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch.Companion.barContainerHeightId
+import app.revanced.patcher.extensions.or
+import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch
+import app.revanced.util.patch.LiteralValueFingerprint
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-object SearchResultsChipBarFingerprint : LiteralOpcodesFingerprint(
+object SearchResultsChipBarFingerprint : LiteralValueFingerprint(
+ returnType = "V",
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
@@ -11,5 +16,5 @@ object SearchResultsChipBarFingerprint : LiteralOpcodesFingerprint(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT
),
- barContainerHeightId
+ literal = HideFilterBarResourcePatch.barContainerHeightId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/fingerprints/ShowFloatingMicrophoneButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/fingerprints/ShowFloatingMicrophoneButtonFingerprint.kt
index 276cfbe4..b471d647 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/fingerprints/ShowFloatingMicrophoneButtonFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/fingerprints/ShowFloatingMicrophoneButtonFingerprint.kt
@@ -1,19 +1,19 @@
package app.revanced.patches.youtube.layout.hide.floatingmicrophone.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.floatingmicrophone.patch.HideFloatingMicrophoneButtonResourcePatch
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object ShowFloatingMicrophoneButtonFingerprint : MethodFingerprint(
+object ShowFloatingMicrophoneButtonFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf(),
opcodes = listOf(
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ,
Opcode.RETURN_VOID
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any {
- (it as? WideLiteralInstruction)?.wideLiteral == HideFloatingMicrophoneButtonResourcePatch.fabButtonId
- } == true
- }
+ literal = HideFloatingMicrophoneButtonResourcePatch.fabButtonId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoFingerprint.kt
index 1c5d3d54..d59f8bff 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoFingerprint.kt
@@ -5,7 +5,8 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object InfocardsIncognitoFingerprint : MethodFingerprint(
- "Ljava/lang/Boolean;",
- AccessFlags.PUBLIC or AccessFlags.FINAL,
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "Ljava/lang/Boolean;",
+ parameters = listOf("L", "J"),
strings = listOf("vibrator")
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsMethodCallFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsMethodCallFingerprint.kt
index 08f9ed02..48bef700 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsMethodCallFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsMethodCallFingerprint.kt
@@ -1,19 +1,15 @@
package app.revanced.patches.youtube.layout.hide.infocards.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.infocards.resource.patch.HideInfocardsResourcePatch
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object InfocardsMethodCallFingerprint : MethodFingerprint(
+object InfocardsMethodCallFingerprint : LiteralValueFingerprint(
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- (instruction as? WideLiteralInstruction)?.wideLiteral == HideInfocardsResourcePatch.drawerResourceId
- } == true
- }
+ strings = listOf("Missing ControlsOverlayPresenter for InfoCards to work."),
+ literal = HideInfocardsResourcePatch.drawerResourceId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/bytecode/fingerprints/HideLoadMoreButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/bytecode/fingerprints/HideLoadMoreButtonFingerprint.kt
index 2669411e..8a01d222 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/bytecode/fingerprints/HideLoadMoreButtonFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/bytecode/fingerprints/HideLoadMoreButtonFingerprint.kt
@@ -1,13 +1,12 @@
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.util.patch.LiteralValueFingerprint
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(
+object HideLoadMoreButtonFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L", "L", "L", "L"),
@@ -17,13 +16,5 @@ object HideLoadMoreButtonFingerprint : MethodFingerprint(
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
- }
+ literal = HideLoadMoreButtonResourcePatch.expandButtonDownId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt
index 4597c4da..372c21c5 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt
@@ -1,11 +1,12 @@
package app.revanced.patches.youtube.layout.hide.personalinformation.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch.HideEmailAddressResourcePatch
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object AccountSwitcherAccessibilityLabelFingerprint : MethodFingerprint(
+object AccountSwitcherAccessibilityLabelFingerprint : LiteralValueFingerprint(
+ returnType = "V",
+ parameters = listOf("L", "Ljava/lang/Object;"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
@@ -15,10 +16,5 @@ object AccountSwitcherAccessibilityLabelFingerprint : MethodFingerprint(
Opcode.APUT_OBJECT,
Opcode.CONST,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == HideEmailAddressResourcePatch.accountSwitcherAccessibilityLabelId
- } == true
- }
+ literal = HideEmailAddressResourcePatch.accountSwitcherAccessibilityLabelId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt
index f235b62e..c22588a2 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/fingerprints/CreatePlayerOverviewFingerprint.kt
@@ -1,13 +1,12 @@
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.util.patch.LiteralValueFingerprint
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(
+object CreatePlayerOverviewFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
opcodes = listOf(
@@ -16,13 +15,5 @@ object CreatePlayerOverviewFingerprint : MethodFingerprint(
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
- }
+ literal = HidePlayerOverlayResourcePatch.scrimOverlayId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/patch/HidePlayerOverlayPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/patch/HidePlayerOverlayPatch.kt
index a0170c0e..ab231034 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/patch/HidePlayerOverlayPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/bytecode/patch/HidePlayerOverlayPatch.kt
@@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.patch
+import app.revanced.extensions.indexOfFirstConstantInstructionValue
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
@@ -16,7 +17,6 @@ import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HideP
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")
@@ -28,11 +28,8 @@ class HidePlayerOverlayPatch : BytecodePatch(listOf(CreatePlayerOverviewFingerpr
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 viewRegisterIndex =
+ indexOfFirstConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId) + 3
val viewRegister = getInstruction(viewRegisterIndex).registerA
val insertIndex = viewRegisterIndex + 1
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt
index 2f99a2f0..282737f7 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt
@@ -1,19 +1,13 @@
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
-import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
+import org.jf.dexlib2.AccessFlags
-object CreateShortsButtonsFingerprint : MethodFingerprint(
+object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
+ returnType = "V",
parameters = listOf("Z", "Z", "L"),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any {
- if (it.opcode != Opcode.CONST) return@any false
-
- val literal = (it as WideLiteralInstruction).wideLiteral
-
- literal == HideShortsComponentsResourcePatch.reelPlayerRightLargeIconSize
- } ?: false
- }
+ literal = HideShortsComponentsResourcePatch.reelPlayerRightLargeIconSize
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt
index 2d6836b2..467fa3c1 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt
@@ -1,19 +1,13 @@
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object ReelConstructorFingerprint : MethodFingerprint(
+object ReelConstructorFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(Opcode.INVOKE_VIRTUAL),
- customFingerprint = { method, _ ->
- method.implementation?.instructions?.any {
- if (it.opcode != Opcode.CONST) return@any false
-
- val literal = (it as WideLiteralInstruction).wideLiteral
-
- literal == HideShortsComponentsResourcePatch.reelMultipleItemShelfId
- } ?: false
- }
+ literal = HideShortsComponentsResourcePatch.reelMultipleItemShelfId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/fingerprints/TimeCounterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/fingerprints/TimeCounterFingerprint.kt
index d230e542..2f43eb0a 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/fingerprints/TimeCounterFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/fingerprints/TimeCounterFingerprint.kt
@@ -1,25 +1,28 @@
package app.revanced.patches.youtube.layout.hide.time.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-
-@FuzzyPatternScanMethod(3)
object TimeCounterFingerprint : MethodFingerprint(
- "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ parameters = listOf(),
+ returnType = "V",
+ opcodes = listOf(
+ Opcode.SUB_LONG_2ADDR,
+ Opcode.INVOKE_STATIC,
+ Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_WIDE,
- Opcode.CONST_WIDE_16,
- Opcode.CMP_LONG,
- Opcode.IF_LEZ,
- Opcode.IGET_OBJECT,
- Opcode.IF_EQZ,
- Opcode.INVOKE_VIRTUAL,
- Opcode.MOVE_RESULT,
- Opcode.IF_EQZ,
- Opcode.GOTO,
- )
+ Opcode.INVOKE_STATIC,
+ Opcode.MOVE_RESULT_OBJECT,
+ Opcode.INVOKE_INTERFACE,
+ Opcode.RETURN_VOID,
+ ),
+ customFingerprint = { _, classDef ->
+ // On older devices this fingerprint resolves very slowly.
+ // Speed this up by checking for the number of methods.
+ classDef.methods.count() == 14
+ }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/patch/HideTimestampPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/patch/HideTimestampPatch.kt
index bb7270d5..8206e936 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/patch/HideTimestampPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/patch/HideTimestampPatch.kt
@@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.hide.time.patch
+import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
@@ -38,7 +39,8 @@ class HideTimestampPatch : BytecodePatch(
)
)
- TimeCounterFingerprint.result!!.mutableMethod.addInstructionsWithLabels(
+ TimeCounterFingerprint.result?.apply {
+ mutableMethod.addInstructionsWithLabels(
0,
"""
invoke-static { }, Lapp/revanced/integrations/patches/HideTimestampPatch;->hideTimestamp()Z
@@ -48,7 +50,8 @@ class HideTimestampPatch : BytecodePatch(
:hide_time
nop
"""
- )
+ )
+ } ?: return TimeCounterFingerprint.toErrorResult()
return PatchResultSuccess()
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderParentFingerprint.kt
index 601e62b8..9a1bb421 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderParentFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderParentFingerprint.kt
@@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
-
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object FullscreenViewAdderParentFingerprint : MethodFingerprint(
- parameters = listOf("L", "L"),
+ returnType = "V",
+ parameters = listOf("Landroid/content/Context;", "Landroid/view/View;"),
opcodes = listOf(
Opcode.GOTO,
Opcode.IGET_BOOLEAN,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/fingerprints/EngagementPanelControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/fingerprints/EngagementPanelControllerFingerprint.kt
index a45ae609..a2c94e6f 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/fingerprints/EngagementPanelControllerFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/fingerprints/EngagementPanelControllerFingerprint.kt
@@ -1,12 +1,9 @@
package app.revanced.patches.youtube.layout.panels.popup.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
-
-@FuzzyPatternScanMethod(3)
object EngagementPanelControllerFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt
index 7fe76816..3ac14b34 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt
@@ -1,13 +1,12 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch.ReturnYouTubeDislikeResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object DislikesOldLayoutTextViewFingerprint : MethodFingerprint(
+object DislikesOldLayoutTextViewFingerprint : LiteralValueFingerprint(
returnType = "V",
parameters = listOf("L"),
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
@@ -19,10 +18,5 @@ object DislikesOldLayoutTextViewFingerprint : MethodFingerprint(
Opcode.IF_NEZ, // textview register
Opcode.GOTO,
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == ReturnYouTubeDislikeResourcePatch.oldUIDislikeId
- } == true
- }
+ literal = ReturnYouTubeDislikeResourcePatch.oldUIDislikeId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextViewFingerprint.kt
index 9d5c2ec2..1c78732d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextViewFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextViewFingerprint.kt
@@ -1,9 +1,12 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.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 ShortsTextViewFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L", "L"),
opcodes = listOf(
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/SetWordmarkHeaderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/SetWordmarkHeaderFingerprint.kt
index f0a82339..836b1aa8 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/SetWordmarkHeaderFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/SetWordmarkHeaderFingerprint.kt
@@ -6,7 +6,9 @@ import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object SetWordmarkHeaderFingerprint : MethodFingerprint(
- "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"),
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf("Landroid/widget/ImageView;"),
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
@@ -17,6 +19,5 @@ object SetWordmarkHeaderFingerprint : MethodFingerprint(
Opcode.IGET_OBJECT,
Opcode.CONST,
Opcode.INVOKE_STATIC,
- ),
- customFingerprint = { methodDef, _ -> methodDef.parameterTypes.first() == "Landroid/widget/ImageView;" }
+ )
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/CreateDarkThemeSeekbarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/CreateDarkThemeSeekbarFingerprint.kt
index 89aec9b6..9c8b32ff 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/CreateDarkThemeSeekbarFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/CreateDarkThemeSeekbarFingerprint.kt
@@ -1,15 +1,15 @@
package app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints
+import app.revanced.extensions.containsConstantInstructionValue
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
-import app.revanced.util.patch.indexOfFirstConstantInstruction
import org.jf.dexlib2.AccessFlags
object CreateDarkThemeSeekbarFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { method, _ ->
- method.indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) != -1
- && method.indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) != -1
+ method.containsConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId)
+ && method.containsConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId)
}
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/SetSeekbarClickedColorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/SetSeekbarClickedColorFingerprint.kt
index abae290d..1ebccca7 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/SetSeekbarClickedColorFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/fingerprints/SetSeekbarClickedColorFingerprint.kt
@@ -5,5 +5,8 @@ import org.jf.dexlib2.Opcode
object SetSeekbarClickedColorFingerprint : MethodFingerprint(
opcodes = listOf(Opcode.CONST_HIGH16),
- strings = listOf("YOUTUBE", "PREROLL", "POSTROLL")
+ strings = listOf("YOUTUBE", "PREROLL", "POSTROLL"),
+ customFingerprint = { methodDef, _ ->
+ methodDef.definingClass.endsWith("ControlsOverlayStyle;")
+ }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/patch/SeekbarColorBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/patch/SeekbarColorBytecodePatch.kt
index e57079a1..ad577357 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/patch/SeekbarColorBytecodePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/bytecode/patch/SeekbarColorBytecodePatch.kt
@@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.seekbar.bytecode.patch
+import app.revanced.extensions.indexOfFirstConstantInstructionValue
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
@@ -19,7 +20,6 @@ import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResource
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch.Companion.lithoColorOverrideHook
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
-import app.revanced.util.patch.indexOfFirstConstantInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
@@ -32,7 +32,7 @@ class SeekbarColorBytecodePatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext): PatchResult {
CreateDarkThemeSeekbarFingerprint.result?.mutableMethod?.apply {
- var registerIndex = indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) + 2
+ var registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) + 2
var colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA
addInstructions(
registerIndex + 1,
@@ -42,7 +42,7 @@ class SeekbarColorBytecodePatch : BytecodePatch(
"""
)
- registerIndex = indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) + 2
+ registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) + 2
colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA
addInstructions(
registerIndex + 1,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/AppendTimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/AppendTimeFingerprint.kt
index 2c6d4720..950c7460 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/AppendTimeFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/AppendTimeFingerprint.kt
@@ -8,7 +8,7 @@ import org.jf.dexlib2.Opcode
object AppendTimeFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
- listOf("L", "L", "L"),
+ listOf("Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;"),
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt
deleted file mode 100644
index 24765524..00000000
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
-
-import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
-import org.jf.dexlib2.AccessFlags
-import org.jf.dexlib2.Opcode
-
-
-@FuzzyPatternScanMethod(2)
-object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint(
- "V",
- AccessFlags.PUBLIC or AccessFlags.FINAL,
- listOf("L"),
- listOf(
- Opcode.INVOKE_DIRECT,
- Opcode.MOVE_RESULT,
- Opcode.IF_NEZ,
- Opcode.FLOAT_TO_DOUBLE,
- Opcode.CONST_WIDE_HIGH16,
- Opcode.CMPL_DOUBLE,
- )
-)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorParentFingerprint.kt
new file mode 100644
index 00000000..735c5546
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorParentFingerprint.kt
@@ -0,0 +1,23 @@
+package app.revanced.patches.youtube.layout.tabletminiplayer.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 MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf("F"),
+ opcodes = listOf(
+ Opcode.CONST_HIGH16,
+ Opcode.ADD_FLOAT_2ADDR,
+ Opcode.MUL_FLOAT,
+ Opcode.CONST_4,
+ Opcode.INVOKE_STATIC,
+ Opcode.MOVE_RESULT,
+ Opcode.FLOAT_TO_INT,
+ Opcode.INVOKE_INTERFACE,
+ Opcode.RETURN_VOID,
+ )
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt
index e4777c4c..45cede93 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt
@@ -8,7 +8,7 @@ import org.jf.dexlib2.Opcode
object MiniPlayerResponseModelSizeCheckFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.FINAL,
- listOf("L", "L"),
+ listOf("Ljava/lang/Object;", "Ljava/lang/Object;"),
listOf(
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt
index 0fdc1bcc..70c06eeb 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt
@@ -32,7 +32,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Version("0.0.1")
class TabletMiniPlayerPatch : BytecodePatch(
listOf(
- MiniPlayerDimensionsCalculatorFingerprint,
+ MiniPlayerDimensionsCalculatorParentFingerprint,
MiniPlayerResponseModelSizeCheckFingerprint,
MiniPlayerOverrideParentFingerprint
)
@@ -48,7 +48,8 @@ class TabletMiniPlayerPatch : BytecodePatch(
)
// First resolve the fingerprints via the parent fingerprint.
- val miniPlayerClass = MiniPlayerDimensionsCalculatorFingerprint.result!!.classDef
+ MiniPlayerDimensionsCalculatorParentFingerprint.result ?: return MiniPlayerDimensionsCalculatorParentFingerprint.toErrorResult()
+ val miniPlayerClass = MiniPlayerDimensionsCalculatorParentFingerprint.result!!.classDef
/*
* No context parameter method.
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/bytecode/fingerprints/LithoThemeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/bytecode/fingerprints/LithoThemeFingerprint.kt
index ffb29604..70d9f9ea 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/bytecode/fingerprints/LithoThemeFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/bytecode/fingerprints/LithoThemeFingerprint.kt
@@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object LithoThemeFingerprint : MethodFingerprint(
- "V", AccessFlags.PROTECTED or AccessFlags.FINAL, listOf("L"), listOf(
+ returnType = "V",
+ accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
+ parameters = listOf("Landroid/graphics/Rect;"),
+ opcodes = listOf(
Opcode.APUT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
@@ -22,5 +25,8 @@ object LithoThemeFingerprint : MethodFingerprint(
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
- )
+ ),
+ customFingerprint = { methodDef, _ ->
+ methodDef.name == "onBoundsChange"
+ }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt
index d5f27945..c26dfa59 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt
@@ -9,7 +9,6 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
-import app.revanced.patches.all.misc.debugging.patch.EnableAndroidDebuggingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.debugging.annotations.DebuggingCompatibility
@@ -18,7 +17,7 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Patch
@Name("enable-debugging")
-@DependsOn([IntegrationsPatch::class, SettingsPatch::class, EnableAndroidDebuggingPatch::class])
+@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Description("Adds debugging options.")
@DebuggingCompatibility
@Version("0.0.2")
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/OnBackPressedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/OnBackPressedFingerprint.kt
index 06f03939..52fee3be 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/OnBackPressedFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/OnBackPressedFingerprint.kt
@@ -1,9 +1,13 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.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 OnBackPressedFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
opcodes = listOf(
Opcode.RETURN_VOID
),
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewScrollingFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewScrollingFingerprint.kt
index 7307d9ab..73c5faee 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewScrollingFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewScrollingFingerprint.kt
@@ -1,9 +1,14 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.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 RecyclerViewScrollingFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf(),
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingParentFingerprint.kt
index 0d4425b9..b891aa4a 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingParentFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingParentFingerprint.kt
@@ -1,9 +1,13 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.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 RecyclerViewTopScrollingParentFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
+ parameters = listOf("L", "L", "Landroid/view/ViewGroup;", "Landroid/view/ViewGroup;"),
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
@@ -14,7 +18,4 @@ object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL,
Opcode.NEW_INSTANCE
),
- customFingerprint = { methodDef, _ ->
- methodDef.name == ""
- }
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/SubtitleWindowSettingsConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/SubtitleWindowSettingsConstructorFingerprint.kt
deleted file mode 100644
index f37201f8..00000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/SubtitleWindowSettingsConstructorFingerprint.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package app.revanced.patches.youtube.misc.fix.playback.fingerprints
-
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
-
-object SubtitleWindowSettingsConstructorFingerprint : MethodFingerprint(
- parameters = listOf("I", "I", "I", "Z", "Z"),
- customFingerprint = { methodDef, _ ->
- methodDef.definingClass == "Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleWindowSettings;"
- && methodDef.name == ""
- }
-)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt
index 04d488ac..4b5f7428 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt
@@ -17,11 +17,9 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.OpenCronetDataSourceFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint
-import app.revanced.patches.youtube.misc.fix.playback.fingerprints.SubtitleWindowSettingsConstructorFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
-import app.revanced.patches.youtube.video.videoid.patch.VideoIdPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Name("spoof-signature-verification")
@@ -30,14 +28,12 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
IntegrationsPatch::class,
SettingsPatch::class,
PlayerTypeHookPatch::class,
- VideoIdPatch::class
])
@Version("0.0.1")
class SpoofSignatureVerificationPatch : BytecodePatch(
listOf(
ProtobufParameterBuilderFingerprint,
OpenCronetDataSourceFingerprint,
- SubtitleWindowSettingsConstructorFingerprint,
)
) {
override fun execute(context: BytecodeContext): PatchResult {
@@ -48,7 +44,8 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
StringResource("revanced_spoof_signature_verification_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
- + "• End screen cards are always hidden\\n"
+ + "• Ambient mode may not work\\n"
+ + "• Seekbar thumbnails are hidden\\n"
+ "• Downloading videos may not work"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"),
StringResource("revanced_spoof_signature_verification_user_dialog_message",
@@ -56,9 +53,6 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
)
)
- // Hook video id, required for subtitle fix.
- VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")
-
// hook parameter
ProtobufParameterBuilderFingerprint.result?.let {
val setParamMethod = context
@@ -95,25 +89,6 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
} ?: return OpenCronetDataSourceFingerprint.toErrorResult()
- // hook override subtitles
- SubtitleWindowSettingsConstructorFingerprint.result?.let {
- it.mutableMethod.apply {
- addInstructions(
- 0,
- """
- invoke-static {p1, p2, p3, p4, p5}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSubtitleWindowSettingsOverride(IIIZZ)[I
- move-result-object v0
- const/4 v1, 0x0
- aget p1, v0, v1 # ap, anchor position
- const/4 v1, 0x1
- aget p2, v0, v1 # ah, horizontal anchor
- const/4 v1, 0x2
- aget p3, v0, v1 # av, vertical anchor
- """
- )
- }
- } ?: return SubtitleWindowSettingsConstructorFingerprint.toErrorResult()
-
return PatchResultSuccess()
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/StandalonePlayerActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/StandalonePlayerActivityFingerprint.kt
index 799b80ee..9d2eb4c0 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/StandalonePlayerActivityFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/StandalonePlayerActivityFingerprint.kt
@@ -1,6 +1,8 @@
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
/**
* Old API activity to embed YouTube into 3rd party Android apps.
@@ -10,6 +12,9 @@ import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.
* https://developers.google.com/youtube/android/player
*/
object StandalonePlayerActivityFingerprint : IntegrationsFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf("L"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/google/android/youtube/api/StandalonePlayerActivity;"
&& methodDef.name == "onCreate"
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt
index 498f7ca2..b0fad80b 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt
@@ -9,5 +9,5 @@ object ComponentContextParserFingerprint : MethodFingerprint(
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE
),
- strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings")
+ strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings.")
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/LithoFilterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/LithoFilterFingerprint.kt
index 0d376072..9839efc3 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/LithoFilterFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/LithoFilterFingerprint.kt
@@ -1,11 +1,13 @@
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
+import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.AccessFlags
object LithoFilterFingerprint : MethodFingerprint(
- customFingerprint = custom@{ method, classDef ->
- if (method.name != "") return@custom false
-
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.CONSTRUCTOR,
+ returnType = "V",
+ customFingerprint = { _, classDef ->
classDef.type.endsWith("LithoFilterPatch;")
}
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt
index 015736b7..dbb7e1e4 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt
@@ -1,13 +1,10 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-
-@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
"Z",
AccessFlags.PUBLIC or AccessFlags.STATIC,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt
index af3840d0..ca676e7a 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt
@@ -1,16 +1,14 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-
-@FuzzyPatternScanMethod(2)
object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
- "L",
- AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "L",
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ parameters = listOf(),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsParentFingerprint.kt
new file mode 100644
index 00000000..59754a7f
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsParentFingerprint.kt
@@ -0,0 +1,14 @@
+package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
+
+import app.revanced.patcher.extensions.or
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.AccessFlags
+
+/**
+ * Class fingerprint for [MinimizedPlaybackSettingsFingerprint]
+ */
+object MinimizedPlaybackSettingsParentFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
+ parameters = listOf("Landroid/content/Context;", "Landroid/support/v4/media/session/MediaSessionCompat"),
+ strings = listOf("sessionToken must not be null")
+)
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt
index 3848df84..c2265438 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt
@@ -8,6 +8,7 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
@@ -21,6 +22,7 @@ import app.revanced.patches.youtube.misc.minimizedplayback.annotations.Minimized
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
+import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsParentFingerprint
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@@ -35,7 +37,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
class MinimizedPlaybackPatch : BytecodePatch(
listOf(
MinimizedPlaybackManagerFingerprint,
- MinimizedPlaybackSettingsFingerprint,
+ MinimizedPlaybackSettingsParentFingerprint,
KidsMinimizedPlaybackPolicyControllerFingerprint
)
) {
@@ -60,6 +62,8 @@ class MinimizedPlaybackPatch : BytecodePatch(
} ?: return MinimizedPlaybackManagerFingerprint.toErrorResult()
// Enable minimized playback option in YouTube settings
+ MinimizedPlaybackSettingsParentFingerprint.result ?: return MinimizedPlaybackSettingsParentFingerprint.toErrorResult()
+ MinimizedPlaybackSettingsFingerprint.resolve(context, MinimizedPlaybackSettingsParentFingerprint.result!!.classDef)
MinimizedPlaybackSettingsFingerprint.result?.apply {
val booleanCalls = method.implementation!!.instructions.withIndex()
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt
index 7de6849b..48b3fb2d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt
@@ -5,42 +5,33 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
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.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
+import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Name("player-controls-bytecode-patch")
-@DependsOn([ResourceMappingPatch::class])
+@DependsOn([BottomControlsResourcePatch::class])
@Description("Manages the code for the player controls of the YouTube player.")
@PlayerControlsCompatibility
@Version("0.0.1")
class PlayerControlsBytecodePatch : BytecodePatch(
- listOf(PlayerControlsVisibilityFingerprint)
+ listOf(PlayerControlsVisibilityFingerprint, BottomControlsInflateFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
-
- bottomUiContainerResourceId = ResourceMappingPatch
- .resourceMappings
- .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
-
- // TODO: another solution is required, this is hacky
- listOf(BottomControlsInflateFingerprint).resolve(context, context.classes)
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
return PatchResultSuccess()
}
internal companion object {
- var bottomUiContainerResourceId: Long = 0
lateinit var showPlayerControlsFingerprintResult: MethodFingerprintResult
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt
index 902f8894..63864aa5 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt
@@ -1,21 +1,19 @@
package app.revanced.patches.youtube.misc.playercontrols.fingerprints
-
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
-import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
+import app.revanced.patcher.extensions.or
+import app.revanced.util.patch.LiteralValueFingerprint
+import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object BottomControlsInflateFingerprint : MethodFingerprint(
+object BottomControlsInflateFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.SYNTHETIC,
+ returnType = "L",
+ parameters = listOf(),
opcodes = listOf(
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT
),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- instruction.opcode.ordinal == Opcode.CONST.ordinal &&
- (instruction as? WideLiteralInstruction)?.wideLiteral == PlayerControlsBytecodePatch.bottomUiContainerResourceId
- } == true
- }
+ literal = BottomControlsResourcePatch.bottomUiContainerResourceId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt
index 0bf59e70..db64aaaa 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt
@@ -1,10 +1,12 @@
package app.revanced.patches.youtube.misc.playercontrols.fingerprints
-
+import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.AccessFlags
object PlayerControlsVisibilityFingerprint : MethodFingerprint(
- "V",
+ accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
+ returnType = "V",
parameters = listOf("Z", "Z"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt
index d6fb1889..20d3841d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt
@@ -8,21 +8,30 @@ 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.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
+import java.io.Closeable
@Name("bottom-controls-resource-patch")
@Description("Manages the resources for the bottom controls of the YouTube player.")
@PlayerControlsCompatibility
+@DependsOn([ResourceMappingPatch::class])
@Version("0.0.1")
-class BottomControlsResourcePatch : ResourcePatch {
+class BottomControlsResourcePatch : ResourcePatch, Closeable {
override fun execute(context: ResourceContext): PatchResult {
resourceContext = context
targetXmlEditor = context.xmlEditor[TARGET_RESOURCE]
+ bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings
+ .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
+
return PatchResultSuccess()
}
companion object {
+ internal var bottomUiContainerResourceId : Long = -1
+
internal const val TARGET_RESOURCE_NAME = "youtube_controls_bottom_ui_container.xml"
private const val TARGET_RESOURCE = "res/layout/$TARGET_RESOURCE_NAME"
@@ -32,8 +41,6 @@ class BottomControlsResourcePatch : ResourcePatch {
// The element to which to add the new elements to
private var lastLeftOf = "fullscreen_button"
-
-
/**
* Add new controls to the bottom of the YouTube player.
* @param hostYouTubeControlsBottomUiResourceName The hosting resource name containing the elements.
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/LicenseActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/LicenseActivityFingerprint.kt
index 42a9f0af..05dfba24 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/LicenseActivityFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/LicenseActivityFingerprint.kt
@@ -1,8 +1,13 @@
package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
+import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.AccessFlags
object LicenseActivityFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf("L"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("LicenseActivity;") && methodDef.name == "onCreate"
}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/SetThemeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/SetThemeFingerprint.kt
index 468e8e24..77e54856 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/SetThemeFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/SetThemeFingerprint.kt
@@ -1,20 +1,15 @@
package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object SetThemeFingerprint : MethodFingerprint(
+object SetThemeFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "L",
+ parameters = listOf(),
opcodes = listOf(Opcode.RETURN_OBJECT),
- customFingerprint = { methodDef, _ ->
- methodDef.implementation?.instructions?.any { instruction ->
- if (instruction.opcode != Opcode.CONST) return@any false
-
- val wideLiteral = (instruction as WideLiteralInstruction).wideLiteral
-
- SettingsResourcePatch.appearanceStringId == wideLiteral
- } ?: false
- }
+ literal = SettingsResourcePatch.appearanceStringId
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsPatch.kt
index 393a20e6..d304dc24 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsPatch.kt
@@ -22,6 +22,7 @@ import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourc
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.util.MethodUtil
+import java.io.Closeable
@DependsOn([IntegrationsPatch::class, SettingsResourcePatch::class, ])
@Name("settings")
@@ -29,7 +30,7 @@ import org.jf.dexlib2.util.MethodUtil
@Version("0.0.1")
class SettingsPatch : BytecodePatch(
listOf(LicenseActivityFingerprint, SetThemeFingerprint)
-) {
+), Closeable {
override fun execute(context: BytecodeContext): PatchResult {
// TODO: Remove this when it is only required at one place.
fun getSetThemeInstructionString(
diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt
index edb71207..81de6a39 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt
@@ -1,9 +1,14 @@
package app.revanced.patches.youtube.video.information.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 OnPlaybackSpeedItemClickFingerprint : MethodFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ returnType = "V",
+ parameters = listOf("L", "L", "I", "J"),
customFingerprint = { methodDef, _ -> methodDef.name == "onItemClick" },
opcodes = listOf(
Opcode.MOVE_RESULT_OBJECT,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt
index bce66756..e671f4c4 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/video/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt
@@ -1,11 +1,15 @@
package app.revanced.patches.youtube.video.oldqualitylayout.fingerprints
-import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import app.revanced.patcher.extensions.or
+import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.video.oldqualitylayout.patch.OldQualityLayoutResourcePatch
+import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-object QualityMenuViewInflateFingerprint : MethodFingerprint(
+object QualityMenuViewInflateFingerprint : LiteralValueFingerprint(
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
+ parameters = listOf("L", "L", "L"),
+ returnType = "L",
opcodes = listOf(
Opcode.INVOKE_SUPER,
Opcode.CONST,
@@ -22,13 +26,5 @@ object QualityMenuViewInflateFingerprint : MethodFingerprint(
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 == OldQualityLayoutResourcePatch.videoQualityBottomSheetListFragmentTitle
- } ?: false
- }
+ literal = OldQualityLayoutResourcePatch.videoQualityBottomSheetListFragmentTitle
)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/SpeedArrayGeneratorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/SpeedArrayGeneratorFingerprint.kt
index 4d624dab..ba998298 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/SpeedArrayGeneratorFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/fingerprints/SpeedArrayGeneratorFingerprint.kt
@@ -1,19 +1,18 @@
package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-@FuzzyPatternScanMethod(2)
object SpeedArrayGeneratorFingerprint : MethodFingerprint(
- "[L",
- AccessFlags.PUBLIC or AccessFlags.STATIC,
+ returnType = "[L",
+ accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
+ parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
opcodes = listOf(
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
- Opcode.GOTO,
+ Opcode.GOTO_16,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/videoid/fingerprint/VideoIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoid/fingerprint/VideoIdFingerprint.kt
index d9c51ab7..3f4a0e23 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/video/videoid/fingerprint/VideoIdFingerprint.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoid/fingerprint/VideoIdFingerprint.kt
@@ -1,12 +1,10 @@
package app.revanced.patches.youtube.video.videoid.fingerprint
import app.revanced.patcher.extensions.or
-import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
-@FuzzyPatternScanMethod(2)
object VideoIdFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
diff --git a/src/main/kotlin/app/revanced/util/patch/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/patch/BytecodeUtils.kt
deleted file mode 100644
index d6285732..00000000
--- a/src/main/kotlin/app/revanced/util/patch/BytecodeUtils.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package app.revanced.util.patch
-
-import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.Method
-import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
-
-/**
- * @return the first constant instruction with the resource id, or -1 if not found.
- */
-fun Method.indexOfFirstConstantInstruction(constantValue: Long): Int {
- return implementation?.let {
- it.instructions.indexOfFirst { instruction ->
- instruction.opcode == Opcode.CONST && (instruction as WideLiteralInstruction).wideLiteral == constantValue
- }
- } ?: -1
-}
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/util/patch/LiteralValueFingerprint.kt b/src/main/kotlin/app/revanced/util/patch/LiteralValueFingerprint.kt
new file mode 100644
index 00000000..ec977e06
--- /dev/null
+++ b/src/main/kotlin/app/revanced/util/patch/LiteralValueFingerprint.kt
@@ -0,0 +1,23 @@
+package app.revanced.util.patch
+
+import app.revanced.extensions.containsConstantInstructionValue
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.Opcode
+
+abstract class LiteralValueFingerprint(
+ returnType: String? = null,
+ accessFlags: Int? = null,
+ parameters: Iterable? = null,
+ opcodes: Iterable? = null,
+ strings: Iterable? = null,
+ literal: Long
+) : MethodFingerprint(
+ returnType = returnType,
+ accessFlags = accessFlags,
+ parameters = parameters,
+ opcodes = opcodes,
+ strings = strings,
+ customFingerprint = { methodDef, _ ->
+ methodDef.containsConstantInstructionValue(literal)
+ }
+)
\ No newline at end of file