diff --git a/CHANGELOG.md b/CHANGELOG.md index d9b5e50b8..013ecc56c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,54 @@ +# [2.193.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v2.193.0-dev.6...v2.193.0-dev.7) (2023-10-08) + + +### Features + +* **YouTube:** Bump compatibility to `18.38.44` ([#3071](https://github.com/ReVanced/revanced-patches/issues/3071)) ([a73868c](https://github.com/ReVanced/revanced-patches/commit/a73868cb270295c871a9f1e4d543f728d6152146)) + +# [2.193.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v2.193.0-dev.5...v2.193.0-dev.6) (2023-10-08) + + +### Bug Fixes + +* **YouTube:** Sort settings alphabetically despite punctuation ([#3097](https://github.com/ReVanced/revanced-patches/issues/3097)) ([46e3c97](https://github.com/ReVanced/revanced-patches/commit/46e3c97d24e282e4d7d444603af4fb475ae03315)) + +# [2.193.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.193.0-dev.4...v2.193.0-dev.5) (2023-10-08) + + +### Bug Fixes + +* Consolidate patches ([#3098](https://github.com/ReVanced/revanced-patches/issues/3098)) ([02f767d](https://github.com/ReVanced/revanced-patches/commit/02f767df3cd1b2d0155e7360d2b26fa5d1cfcace)) + +# [2.193.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.193.0-dev.3...v2.193.0-dev.4) (2023-10-08) + + +### Bug Fixes + +* **Boost for Reddit - Spoof client:** Set user-agent for OAuth requests to fix login ([2223951](https://github.com/ReVanced/revanced-patches/commit/2223951fa16011d735ef4c4cda11eba13403f62d)) +* **Infinity for Reddit - Spoof client:** Set user-agent for OAuth requests to fix login ([a710f05](https://github.com/ReVanced/revanced-patches/commit/a710f05bb46156e66ca56aa4731e1028f459c414)) +* **Sync for Reddit - Spoof client:** Set user-agent for OAuth requests to fix login ([a48c4a7](https://github.com/ReVanced/revanced-patches/commit/a48c4a7cc1dbb3ecfce2e345240bca8142740b77)) + +# [2.193.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.193.0-dev.2...v2.193.0-dev.3) (2023-10-07) + + +### Features + +* **YouTube - Return YouTube Dislike:** Support version `18.37.36` ([#3061](https://github.com/ReVanced/revanced-patches/issues/3061)) ([fe11db7](https://github.com/ReVanced/revanced-patches/commit/fe11db70eafb481db87231d3db22eafbaa479871)) + +# [2.193.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.193.0-dev.1...v2.193.0-dev.2) (2023-10-07) + + +### Features + +* **YouTube:** Add `Disable fine scrubbing gesture` patch ([6c9baf2](https://github.com/ReVanced/revanced-patches/commit/6c9baf22614b1be4870be684915445f7a138cf31)) + +# [2.193.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.192.0...v2.193.0-dev.1) (2023-10-05) + + +### Features + +* **YouTube - Hide shorts components:** Hide subscribe button when paused separately from subscribe button ([52d07ec](https://github.com/ReVanced/revanced-patches/commit/52d07ecd39b1c37cfbfbfa699ccbef849600d9f8)) + # [2.192.0](https://github.com/ReVanced/revanced-patches/compare/v2.191.0...v2.192.0) (2023-10-05) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae02f2a8f..01cb5a244 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,12 +28,15 @@     - - + + + + +     -     +

Continuing the legacy of Vanced diff --git a/README.md b/README.md index 6336b2c21..58d916247 100644 --- a/README.md +++ b/README.md @@ -28,18 +28,20 @@     - - + + + + +     -     +

Continuing the legacy of Vanced

- # 🧩 ReVanced Patches ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/ReVanced/revanced-patches/release.yml) diff --git a/gradle.properties b/gradle.properties index f73b46054..931dc0c82 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 2.192.0 +version = 2.193.0-dev.7 diff --git a/patches.json b/patches.json index c659ae446..2151947f3 100644 --- a/patches.json +++ b/patches.json @@ -1 +1 @@ -[{"name":"Unlock premium","description":null,"compatiblePackages":[{"name":"com.adobe.lrmobile","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable mandatory login","description":null,"compatiblePackages":[{"name":"com.adobe.lrmobile","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":"Removes general ads.","compatiblePackages":[{"name":"com.vanced.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable typing indicator","description":"Disables the indicator while typing a message.","compatiblePackages":[{"name":"com.facebook.orca","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable switching emoji to sticker","description":"Disables switching from emoji to sticker search mode in message input field.","compatiblePackages":[{"name":"com.facebook.orca","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide inbox ads","description":"Hides ads in inbox.","compatiblePackages":[{"name":"com.facebook.orca","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove file size limit","description":"Allows opening files larger than 2 MB in the text editor.","compatiblePackages":[{"name":"pl.solidexplorer2","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","compatiblePackages":[{"name":"com.ticktick.task","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide premium navbar","description":"Removes the premium tab from the navbar.","compatiblePackages":[{"name":"com.spotify.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"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.","compatiblePackages":[{"name":"com.spotify.lite","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Custom theme","description":"Applies a custom theme.","compatiblePackages":[{"name":"com.spotify.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"backgroundColor","default":"@android:color/black","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false},{"key":"accentColor","default":"#ff1ed760","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false},{"key":"accentPressedColor","default":"#ff169c46","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}]},{"name":"Unlock premium","description":null,"compatiblePackages":[{"name":"io.yuka.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.candylink.openvpn","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Exclusive audio playback","description":"Enables the option to play audio without video.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Codecs unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Permanent repeat","description":"Permanently remember your repeating preference even if the playlist ends or another track is played.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Permanent shuffle","description":"Permanently remember your shuffle preference even if the playlist ends or another track is played.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Music video ads","description":"Removes ads in the music player.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Background play","description":"Enables playing music in the background.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Vanced MicroG support","description":"Allows YouTube Music to run without root and under a different package name.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Bypass certificate checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide get premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Minimized playback music","description":"Enables minimized playback on Kids music.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Compact header","description":"Hides the music category bar at the top of the homepage.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Remove upgrade button","description":"Removes the upgrade tab from the pivot bar.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove root detection","description":"Removes the check for root permissions.","compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove bootloader detection","description":"Removes the check for an unlocked bootloader.","compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Pro unlock","description":null,"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof device ID","description":"Spoofs device ID to mitigate manual bans by developers.","compatiblePackages":[{"name":"com.microblink.photomath","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock plus","description":null,"compatiblePackages":[{"name":"com.microblink.photomath","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable ads","description":null,"compatiblePackages":[{"name":"com.myprog.hexedit","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Auto claim channel points","description":"Automatically claim Channel Points.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Show deleted messages","description":"Shows deleted chat messages behind a clickable spoiler.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Debug mode","description":"Enables Twitch\u0027s internal debugging mode.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Block audio ads","description":"Blocks audio ads in streams and VODs.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Block video ads","description":"Blocks video ads in streams and VODs.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Block embedded ads","description":"Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Settings","description":"Adds settings menu to Twitch.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Promo code unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","compatiblePackages":[{"name":"de.dwd.warnapp","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Feed filter","description":"Filters tiktok videos: removing ads, removing livestreams.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Downloads","description":"Removes download restrictions and changes the default path to download to.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["30.8.4"]},{"name":"com.zhiliaoapp.musically","versions":["30.8.4"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Playback speed","description":"Enables the playback speed option for all videos.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Show seekbar","description":"Shows progress bar for all video.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["30.8.4"]},{"name":"com.zhiliaoapp.musically","versions":["30.8.4"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"SIM spoof","description":"Spoofs the information which is retrieved from the SIM card.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Disable login requirement","description":null,"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Fix Google login","description":"Allows logging in with a Google account.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Settings","description":"Adds ReVanced settings to TikTok.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["30.8.4"]},{"name":"com.zhiliaoapp.musically","versions":["30.8.4"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock paid widgets","description":"Unlocks paid widgets of the app","compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable subscription suggestions","description":null,"compatiblePackages":[{"name":"com.strava","versions":["320.12"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock subscription features","description":"Unlocks \"Routes\", \"Matched Runs\" and \"Segment Efforts\".","compatiblePackages":[{"name":"com.strava","versions":["320.12"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable dashboard ads","description":"Disables ads in the dashboard.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable gift message popup","description":"Disables the popup suggesting to buy TumblrMart items for other people.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable in-app update","description":"Disables the in-app update check and update prompt.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable blog notification reminder","description":"Disables the reminder to enable notifications for blogs you visit.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable Tumblr Live","description":"Disable the Tumblr Live tab button and dashboard carousel.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove root detection","description":"Removes the check for root permissions and unlocked bootloader.","compatiblePackages":[{"name":"at.gv.bka.serviceportal","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove badge tab","description":"Removes the badge tab from the activity tab.","compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove notification badge","description":"Removes the red notification badge from the activity tab.","compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove device restrictions","description":"Removes restrictions from using the app on any device. Requires mounting patched app over original.","compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.awedea.nyx","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":"Unlocks pro features.","compatiblePackages":[{"name":"com.vsco.cam","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof signature","description":"Spoofs the signature of the app.","compatiblePackages":[{"name":"at.gv.oe.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove root detection","description":"Removes the check for root permissions and unlocked bootloader.","compatiblePackages":[{"name":"at.gv.oe.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":"Unlocks all pro features.","compatiblePackages":[{"name":"co.windyapp.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"jp.pxv.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Show on lockscreen","description":"Shows student id and student ticket on lockscreen.","compatiblePackages":[{"name":"de.tudortmund.app","versions":null}],"use":true,"requiresIntegrations":true,"options":[]},{"name":"Remove debugging detection","description":"Removes the USB and wireless debugging checks.","compatiblePackages":[{"name":"com.scb.phone","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"External downloads","description":"Adds support to download and save YouTube videos using an external app.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Copy video url","description":"Adds buttons in player to copy video links.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Seekbar tapping","description":"Enables tap-to-seek on the seekbar of the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Swipe controls","description":"Adds volume and brightness swipe controls.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":"Removes general ads.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide \"Get YouTube Premium\" advertisements","description":"Hides YouTube Premium advertisements under video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Video ads","description":"Removes ads in the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Old video quality menu","description":"Shows the old video quality with the advanced video quality options instead of the new one.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Playback speed","description":"Adds custom playback speeds and ability to remember the playback speed you chose in the video playback speed flyout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"HDR auto brightness","description":"Makes the brightness of HDR videos follow the system default.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remember video quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Always autorepeat","description":"Always repeats the playing video again.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Vanced MicroG support","description":"Allows YouTube to run without root and under a different package name with Vanced MicroG.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Minimized playback","description":"Enables minimized and background playback.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable zoom haptics","description":"Disables haptics when zooming.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Enable debugging","description":"Adds debugging options.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Bypass URL redirects","description":"Bypass URL redirects and open the original URL directly.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Open links externally","description":"Open links outside of the app directly in your browser.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Client spoof","description":"Spoofs the client to allow playback.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide filter bar","description":"Hides the filter bar in video feeds.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide timestamp","description":"Hides timestamp in video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide \"Load more\" button","description":"Hides the button under videos that loads similar videos.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide layout components","description":"Hides general layout components.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide breaking news shelf","description":"Hides the breaking news shelf on the homepage tab.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide endscreen cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide floating microphone button","description":"Hides the floating microphone button which appears in search.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide watermark","description":"Hides creator\u0027s watermarks on videos.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Comments","description":"Hides components related to comments.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide album cards","description":"Hides the album cards below the artist description.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide email address","description":"Hides the email address in the account switcher.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide seekbar","description":"Hides the seekbar.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide Shorts components","description":"Hides components from YouTube Shorts.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide crowdfunding box","description":"Hides the crowdfunding box between the player and video description.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide info cards","description":"Hides info cards in videos.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Player flyout menu","description":"Hides player flyout menu items.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide captions button","description":"Hides the captions button on video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide autoplay button","description":"Hides the autoplay button in the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Navigation buttons","description":"Adds options to hide or change navigation buttons.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide video action buttons","description":"Adds the options to hide action buttons under a video.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide cast button","description":"Hides the cast button in the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide player buttons","description":"Adds the option to hide video player previous and next buttons.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable auto captions","description":"Disable forced captions from being automatically enabled.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Wide searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Enable tablet layout","description":"Spoofs the device form factor to a tablet which enables the tablet layout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable Shorts on startup","description":"Disables playing YouTube Shorts when launching YouTube.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Theme","description":"Applies a custom theme.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"darkThemeBackgroundColor","default":"@android:color/black","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},{"key":"lightThemeBackgroundColor","default":"@android:color/white","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}]},{"name":"Disable player popup panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"SponsorBlock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Custom branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":false,"requiresIntegrations":false,"options":[{"key":"appName","default":"YouTube ReVanced","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true},{"key":"iconPath","default":null,"title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false}]},{"name":"Premium heading","description":"Show or hide the premium heading.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"usePremiumHeading","default":true,"title":"Use premium heading","description":"Whether to use the premium heading.","required":true}]},{"name":"Return YouTube Dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.32.39"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Tablet mini player","description":"Enables the tablet mini player layout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"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.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Alternative thumbnails","description":"Adds options to replace video thumbnails with still image captures of the video.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Custom player overlay opacity","description":"Change the opacity of the player background, when player controls are visible.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove player controls background","description":"Removes the background from the video player controls.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36"]}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Export all activities","description":"Makes all app activities exportable.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Remove screen capture restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","compatiblePackages":null,"use":false,"requiresIntegrations":true,"options":[]},{"name":"Remove screenshot restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","compatiblePackages":null,"use":false,"requiresIntegrations":true,"options":[]},{"name":"Spoof Wi-Fi connection","description":"Spoofs an existing Wi-Fi connection.","compatiblePackages":null,"use":false,"requiresIntegrations":true,"options":[]},{"name":"Predictive back gesture","description":"Enables the predictive back gesture introduced on Android 13.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Override certificate pinning","description":"Overrides certificate pinning, allowing to inspect traffic via a proxy.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Change package name","description":"Appends \".revanced\" to the package name by default.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[{"key":"packageName","default":null,"title":"Package name","description":"The name of the package to rename the app to.","required":false}]},{"name":"Enable Android debugging","description":"Enables Android debugging capabilities. This can slow down the app.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Disable ads","description":null,"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable Sync for Lemmy bottom sheet","description":"Disables the bottom sheet at the startup that asks you to signup to \"Sync for Lemmy\".","compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":["v23.06.30-13:39"]},{"name":"com.laurencedawson.reddit_sync.pro","versions":null},{"name":"com.laurencedawson.reddit_sync.dev","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":null},{"name":"com.laurencedawson.reddit_sync.pro","versions":null},{"name":"com.laurencedawson.reddit_sync.dev","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":["5.4.0","5.4.1","5.4.2","6.0.1","6.0.2","6.0.4","6.0.6","6.1.1"]}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.onelouder.baconreader","versions":null},{"name":"com.onelouder.baconreader.premium","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://baconreader.com/auth\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"me.ccrama.redditslide","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://www.ccrama.me\".","required":true}]},{"name":"Disable ads","description":null,"compatiblePackages":[{"name":"o.o.joey","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"o.o.joey","versions":null},{"name":"o.o.joey.pro","versions":null},{"name":"o.o.joey.dev","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"https://127.0.0.1:65023/authorize_callback\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"free.reddit.news","versions":null},{"name":"reddit.news","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":null},{"name":"com.andrewshu.android.redditdonation","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","required":true}]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":true,"options":[]},{"name":"Sanitize sharing links","description":"Removes (tracking) query parameters from the URLs when sharing links.","compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable screenshot popup","description":"Disables the popup that shows up when taking a screenshot.","compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock premium Reddit icons","description":null,"compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":"Hides ads.","compatiblePackages":[{"name":"com.twitter.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide recommended users","description":null,"compatiblePackages":[{"name":"com.twitter.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Dynamic color","description":"Replaces the default Twitter Blue with the user\u0027s Material You palette.","compatiblePackages":[{"name":"com.twitter.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove broadcasts restriction","description":"Enables starting/stopping NetGuard via broadcasts.","compatiblePackages":[{"name":"eu.faircode.netguard","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"tv.trakt.trakt","versions":["1.1.1"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove ads","description":null,"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide timeline ads","description":"Removes ads from the timeline.","compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"com.nis.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":null}],"use":true,"requiresIntegrations":false,"options":[]}] \ No newline at end of file +[{"name":"Unlock premium","description":null,"compatiblePackages":[{"name":"com.adobe.lrmobile","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable mandatory login","description":null,"compatiblePackages":[{"name":"com.adobe.lrmobile","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":"Removes general ads.","compatiblePackages":[{"name":"com.vanced.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable typing indicator","description":"Disables the indicator while typing a message.","compatiblePackages":[{"name":"com.facebook.orca","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable switching emoji to sticker","description":"Disables switching from emoji to sticker search mode in message input field.","compatiblePackages":[{"name":"com.facebook.orca","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide inbox ads","description":"Hides ads in inbox.","compatiblePackages":[{"name":"com.facebook.orca","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove file size limit","description":"Allows opening files larger than 2 MB in the text editor.","compatiblePackages":[{"name":"pl.solidexplorer2","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","compatiblePackages":[{"name":"com.ticktick.task","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide premium navbar","description":"Removes the premium tab from the navbar.","compatiblePackages":[{"name":"com.spotify.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"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.","compatiblePackages":[{"name":"com.spotify.lite","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Custom theme","description":"Applies a custom theme.","compatiblePackages":[{"name":"com.spotify.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"backgroundColor","default":"@android:color/black","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false},{"key":"accentColor","default":"#ff1ed760","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false},{"key":"accentPressedColor","default":"#ff169c46","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}]},{"name":"Unlock premium","description":null,"compatiblePackages":[{"name":"io.yuka.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.candylink.openvpn","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Exclusive audio playback","description":"Enables the option to play audio without video.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Codecs unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Permanent repeat","description":"Permanently remember your repeating preference even if the playlist ends or another track is played.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Permanent shuffle","description":"Permanently remember your shuffle preference even if the playlist ends or another track is played.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Music video ads","description":"Removes ads in the music player.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Background play","description":"Enables playing music in the background.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Vanced MicroG support","description":"Allows YouTube Music to run without root and under a different package name.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Bypass certificate checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide get premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Minimized playback music","description":"Enables minimized playback on Kids music.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Compact header","description":"Hides the music category bar at the top of the homepage.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Remove upgrade button","description":"Removes the upgrade tab from the pivot bar.","compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove root detection","description":"Removes the check for root permissions.","compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove bootloader detection","description":"Removes the check for an unlocked bootloader.","compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Pro unlock","description":null,"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof device ID","description":"Spoofs device ID to mitigate manual bans by developers.","compatiblePackages":[{"name":"com.microblink.photomath","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock plus","description":null,"compatiblePackages":[{"name":"com.microblink.photomath","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable ads","description":null,"compatiblePackages":[{"name":"com.myprog.hexedit","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Auto claim channel points","description":"Automatically claim Channel Points.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Show deleted messages","description":"Shows deleted chat messages behind a clickable spoiler.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Debug mode","description":"Enables Twitch\u0027s internal debugging mode.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Block audio ads","description":"Blocks audio ads in streams and VODs.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Block video ads","description":"Blocks video ads in streams and VODs.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Block embedded ads","description":"Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":["15.4.1","16.1.0"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Settings","description":"Adds settings menu to Twitch.","compatiblePackages":[{"name":"tv.twitch.android.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Promo code unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","compatiblePackages":[{"name":"de.dwd.warnapp","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Feed filter","description":"Filters tiktok videos: removing ads, removing livestreams.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Downloads","description":"Removes download restrictions and changes the default path to download to.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["30.8.4"]},{"name":"com.zhiliaoapp.musically","versions":["30.8.4"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Playback speed","description":"Enables the playback speed option for all videos.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Show seekbar","description":"Shows progress bar for all video.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["30.8.4"]},{"name":"com.zhiliaoapp.musically","versions":["30.8.4"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"SIM spoof","description":"Spoofs the information which is retrieved from the SIM card.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Disable login requirement","description":null,"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Fix Google login","description":"Allows logging in with a Google account.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":null},{"name":"com.zhiliaoapp.musically","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Settings","description":"Adds ReVanced settings to TikTok.","compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["30.8.4"]},{"name":"com.zhiliaoapp.musically","versions":["30.8.4"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock paid widgets","description":"Unlocks paid widgets of the app","compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable subscription suggestions","description":null,"compatiblePackages":[{"name":"com.strava","versions":["320.12"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock subscription features","description":"Unlocks \"Routes\", \"Matched Runs\" and \"Segment Efforts\".","compatiblePackages":[{"name":"com.strava","versions":["320.12"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable dashboard ads","description":"Disables ads in the dashboard.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable gift message popup","description":"Disables the popup suggesting to buy TumblrMart items for other people.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable in-app update","description":"Disables the in-app update check and update prompt.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable blog notification reminder","description":"Disables the reminder to enable notifications for blogs you visit.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable Tumblr Live","description":"Disable the Tumblr Live tab button and dashboard carousel.","compatiblePackages":[{"name":"com.tumblr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove root detection","description":"Removes the check for root permissions and unlocked bootloader.","compatiblePackages":[{"name":"at.gv.bka.serviceportal","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove badge tab","description":"Removes the badge tab from the activity tab.","compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove notification badge","description":"Removes the red notification badge from the activity tab.","compatiblePackages":[{"name":"com.sony.songpal.mdr","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove device restrictions","description":"Removes restrictions from using the app on any device. Requires mounting patched app over original.","compatiblePackages":[{"name":"com.google.android.apps.recorder","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.awedea.nyx","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":"Unlocks pro features.","compatiblePackages":[{"name":"com.vsco.cam","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof signature","description":"Spoofs the signature of the app.","compatiblePackages":[{"name":"at.gv.oe.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove root detection","description":"Removes the check for root permissions and unlocked bootloader.","compatiblePackages":[{"name":"at.gv.oe.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":"Unlocks all pro features.","compatiblePackages":[{"name":"co.windyapp.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364","4.6370","4.6375","4.6377"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"jp.pxv.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Show on lockscreen","description":"Shows student id and student ticket on lockscreen.","compatiblePackages":[{"name":"de.tudortmund.app","versions":null}],"use":true,"requiresIntegrations":true,"options":[]},{"name":"Remove debugging detection","description":"Removes the USB and wireless debugging checks.","compatiblePackages":[{"name":"com.scb.phone","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"External downloads","description":"Adds support to download and save YouTube videos using an external app.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Copy video url","description":"Adds buttons in player to copy video links.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable fine scrubbing gesture","description":"Disables gesture that shows the fine scrubbing overlay when swiping up on the seekbar.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Seekbar tapping","description":"Enables tap-to-seek on the seekbar of the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Swipe controls","description":"Adds volume and brightness swipe controls.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":"Removes general ads.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Video ads","description":"Removes ads in the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Old video quality menu","description":"Shows the old video quality with the advanced video quality options instead of the new one.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Playback speed","description":"Adds custom playback speeds and ability to remember the playback speed you chose in the video playback speed flyout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"HDR auto brightness","description":"Makes the brightness of HDR videos follow the system default.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remember video quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Always autorepeat","description":"Always repeats the playing video again.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Vanced MicroG support","description":"Allows YouTube to run without root and under a different package name with Vanced MicroG.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Minimized playback","description":"Enables minimized and background playback.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable zoom haptics","description":"Disables haptics when zooming.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Enable debugging","description":"Adds debugging options.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Bypass URL redirects","description":"Bypass URL redirects and open the original URL directly.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Open links externally","description":"Open links outside of the app directly in your browser.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Client spoof","description":"Spoofs the client to allow playback.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide filter bar","description":"Hides the filter bar in video feeds.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide timestamp","description":"Hides timestamp in video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide \u0027Load more\u0027 button","description":"Hides the button under videos that loads similar videos.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide layout components","description":"Hides general layout components.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide breaking news shelf","description":"Hides the breaking news shelf on the homepage tab.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide endscreen cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide floating microphone button","description":"Hides the floating microphone button which appears in search.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide watermark","description":"Hides creator\u0027s watermarks on videos.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Comments","description":"Hides components related to comments.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide album cards","description":"Hides the album cards below the artist description.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide email address","description":"Hides the email address in the account switcher.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide seekbar","description":"Hides the seekbar.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide Shorts components","description":"Hides components from YouTube Shorts.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide crowdfunding box","description":"Hides the crowdfunding box between the player and video description.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide info cards","description":"Hides info cards in videos.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Player flyout menu","description":"Hides player flyout menu items.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide captions button","description":"Hides the captions button on video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide autoplay button","description":"Hides the autoplay button in the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Navigation buttons","description":"Adds options to hide or change navigation buttons.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide video action buttons","description":"Adds the options to hide action buttons under a video.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide cast button","description":"Hides the cast button in the video player.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide player buttons","description":"Adds the option to hide video player previous and next buttons.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable auto captions","description":"Disable forced captions from being automatically enabled.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Wide searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Enable tablet layout","description":"Spoofs the device form factor to a tablet which enables the tablet layout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable Shorts on startup","description":"Disables playing YouTube Shorts when launching YouTube.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Theme","description":"Applies a custom theme.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"darkThemeBackgroundColor","default":"@android:color/black","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},{"key":"lightThemeBackgroundColor","default":"@android:color/white","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}]},{"name":"Disable player popup panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"SponsorBlock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Custom branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":false,"requiresIntegrations":false,"options":[{"key":"appName","default":"YouTube ReVanced","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true},{"key":"iconPath","default":null,"title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false}]},{"name":"Premium heading","description":"Show or hide the premium heading.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"usePremiumHeading","default":true,"title":"Use premium heading","description":"Whether to use the premium heading.","required":true}]},{"name":"Return YouTube Dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Tablet mini player","description":"Enables the tablet mini player layout.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"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.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Alternative thumbnails","description":"Adds options to replace video thumbnails with still image captures of the video.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Custom player overlay opacity","description":"Change the opacity of the player background, when player controls are visible.","compatiblePackages":[{"name":"com.google.android.youtube","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove player controls background","description":"Removes the background from the video player controls.","compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.16.37","18.19.35","18.20.39","18.23.35","18.29.38","18.32.39","18.37.36","18.38.44"]}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Export all activities","description":"Makes all app activities exportable.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Remove screen capture restriction","description":"Removes the restriction of capturing audio from apps that normally wouldn\u0027t allow it.","compatiblePackages":null,"use":false,"requiresIntegrations":true,"options":[]},{"name":"Remove screenshot restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","compatiblePackages":null,"use":false,"requiresIntegrations":true,"options":[]},{"name":"Spoof Wi-Fi connection","description":"Spoofs an existing Wi-Fi connection.","compatiblePackages":null,"use":false,"requiresIntegrations":true,"options":[]},{"name":"Predictive back gesture","description":"Enables the predictive back gesture introduced on Android 13.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Override certificate pinning","description":"Overrides certificate pinning, allowing to inspect traffic via a proxy.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Change package name","description":"Appends \".revanced\" to the package name by default.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[{"key":"packageName","default":null,"title":"Package name","description":"The name of the package to rename the app to.","required":false}]},{"name":"Enable Android debugging","description":"Enables Android debugging capabilities. This can slow down the app.","compatiblePackages":null,"use":false,"requiresIntegrations":false,"options":[]},{"name":"Disable ads","description":null,"compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable Sync for Lemmy bottom sheet","description":"Disables the bottom sheet at the startup that asks you to signup to \"Sync for Lemmy\".","compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":["v23.06.30-13:39"]},{"name":"com.laurencedawson.reddit_sync.pro","versions":null},{"name":"com.laurencedawson.reddit_sync.dev","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.laurencedawson.reddit_sync","versions":null},{"name":"com.laurencedawson.reddit_sync.pro","versions":null},{"name":"com.laurencedawson.reddit_sync.dev","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://redditsync/auth\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.rubenmayayo.reddit","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://rubenmayayo.com\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"ml.docilealligator.infinityforreddit","versions":["5.4.0","5.4.1","5.4.2","6.0.1","6.0.2","6.0.4","6.0.6","6.1.1"]}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"infinity://localhost\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.onelouder.baconreader","versions":null},{"name":"com.onelouder.baconreader.premium","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://baconreader.com/auth\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"me.ccrama.redditslide","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"http://www.ccrama.me\".","required":true}]},{"name":"Disable ads","description":null,"compatiblePackages":[{"name":"o.o.joey","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"o.o.joey","versions":null},{"name":"o.o.joey.pro","versions":null},{"name":"o.o.joey.dev","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"https://127.0.0.1:65023/authorize_callback\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"free.reddit.news","versions":null},{"name":"reddit.news","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"dbrady://relay\".","required":true}]},{"name":"Spoof client","description":"Restores functionality of the app by using custom client ID\u0027s.","compatiblePackages":[{"name":"com.andrewshu.android.reddit","versions":null},{"name":"com.andrewshu.android.redditdonation","versions":null}],"use":true,"requiresIntegrations":false,"options":[{"key":"client-id","default":null,"title":"OAuth client ID","description":"The Reddit OAuth client ID. You can get your client ID from https://www.reddit.com/prefs/apps. The application type has to be \"Installed app\" and the redirect URI has to be set to \"redditisfun://auth\".","required":true}]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":true,"options":[]},{"name":"Sanitize sharing links","description":"Removes (tracking) query parameters from the URLs when sharing links.","compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Disable screenshot popup","description":"Disables the popup that shows up when taking a screenshot.","compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock premium Reddit icons","description":null,"compatiblePackages":[{"name":"com.reddit.frontpage","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":"Hides ads.","compatiblePackages":[{"name":"com.twitter.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide recommended users","description":null,"compatiblePackages":[{"name":"com.twitter.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Dynamic color","description":"Replaces the default Twitter Blue with the user\u0027s Material You palette.","compatiblePackages":[{"name":"com.twitter.android","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove broadcasts restriction","description":"Enables starting/stopping NetGuard via broadcasts.","compatiblePackages":[{"name":"eu.faircode.netguard","versions":null}],"use":false,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"tv.trakt.trakt","versions":["1.1.1"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Remove ads","description":null,"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide timeline ads","description":"Removes ads from the timeline.","compatiblePackages":[{"name":"com.instagram.android","versions":["275.0.0.27.98"]}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Hide ads","description":null,"compatiblePackages":[{"name":"com.nis.app","versions":null}],"use":true,"requiresIntegrations":false,"options":[]},{"name":"Unlock pro","description":null,"compatiblePackages":[{"name":"com.wakdev.apps.nfctools.se","versions":null}],"use":true,"requiresIntegrations":false,"options":[]}] \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/Constants.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/Constants.kt new file mode 100644 index 000000000..6891a97a8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/Constants.kt @@ -0,0 +1,6 @@ +package app.revanced.patches.reddit.customclients + +object Constants { + const val OAUTH_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " + + "Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60" +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/SpoofClientPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/SpoofClientPatch.kt index 137cb137a..7d8ac71f7 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/SpoofClientPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/SpoofClientPatch.kt @@ -6,7 +6,9 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch +import app.revanced.patches.reddit.customclients.Constants.OAUTH_USER_AGENT import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint +import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.LoginActivityOnCreateFingerprint @Patch( name = "Spoof client", @@ -15,7 +17,9 @@ import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints ) @Suppress("unused") object SpoofClientPatch : AbstractSpoofClientPatch( - "http://rubenmayayo.com", listOf(GetClientIdFingerprint) + "http://rubenmayayo.com", + clientIdFingerprints = listOf(GetClientIdFingerprint), + userAgentFingerprints = listOf(LoginActivityOnCreateFingerprint) ) { override fun List.patchClientId(context: BytecodeContext) { first().mutableMethod.addInstructions( @@ -26,4 +30,20 @@ object SpoofClientPatch : AbstractSpoofClientPatch( """ ) } + + override fun List.patchUserAgent(context: BytecodeContext) { + first().let { result -> + result.mutableMethod.apply { + val insertIndex = result.scanResult.patternScanResult!!.endIndex + + addInstructions( + insertIndex, + """ + const-string v7, "$OAUTH_USER_AGENT" + invoke-virtual {v4, v7}, Landroid/webkit/WebSettings;->setUserAgentString(Ljava/lang/String;)V + """ + ) + } + } + } } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt new file mode 100644 index 000000000..b7bbe1e66 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object LoginActivityOnCreateFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST_4 + ), + customFingerprint = { method, classDef -> + method.name == "onCreate" && classDef.type.endsWith("LoginActivity;") + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt index 5a2a7e968..ea1378dfb 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt @@ -1,14 +1,17 @@ package app.revanced.patches.reddit.customclients.infinityforreddit.api 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.MethodFingerprintResult import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch +import app.revanced.patches.reddit.customclients.Constants.OAUTH_USER_AGENT import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.GetHttpBasicAuthHeaderFingerprint import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.LoginActivityOnCreateFingerprint +import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.SetWebViewSettingsFingerprint import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Patch( @@ -32,7 +35,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") object SpoofClientPatch : AbstractSpoofClientPatch( "infinity://localhost", - listOf(GetHttpBasicAuthHeaderFingerprint, LoginActivityOnCreateFingerprint) + clientIdFingerprints = listOf(GetHttpBasicAuthHeaderFingerprint, LoginActivityOnCreateFingerprint), + userAgentFingerprints = listOf(SetWebViewSettingsFingerprint) ) { override fun List.patchClientId(context: BytecodeContext) { forEach { @@ -48,4 +52,18 @@ object SpoofClientPatch : AbstractSpoofClientPatch( } } } + + override fun List.patchUserAgent(context: BytecodeContext) { + first().let { result -> + val insertIndex = result.scanResult.stringsScanResult!!.matches.first().index + + result.mutableMethod.addInstructions( + insertIndex, + """ + const-string v0, "$OAUTH_USER_AGENT" + invoke-virtual {p1, v0}, Landroid/webkit/WebSettings;->setUserAgentString(Ljava/lang/String;)V + """ + ) + } + } } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/SetWebViewSettingsFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/SetWebViewSettingsFingerprint.kt new file mode 100644 index 000000000..c9e015c27 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/SetWebViewSettingsFingerprint.kt @@ -0,0 +1,7 @@ +package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object SetWebViewSettingsFingerprint : MethodFingerprint( + strings= listOf("https://www.reddit.com/api/v1/authorize.compact") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/SpoofClientPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/SpoofClientPatch.kt index 9e91dcc6c..aab12bdc7 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/SpoofClientPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/SpoofClientPatch.kt @@ -10,9 +10,11 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch +import app.revanced.patches.reddit.customclients.Constants.OAUTH_USER_AGENT import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetBearerTokenFingerprint import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.ImgurImageAPIFingerprint +import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.LoadBrowserURLFingerprint import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.DisablePiracyDetectionPatch import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @@ -33,6 +35,7 @@ import java.util.* object SpoofClientPatch : AbstractSpoofClientPatch( "http://redditsync/auth", clientIdFingerprints = listOf(GetAuthorizationStringFingerprint), + userAgentFingerprints = listOf(LoadBrowserURLFingerprint), miscellaneousFingerprints = listOf(ImgurImageAPIFingerprint) ) { override fun List.patchClientId(context: BytecodeContext) { @@ -79,4 +82,18 @@ object SpoofClientPatch : AbstractSpoofClientPatch( "const-string v1, \"https://api.imgur.com/3/image\"" ) } + + override fun List.patchUserAgent(context: BytecodeContext) { + first().let { result -> + val insertIndex = result.scanResult.patternScanResult!!.startIndex + + result.mutableMethod.addInstructions( + insertIndex, + """ + const-string v0, "$OAUTH_USER_AGENT" + invoke-virtual {p1, v0}, Landroid/webkit/WebSettings;->setUserAgentString(Ljava/lang/String;)V + """ + ) + } + } } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/fingerprints/LoadBrowserURLFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/fingerprints/LoadBrowserURLFingerprint.kt new file mode 100644 index 000000000..67aba4295 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/fingerprints/LoadBrowserURLFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object LoadBrowserURLFingerprint : MethodFingerprint( + parameters = listOf("Landroid/view/View;", "Landroid/os/Bundle;"), + opcodes = listOf(Opcode.CONST_4), + strings = listOf("CustomInterface") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/ComponentsExtensions.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/ComponentsExtensions.kt index 21207188b..7e13127f0 100644 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/ComponentsExtensions.kt +++ b/src/main/kotlin/app/revanced/patches/shared/settings/preference/ComponentsExtensions.kt @@ -40,4 +40,9 @@ internal fun Element.addDefault(default: T) { } ) } +} + +internal fun CharSequence.removePunctuation(): String { + val punctuation = "\\p{P}+".toRegex() + return this.replace(punctuation, "") } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/util/AbstractPreferenceScreen.kt b/src/main/kotlin/app/revanced/patches/shared/settings/util/AbstractPreferenceScreen.kt index 30402f5a7..1c38980b6 100644 --- a/src/main/kotlin/app/revanced/patches/shared/settings/util/AbstractPreferenceScreen.kt +++ b/src/main/kotlin/app/revanced/patches/shared/settings/util/AbstractPreferenceScreen.kt @@ -4,6 +4,7 @@ import app.revanced.patches.shared.settings.preference.BasePreference import app.revanced.patches.shared.settings.preference.impl.PreferenceCategory import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.removePunctuation import java.io.Closeable abstract class AbstractPreferenceScreen( @@ -35,8 +36,8 @@ abstract class AbstractPreferenceScreen( return PreferenceScreen( key, StringResource("${key}_title", title), - preferences.sortedBy { it.title.value.lowercase() } + - categories.sortedBy { it.title.lowercase() }.map { it.transform() }, + preferences.sortedBy { it.title.value.removePunctuation().lowercase() } + + categories.sortedBy { it.title.removePunctuation().lowercase() }.map { it.transform() }, summary?.let { summary -> StringResource("${key}_summary", summary) } @@ -63,7 +64,7 @@ abstract class AbstractPreferenceScreen( return PreferenceCategory( key, StringResource("${key}_title", title), - preferences.sortedBy { it.title.value.lowercase() } + preferences.sortedBy { it.title.value.removePunctuation().lowercase() } ) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt index e19765ba8..a76288abe 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt @@ -32,7 +32,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt index 483ab7335..1e7a75e8d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt @@ -15,8 +15,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction @Patch( - name = "Hide \"Get YouTube Premium\" advertisements", - description = "Hides YouTube Premium advertisements under video player.", + description = "Hides YouTube Premium signup promotions under the video player.", dependencies = [IntegrationsPatch::class, SettingsPatch::class], compatiblePackages = [ CompatiblePackage( @@ -27,7 +26,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] @@ -42,15 +42,15 @@ object HideGetPremiumPatch : BytecodePatch(setOf(GetPremiumViewFingerprint)) { "revanced_hide_get_premium", StringResource( "revanced_hide_get_premium_title", - "Hide \"Get YouTube Premium\" advertisements" + "Hide YouTube Premium promotions" ), StringResource( "revanced_hide_get_premium_summary_on", - "YouTube Premium advertisements under video player are hidden" + "YouTube Premium promotions under video player is hidden" ), StringResource( "revanced_hide_get_premium_summary_off", - "YouTube Premium advertisements under video player are shown" + "YouTube Premium promotions under video player is shown" ) ) ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt index 31e442ee3..5ff58b6a9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt @@ -30,7 +30,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt index e9638043f..ee8a4b240 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt @@ -25,7 +25,8 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt index f02aae13f..c5310675d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt @@ -25,7 +25,8 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ), ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisableFineScrubbingGesturePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisableFineScrubbingGesturePatch.kt new file mode 100644 index 000000000..29393c881 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisableFineScrubbingGesturePatch.kt @@ -0,0 +1,65 @@ +package app.revanced.patches.youtube.interaction.seekbar + +import app.revanced.extensions.exception +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.interaction.seekbar.fingerprints.IsSwipingUpFingerprint +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.SettingsPatch +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction + +@Patch( + name = "Disable fine scrubbing gesture", + description = "Disables gesture that shows the fine scrubbing overlay when swiping up on the seekbar.", + dependencies = [IntegrationsPatch::class, SettingsPatch::class], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", + [ + "18.32.39", + "18.37.36", + "18.38.44" + ] + ) + ] +) +@Suppress("unused") +object DisableFineScrubbingGesturePatch : BytecodePatch( + setOf(IsSwipingUpFingerprint) +) { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "Lapp/revanced/integrations/patches/DisableFineScrubbingGesturePatch;->" + + "disableGesture(Landroid/view/VelocityTracker;Landroid/view/MotionEvent;)V" + + override fun execute(context: BytecodeContext) { + SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( + SwitchPreference( + "revanced_disable_fine_scrubbing_gesture", + StringResource("revanced_disable_fine_scrubbing_gesture_title", "Disable fine scrubbing gesture"), + StringResource("revanced_disable_fine_scrubbing_gesture_summary_on", "Gesture is disabled"), + StringResource("revanced_disable_fine_scrubbing_gesture_summary_off", "Gesture is enabled"), + ) + ) + + IsSwipingUpFingerprint.result?.let { + val addMovementIndex = it.scanResult.patternScanResult!!.startIndex - 1 + + it.mutableMethod.apply { + val addMovementInstruction = getInstruction(addMovementIndex) + val trackerRegister = addMovementInstruction.registerC + val eventRegister = addMovementInstruction.registerD + + replaceInstruction( + addMovementIndex, + "invoke-static {v$trackerRegister, v$eventRegister}, $INTEGRATIONS_METHOD_DESCRIPTOR" + ) + } + } ?: throw IsSwipingUpFingerprint.exception + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt index 185292232..89bee3bde 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt @@ -8,9 +8,12 @@ import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.youtube.interaction.seekbar.fingerprints.OnTouchEventHandlerFingerprint import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingFingerprint import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.SettingsPatch import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -19,9 +22,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference name = "Seekbar tapping", description = "Enables tap-to-seek on the seekbar of the video player.", dependencies = [ - IntegrationsPatch::class, - EnableSeekbarTappingResourcePatch::class - ], + IntegrationsPatch::class, SettingsPatch::class], compatiblePackages = [ CompatiblePackage( "com.google.android.youtube", @@ -32,7 +33,8 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] @@ -45,6 +47,15 @@ object EnableSeekbarTappingPatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext) { + SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( + SwitchPreference( + "revanced_seekbar_tapping", + StringResource("revanced_seekbar_tapping_title", "Enable seekbar tapping"), + StringResource("revanced_seekbar_tapping_summary_on", "Seekbar tapping is enabled"), + StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled") + ) + ) + // Find the required methods to tap the seekbar. val seekbarTappingMethods = OnTouchEventHandlerFingerprint.result?.let { val patternScanResult = it.scanResult.patternScanResult!! diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingResourcePatch.kt deleted file mode 100644 index a39bc0e8b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingResourcePatch.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.interaction.seekbar - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.settings.SettingsPatch - -@Patch( - dependencies = [SettingsPatch::class] -) -object EnableSeekbarTappingResourcePatch : ResourcePatch() { - override fun execute(context: ResourceContext) { - SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( - SwitchPreference( - "revanced_seekbar_tapping", - StringResource("revanced_seekbar_tapping_title", "Enable seekbar tapping"), - StringResource("revanced_seekbar_tapping_summary_on", "Seekbar tapping is enabled"), - StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled") - ) - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/IsSwipingUpFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/IsSwipingUpFingerprint.kt new file mode 100644 index 000000000..3a35684a7 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/IsSwipingUpFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.youtube.interaction.seekbar.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object IsSwipingUpFingerprint : MethodFingerprint( + parameters = listOf("Landroid/view/MotionEvent;", "J"), + opcodes = listOf(Opcode.SGET_OBJECT) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt index 04a6196ae..eeff69b00 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt @@ -32,7 +32,8 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt index 6421de5c0..8a6525a7d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt @@ -30,7 +30,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt index 0dd28b2b3..633a31893 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt @@ -28,7 +28,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt index a04196b53..2ef5e0316 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt @@ -38,7 +38,8 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt index 98f6a8328..a8598a9ac 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt @@ -29,7 +29,8 @@ import com.android.tools.smali.dexlib2.Opcode "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt index 07e77c68c..e5cb3d077 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt @@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt index ab77bf82c..a299c211d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt @@ -33,7 +33,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt index f5bf28a24..a6cb2db76 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt @@ -28,7 +28,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt index c6cbea4b7..e938dc70e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt @@ -28,7 +28,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt index daef32de5..a783a30ca 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt @@ -27,7 +27,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt index 4c7f311e6..a9d4996b5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt @@ -28,7 +28,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt index 8afa56d00..4ae8e0b4a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt @@ -31,7 +31,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt index f8a4458bf..0be4d7673 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt @@ -28,7 +28,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt index 8ec4bd788..3ad8a7ec3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt @@ -24,7 +24,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index d88ad6cd7..b2f56dfe3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -31,7 +31,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction CompatiblePackage( "com.google.android.youtube", [ "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] @@ -53,14 +54,14 @@ object HideLayoutComponentsPatch : BytecodePatch( ), SwitchPreference( "revanced_hide_join_membership_button", - StringResource("revanced_hide_join_membership_button_title", "Hide \"Join\" button"), + StringResource("revanced_hide_join_membership_button_title", "Hide \\\'Join\\\' button"), StringResource("revanced_hide_join_membership_button_summary_on", "Button is hidden"), StringResource("revanced_hide_join_membership_button_summary_off", "Button is shown") ), SwitchPreference( "revanced_hide_notify_me_button", - StringResource("revanced_hide_notify_me_button_title", "Hide \"Notify me\" button"), + StringResource("revanced_hide_notify_me_button_title", "Hide \\\'Notify me\\\' button"), StringResource("revanced_hide_notify_me_button_summary_on", "Button is hidden"), StringResource("revanced_hide_notify_me_button_summary_off", "Button is shown") ), diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt index a09daed51..eb6e938b3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt @@ -36,7 +36,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt index 83321ce09..0e7ac6276 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt @@ -11,7 +11,7 @@ import app.revanced.patches.youtube.layout.hide.loadmorebutton.fingerprints.Hide import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Patch( - name = "Hide \"Load more\" button", + name = "Hide \'Load more\' button", description = "Hides the button under videos that loads similar videos.", dependencies = [HideLoadMoreButtonResourcePatch::class], compatiblePackages = [ @@ -24,7 +24,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonResourcePatch.kt index ae2e7a8ed..65f733afe 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonResourcePatch.kt @@ -21,7 +21,7 @@ object HideLoadMoreButtonResourcePatch : ResourcePatch() { SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( SwitchPreference( "revanced_hide_load_more_button", - StringResource("revanced_hide_load_more_button_title", "Hide \"Load More\" button"), + StringResource("revanced_hide_load_more_button_title", "Hide \\\'Load More\\\' button"), StringResource("revanced_hide_load_more_button_summary_on", "Button is hidden"), StringResource("revanced_hide_load_more_button_summary_off", "Button is shown") ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/HideEmailAddressPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/HideEmailAddressPatch.kt index 1d1c6157f..6d0265078 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/HideEmailAddressPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/HideEmailAddressPatch.kt @@ -24,7 +24,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt index b7d556374..1d8c32fed 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt @@ -25,7 +25,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ]) ] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt index 39b2a540a..d27253ff2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt @@ -33,7 +33,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt index c6708c049..efc7160b8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt @@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] @@ -122,7 +123,7 @@ object HideShortsComponentsPatch : BytecodePatch( // Required to prevent a black bar from appearing at the bottom of the screen. BottomNavigationBarFingerprint.result?.let { it.mutableMethod.apply { - val moveResultIndex = it.scanResult.patternScanResult!!.startIndex + val moveResultIndex = it.scanResult.patternScanResult!!.startIndex + 2 val viewRegister = getInstruction(moveResultIndex).registerA val insertIndex = moveResultIndex + 1 diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt index 574eb752f..51c05873e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt @@ -38,6 +38,12 @@ object HideShortsComponentsResourcePatch : ResourcePatch() { StringResource("revanced_hide_shorts_subscribe_button_on", "Subscribe button is hidden"), StringResource("revanced_hide_shorts_subscribe_button_off", "Subscribe button is shown") ), + SwitchPreference( + "revanced_hide_shorts_subscribe_button_paused", + StringResource("revanced_hide_shorts_subscribe_button_paused_title", "Hide subscribe button when paused"), + StringResource("revanced_hide_shorts_subscribe_button_paused_on", "Subscribe button is hidden"), + StringResource("revanced_hide_shorts_subscribe_button_paused_off", "Subscribe button is shown") + ), SwitchPreference( "revanced_hide_shorts_thanks_button", StringResource("revanced_hide_shorts_thanks_button_title", "Hide thanks button"), diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/fingerprints/BottomNavigationBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/fingerprints/BottomNavigationBarFingerprint.kt index a451bb459..d39ddf282 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/fingerprints/BottomNavigationBarFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/fingerprints/BottomNavigationBarFingerprint.kt @@ -1,18 +1,24 @@ package app.revanced.patches.youtube.layout.hide.shorts.fingerprints +import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode object BottomNavigationBarFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Landroid/view/View;", "Landroid/os/Bundle;"), opcodes = listOf( - Opcode.MOVE_RESULT_OBJECT, // Refers to bottom navigation bar + Opcode.CONST, // R.id.app_engagement_panel_wrapper + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, Opcode.IF_EQZ, Opcode.IGET_OBJECT, Opcode.IGET_OBJECT, Opcode.IGET_OBJECT, ), strings = listOf( - "navigation_endpoint_interaction_logging_extension", - "reel_watch_fragment_watch_while", + "ReelWatchPaneFragmentViewModelKey" ), ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt index 836a601f3..58c8bbad0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt @@ -25,7 +25,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/HideWatermarkPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/HideWatermarkPatch.kt index 72bda6de5..91b67f8c2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/HideWatermarkPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/HideWatermarkPatch.kt @@ -29,7 +29,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt index e91a9ff2b..c52ec616d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt @@ -25,7 +25,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt index 764434c33..80202da0b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt @@ -19,7 +19,8 @@ import org.w3c.dom.Element "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt index 3ab8e1efa..b63fc5a49 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt @@ -14,6 +14,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.* import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction @@ -26,12 +27,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction description = "Shows the dislike count of videos using the Return YouTube Dislike API.", dependencies = [ IntegrationsPatch::class, + LithoFilterPatch::class, VideoIdPatch::class, ReturnYouTubeDislikeResourcePatch::class, PlayerTypeHookPatch::class, ], compatiblePackages = [ - CompatiblePackage("com.google.android.youtube", ["18.32.39"]) + CompatiblePackage("com.google.android.youtube", ["18.37.36", "18.38.44"]) ] ) @Suppress("unused") @@ -48,11 +50,17 @@ object ReturnYouTubeDislikePatch : BytecodePatch( private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;" + private const val FILTER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/patches/components/ReturnYouTubeDislikeFilterPatch;" + override fun execute(context: BytecodeContext) { // region Inject newVideoLoaded event handler to update dislikes when a new video is loaded. VideoIdPatch.hookVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") + // Hook the player response video id, to start loading RYD sooner in the background. + VideoIdPatch.hookPlayerResponseVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->preloadVideoId(Ljava/lang/String;)V") + // endregion // region Hook like/dislike/remove like button clicks to send votes to the API. @@ -89,49 +97,40 @@ object ReturnYouTubeDislikePatch : BytecodePatch( throw TextComponentAtomicReferenceFingerprint.exception }?.let { textComponentContextFingerprintResult -> val conversionContextIndex = textComponentContextFingerprintResult - .scanResult.patternScanResult!!.startIndex + .scanResult.patternScanResult!!.endIndex val atomicReferenceStartIndex = TextComponentAtomicReferenceFingerprint.result!! .scanResult.patternScanResult!!.startIndex - val insertIndex = atomicReferenceStartIndex + 6 + val insertIndex = atomicReferenceStartIndex + 9 textComponentContextFingerprintResult.mutableMethod.apply { - // Get the conversion context obfuscated field name, and the registers for the AtomicReference and CharSequence + // Get the conversion context obfuscated field name val conversionContextFieldReference = getInstruction(conversionContextIndex).reference - // Reuse the free register to make room for the atomic reference register. + // Free register to hold the conversion context val freeRegister = getInstruction(atomicReferenceStartIndex).registerB val atomicReferenceRegister = - getInstruction(atomicReferenceStartIndex + 1).registerC + getInstruction(atomicReferenceStartIndex + 6).registerC - val moveCharSequenceInstruction = getInstruction(insertIndex - 1) + // Instruction that is replaced, and also has the CharacterSequence register. + val moveCharSequenceInstruction = getInstruction(insertIndex) val charSequenceSourceRegister = moveCharSequenceInstruction.registerB val charSequenceTargetRegister = moveCharSequenceInstruction.registerA - // In order to preserve the atomic reference register, because it is overwritten, - // use another free register to store it. - replaceInstruction( - atomicReferenceStartIndex + 2, - "move-result-object v$freeRegister" - ) - replaceInstruction( - atomicReferenceStartIndex + 3, - "move-object v$charSequenceSourceRegister, v$freeRegister" - ) - // Move the current instance to the free register, and get the conversion context from it. - replaceInstruction(insertIndex - 1, "move-object/from16 v$freeRegister, p0") + // Must replace the instruction to preserve the control flow label. + replaceInstruction(insertIndex, "move-object/from16 v$freeRegister, p0") addInstructions( - insertIndex, + insertIndex + 1, """ # Move context to free register - iget-object v$freeRegister, v$freeRegister, $conversionContextFieldReference + iget-object v$freeRegister, v$freeRegister, $conversionContextFieldReference invoke-static {v$freeRegister, v$atomicReferenceRegister, v$charSequenceSourceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; move-result-object v$freeRegister - # Replace the original char sequence with the modified one. + # Replace the original instruction move-object v${charSequenceTargetRegister}, v${freeRegister} """ ) @@ -140,7 +139,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch( // endregion - // region Hook for Short videos. + // region Hook for non litho Short videos. ShortsTextViewFingerprint.result?.let { it.mutableMethod.apply { @@ -150,7 +149,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch( val isDisLikesBooleanReference = getInstruction(patternResult.endIndex).reference val textViewFieldReference = // Like/Dislike button TextView field - getInstruction(patternResult.endIndex - 2).reference + getInstruction(patternResult.endIndex - 1).reference // Check if the hooked TextView object is that of the dislike button. // If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted. @@ -180,6 +179,13 @@ object ReturnYouTubeDislikePatch : BytecodePatch( // endregion + // region Hook for litho Shorts + + // Filter that parses the video id from the UI + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + // endregion + // region Hook old UI layout dislikes, for the older app spoofs used with spoof-app-version. DislikesOldLayoutTextViewFingerprint.result?.let { 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 a012ad54b..c5efc64e4 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 @@ -27,7 +27,6 @@ object ShortsTextViewFingerprint : MethodFingerprint( Opcode.IF_EQ, Opcode.RETURN_VOID, Opcode.IGET_OBJECT, // TextView field - Opcode.CHECK_CAST, Opcode.IGET_BOOLEAN, // boolean field ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt index 069ec8bb6..b929e2c11 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt @@ -13,13 +13,17 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint( accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, parameters = listOf("L"), opcodes = listOf( - Opcode.MOVE_OBJECT, // Register A and B is context, use B as context, reuse A as free register + Opcode.MOVE_OBJECT, // Register B is free register + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, Opcode.INVOKE_VIRTUAL, // Register C is atomic reference Opcode.MOVE_RESULT_OBJECT, // Register A is char sequence - Opcode.MOVE_OBJECT, Opcode.CHECK_CAST, - Opcode.MOVE_OBJECT, - Opcode.INVOKE_INTERFACE, // Insert hook here + Opcode.MOVE_OBJECT, // Replace this instruction with patch code + Opcode.INVOKE_INTERFACE, Opcode.MOVE_RESULT, Opcode.IF_EQZ, Opcode.INVOKE_INTERFACE, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt index 9c2e7d7e7..c23573bc2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt @@ -13,12 +13,14 @@ object TextComponentContextFingerprint : MethodFingerprint( accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, parameters = listOf("L"), opcodes = listOf( + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, + Opcode.INVOKE_STATIC_RANGE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, Opcode.IGET_OBJECT, // conversion context field name - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_BOOLEAN, - Opcode.IGET, - Opcode.IGET, - Opcode.IGET, ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt index 900e1c296..a742152e5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt @@ -28,7 +28,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt index ddc1e9c15..89903001c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt @@ -45,7 +45,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt index b8684cec5..6a569ff93 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt @@ -29,7 +29,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableShortsOnStartupPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableShortsOnStartupPatch.kt index 4db654652..7b90a378b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableShortsOnStartupPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableShortsOnStartupPatch.kt @@ -24,7 +24,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt index 774ccd352..8ee252846 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt @@ -34,7 +34,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ) ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt index 6a97db107..093eb6100 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt @@ -26,7 +26,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt index 1238fdb2e..90a0ce3f8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt @@ -30,7 +30,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt index 2bf64166b..3afec9416 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt @@ -25,7 +25,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt index b164b1582..14b3f78c7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt @@ -29,7 +29,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt index fecf51010..92166fa35 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt @@ -29,7 +29,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/MicroGBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/MicroGBytecodePatch.kt index 01af68664..9d33bcfe4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/MicroGBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/MicroGBytecodePatch.kt @@ -29,7 +29,8 @@ import app.revanced.util.microg.MicroGBytecodeHelper "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt index eb94ba06c..31b5c9af4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt @@ -35,7 +35,8 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsBytecodePatch.kt index f3962f82e..1bb771370 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsBytecodePatch.kt @@ -58,7 +58,7 @@ object PlayerControlsBytecodePatch : BytecodePatch( * @param descriptor The descriptor of the method which should be calleed. */ fun initializeControl(descriptor: String) { - inflateFingerprintResult!!.mutableMethod.addInstruction( + inflateFingerprintResult.mutableMethod.addInstruction( moveToRegisterInstructionIndex + 1, "invoke-static {v$viewRegister}, $descriptor" ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt index c92a743a8..614cfcaf1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt @@ -27,7 +27,8 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt index d9008763f..16aae93e5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt @@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt index 8b621518b..4ced038b2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt @@ -19,7 +19,8 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/OldVideoQualityMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/OldVideoQualityMenuPatch.kt index 602587c24..c8ebeebf8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/OldVideoQualityMenuPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/OldVideoQualityMenuPatch.kt @@ -29,7 +29,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.23.35", "18.29.38", "18.32.39", - "18.37.36" + "18.37.36", + "18.38.44" ] ) ]