diff --git a/CHANGELOG.md b/CHANGELOG.md index 15512ca92..a9008310a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,51 @@ +# [2.173.0](https://github.com/revanced/revanced-patches/compare/v2.172.0...v2.173.0) (2023-05-02) + + +### Features + +* **youtube/create-button:** switch create with notifications button ([385ceda](https://github.com/revanced/revanced-patches/commit/385ceda61f586f24b11a284688f55758ef5b4e74)) +* **youtube/theme:** change seekbar color via preference ([9b465d9](https://github.com/revanced/revanced-patches/commit/9b465d95887863f6b42baa6b710ed98c97383a82)) +* **youtube/theme:** theme seekbar when clicked ([691a231](https://github.com/revanced/revanced-patches/commit/691a231d99b3b2fbe446fc7edb7a88c7a3127037)) +* **youtube:** `navigation-buttons` patch ([4bece31](https://github.com/revanced/revanced-patches/commit/4bece31f56eb340933ad26da3d1bfc902ea8569f)) +* **youtube:** bump compatibility to `18.16.37` ([fe3fdd5](https://github.com/revanced/revanced-patches/commit/fe3fdd5c6cb186bcebc2f86b1d5b597109b25cb6)) +* **youtube:** support version `18.16.37` ([8beb5ea](https://github.com/revanced/revanced-patches/commit/8beb5ea860284be915c0ef0c6039821a50c14fa8)) + +# [2.173.0-dev.5](https://github.com/revanced/revanced-patches/compare/v2.173.0-dev.4...v2.173.0-dev.5) (2023-05-02) + + +### Features + +* **youtube:** `navigation-buttons` patch ([4bece31](https://github.com/revanced/revanced-patches/commit/4bece31f56eb340933ad26da3d1bfc902ea8569f)) + +# [2.173.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.173.0-dev.3...v2.173.0-dev.4) (2023-05-02) + + +### Features + +* **youtube/create-button:** switch create with notifications button ([385ceda](https://github.com/revanced/revanced-patches/commit/385ceda61f586f24b11a284688f55758ef5b4e74)) + +# [2.173.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.173.0-dev.2...v2.173.0-dev.3) (2023-05-02) + + +### Features + +* **youtube/theme:** theme seekbar when clicked ([691a231](https://github.com/revanced/revanced-patches/commit/691a231d99b3b2fbe446fc7edb7a88c7a3127037)) + +# [2.173.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.173.0-dev.1...v2.173.0-dev.2) (2023-05-02) + + +### Features + +* **youtube/theme:** change seekbar color via preference ([9b465d9](https://github.com/revanced/revanced-patches/commit/9b465d95887863f6b42baa6b710ed98c97383a82)) + +# [2.173.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.172.0...v2.173.0-dev.1) (2023-05-02) + + +### Features + +* **youtube:** bump compatibility to `18.16.37` ([fe3fdd5](https://github.com/revanced/revanced-patches/commit/fe3fdd5c6cb186bcebc2f86b1d5b597109b25cb6)) +* **youtube:** support version `18.16.37` ([8beb5ea](https://github.com/revanced/revanced-patches/commit/8beb5ea860284be915c0ef0c6039821a50c14fa8)) + # [2.172.0](https://github.com/revanced/revanced-patches/compare/v2.171.0...v2.172.0) (2023-05-01) diff --git a/README-template.md b/README-template.md index f9ddf51ba..239d7dd3d 100644 --- a/README-template.md +++ b/README-template.md @@ -28,95 +28,3 @@ The file contains an array of objects, each object representing a patch. The obj | `compatiblePackages` | An array of packages compatible with this patch. | | `compatiblePackages.name` | The name of the package. | | `compatiblePackages.versions` | An array of versions of the package compatible with this patch. If empty, all versions are seemingly compatible. | - -Example: - -```json -[ - { - "name": "remember-video-quality", - "description": "Adds the ability to remember the video quality you chose in the video quality flyout.", - "version": "0.0.1", - "excluded": false, - "options": [], - "dependencies": [ - "integrations", - "video-id-hook" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [ - "17.22.36", - "17.24.35", - "17.26.35", - "17.27.39", - "17.28.34", - "17.29.34", - "17.32.35", - "17.33.42" - ] - } - ] - }, - { - "name": "theme", - "description": "Enables a custom theme.", - "version": "0.0.1", - "excluded": false, - "deprecated": false, - "options": [ - { - "key": "theme", - "title": "Theme", - "description": "Select a theme.", - "required": true, - "choices": [ - "Amoled" - ] - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - }, - { - "name": "custom-branding", - "description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).", - "version": "0.0.1", - "excluded": false, - "deprecated": false, - "options": [ - { - "key": "appName", - "title": "Application Name", - "description": "The name of the application it will show on your home screen.", - "required": true, - "choices": null - }, - { - "key": "appIconPath", - "title": "Application Icon Path", - "description": "A path to the icon of the application.", - "required": false, - "choices": null - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - } -] -``` \ No newline at end of file diff --git a/README.md b/README.md index 68d15b9d2..0a8b80cff 100644 --- a/README.md +++ b/README.md @@ -4,371 +4,22 @@ The official Patch bundle provided by ReVanced and the community. > Looking for the JSON variant of this? [Click here](patches.json). -### [📦 `com.google.android.youtube`](https://play.google.com/store/apps/details?id=com.google.android.youtube) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `always-autorepeat` | Always repeats the playing video again. | 18.15.40 | -| `client-spoof` | Spoofs a patched client to allow playback. | all | -| `comments` | Hides components related to comments. | 18.15.40 | -| `copy-video-url` | Adds buttons in player to copy video links. | 18.15.40 | -| `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all | -| `custom-video-buffer` | Lets you change the buffers of videos. | 18.15.40 | -| `custom-video-speed` | Adds more video speed options. | 18.15.40 | -| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 18.15.40 | -| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 18.15.40 | -| `disable-player-popup-panels` | Disables panels from appearing automatically when going into fullscreen (playlist or live chat). | 18.15.40 | -| `disable-shorts-on-startup` | Disables playing YouTube Shorts when launching YouTube. | 18.15.40 | -| `disable-zoom-haptics` | Disables haptics when zooming. | all | -| `downloads` | Enables downloading music and videos from YouTube. | 18.15.40 | -| `enable-debugging` | Adds debugging options. | all | -| `general-ads` | Removes general ads. | 18.15.40 | -| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 18.15.40 | -| `hide-album-cards` | Hides the album cards below the artist description. | 18.15.40 | -| `hide-artist-card` | Hides the artist card below the searchbar. | 18.15.40 | -| `hide-autoplay-button` | Hides the autoplay button in the video player. | 18.15.40 | -| `hide-breaking-news-shelf` | Hides the breaking news shelf on the homepage tab. | 18.15.40 | -| `hide-captions-button` | Hides the captions button on video player. | 18.15.40 | -| `hide-cast-button` | Hides the cast button in the video player. | all | -| `hide-create-button` | Hides the create button in the navigation bar. | 18.15.40 | -| `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 18.15.40 | -| `hide-email-address` | Hides the email address in the account switcher. | 18.15.40 | -| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 18.15.40 | -| `hide-floating-microphone-button` | Hides the floating microphone button which appears in search. | 18.15.40 | -| `hide-get-premium` | Hides advertisement for YouTube Premium under the video player. | 18.15.40 | -| `hide-info-cards` | Hides info cards in videos. | 18.15.40 | -| `hide-player-buttons` | Adds the option to hide video player previous and next buttons. | all | -| `hide-player-overlay` | Hides the dark player overlay when player controls are visible. | all | -| `hide-seekbar` | Hides the seekbar. | 18.15.40 | -| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 18.15.40 | -| `hide-timestamp` | Hides timestamp in video player. | 18.15.40 | -| `hide-video-action-buttons` | Adds the options to hide action buttons under a video. | 18.15.40 | -| `hide-watch-in-vr` | Hides the option to watch in VR from the player settings flyout panel. | 18.15.40 | -| `hide-watermark` | Hides creator's watermarks on videos. | 18.15.40 | -| `minimized-playback` | Enables minimized and background playback. | 18.15.40 | -| `old-quality-layout` | Enables the original video quality flyout in the video player settings | 18.15.40 | -| `open-links-externally` | Open links outside of the app directly in your browser. | 18.15.40 | -| `premium-heading` | Shows premium branding on the home screen. | all | -| `remember-playback-speed` | Adds the ability to remember the playback speed you chose in the video playback speed flyout. | 18.15.40 | -| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 18.15.40 | -| `remove-player-button-background` | Removes the background from the video player buttons. | 18.15.40 | -| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 18.15.40 | -| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 18.15.40 | -| `sponsorblock` | Integrates SponsorBlock which allows skipping video segments such as sponsored content. | 18.15.40 | -| `spoof-app-version` | Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI. | 18.15.40 | -| `spoof-signature-verification` | Spoofs a patched client to prevent playback issues. | 18.15.40 | -| `swipe-controls` | Adds volume and brightness swipe controls. | 18.15.40 | -| `tablet-mini-player` | Enables the tablet mini player layout. | 18.15.40 | -| `theme` | Applies a custom theme. | all | -| `vanced-microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 18.15.40 | -| `video-ads` | Removes ads in the video player. | 18.15.40 | -| `wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 18.15.40 | -
- -### [📦 `com.google.android.apps.youtube.music`](https://play.google.com/store/apps/details?id=com.google.android.apps.youtube.music) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `background-play` | Enables playing music in the background. | all | -| `bypass-certificate-checks` | Bypasses certificate checks which prevent YouTube Music from working on Android Auto. | 5.39.52 | -| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | all | -| `compact-header` | Hides the music category bar at the top of the homepage. | all | -| `exclusive-audio-playback` | Enables the option to play music without video. | all | -| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.39.52 | -| `minimized-playback-music` | Enables minimized playback on Kids music. | all | -| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | all | -| `music-video-ads` | Removes ads in the music player. | all | -| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | all | -| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | all | -
- -### [📦 `com.ss.android.ugc.trill`](https://play.google.com/store/apps/details?id=com.ss.android.ugc.trill) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-login-requirement` | Do not force login. | all | -| `downloads` | Removes download restrictions and changes the default path to download to. | 27.8.3 | -| `feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | 27.8.3 | -| `fix-google-login` | Allows logging in with a Google account. | all | -| `hide-ads` | Removes ads from TikTok. | all | -| `playback-speed` | Enables the playback speed option for all videos. | all | -| `settings` | Adds ReVanced settings to TikTok. | 27.8.3 | -| `show-seekbar` | Shows progress bar for all video. | all | -| `sim-spoof` | Spoofs the information which is retrieved from the sim-card. | 27.8.3 | -
- -### [📦 `com.zhiliaoapp.musically`](https://play.google.com/store/apps/details?id=com.zhiliaoapp.musically) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-login-requirement` | Do not force login. | all | -| `downloads` | Removes download restrictions and changes the default path to download to. | 27.8.3 | -| `feed-filter` | Filters tiktok videos: removing ads, removing livestreams. | 27.8.3 | -| `fix-google-login` | Allows logging in with a Google account. | all | -| `hide-ads` | Removes ads from TikTok. | all | -| `playback-speed` | Enables the playback speed option for all videos. | all | -| `settings` | Adds ReVanced settings to TikTok. | 27.8.3 | -| `show-seekbar` | Shows progress bar for all video. | all | -| `sim-spoof` | Spoofs the information which is retrieved from the sim-card. | 27.8.3 | -
- -### [📦 `tv.twitch.android.app`](https://play.google.com/store/apps/details?id=tv.twitch.android.app) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `block-audio-ads` | Blocks audio ads in streams and VODs. | 14.6.1 | -| `block-embedded-ads` | Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker. | 14.6.1 | -| `block-video-ads` | Blocks video ads in streams and VODs. | 14.6.1 | -| `debug-mode` | Enables Twitch's internal debugging mode. | all | -| `settings` | Adds settings menu to Twitch. | all | -| `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | all | -
- -### [📦 `com.twitter.android`](https://play.google.com/store/apps/details?id=com.twitter.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `dynamic-color` | Replaces the default Twitter Blue with the users Material You palette. | all | -| `hide-ads` | Hides ads. | all | -| `hide-recommended-users` | Hides recommended users. | all | -| `hide-views-stats` | Hides the view stats under tweets. | 9.71.0-release.0 | -
- -### [📦 `com.spotify.music`](https://play.google.com/store/apps/details?id=com.spotify.music) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-capture-restriction` | Allows capturing Spotify's audio output while screen sharing or screen recording. | all | -| `hide-premium-navbar` | Removes the premium tab from the navbar. | all | -| `spotify-theme` | Applies a custom theme. | all | -
- ### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage)
| 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | 2023.12.0 | -| `hide-subreddit-banner` | Hides banner ads from comments on subreddits. | 2023.12.0 | -| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all | -
- -### [📦 `com.vanced.android.youtube`](https://play.google.com/store/apps/details?id=com.vanced.android.youtube) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `client-spoof` | Spoofs a patched client to allow playback. | all | -| `hide-ads` | Removes general ads. | all | -
- -### [📦 `at.gv.bmf.bmf2go`](https://play.google.com/store/apps/details?id=at.gv.bmf.bmf2go) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-bootloader-detection` | Removes the check for an unlocked bootloader. | 2.2.0 | -| `remove-root-detection` | Removes the check for root permissions. | 2.2.0 | -
- -### [📦 `at.gv.oe.app`](https://play.google.com/store/apps/details?id=at.gv.oe.app) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-root-detection` | Removes the check for root permissions and unlocked bootloader. | all | -| `spoof-signature` | Spoofs the signature of the app. | all | -
- -### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `disable-ads` | Disables ads in HexEditor. | all | -
- -### [📦 `com.spotify.lite`](https://play.google.com/store/apps/details?id=com.spotify.lite) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `enable-on-demand` | Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads. | all | -
- -### [📦 `com.nis.app`](https://play.google.com/store/apps/details?id=com.nis.app) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-ads` | Removes ads from Inshorts. | all | -
- -### [📦 `com.facebook.orca`](https://play.google.com/store/apps/details?id=com.facebook.orca) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-inbox-ads` | Hides ads in inbox. | all | -
- -### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `hide-timeline-ads` | Removes ads from the timeline. | all | -
- -### [📦 `org.citra.citra_emu`](https://play.google.com/store/apps/details?id=org.citra.citra_emu) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `premium-unlock` | Unlocks premium functions. | all | -
- -### [📦 `org.citra.citra_emu.canary`](https://play.google.com/store/apps/details?id=org.citra.citra_emu.canary) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `premium-unlock` | Unlocks premium functions. | all | -
- -### [📦 `com.backdrops.wallpapers`](https://play.google.com/store/apps/details?id=com.backdrops.wallpapers) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `pro-unlock` | Unlocks pro-only functions. | 4.52 | -
- -### [📦 `de.dwd.warnapp`](https://play.google.com/store/apps/details?id=de.dwd.warnapp) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all | -
- -### [📦 `net.binarymode.android.irplus`](https://play.google.com/store/apps/details?id=net.binarymode.android.irplus) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-ads` | Removes all ads from the app. | all | -
- -### [📦 `eu.faircode.netguard`](https://play.google.com/store/apps/details?id=eu.faircode.netguard) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `remove-broadcasts-restriction` | Enables starting/stopping NetGuard via broadcasts. | all | -
- -### [📦 `com.dci.dev.androidtwelvewidgets`](https://play.google.com/store/apps/details?id=com.dci.dev.androidtwelvewidgets) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-paid-widgets` | Unlocks paid widgets of the app | all | -
- -### [📦 `com.microblink.photomath`](https://play.google.com/store/apps/details?id=com.microblink.photomath) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-plus` | Unlocks plus features. | 8.9.0 | -
- -### [📦 `io.yuka.android`](https://play.google.com/store/apps/details?id=io.yuka.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-premium` | Unlocks premium features. | all | -
- -### [📦 `com.teslacoilsw.launcher`](https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-prime` | Unlocks Nova Prime and all functions of the app. | all | -
- -### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all pro features. | all | -
- -### [📦 `org.totschnig.myexpenses`](https://play.google.com/store/apps/details?id=org.totschnig.myexpenses) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all professional features. | 3.4.9 | -
- -### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks pro features. | 4.6364 | -
- -### [📦 `com.ithebk.expensemanager`](https://play.google.com/store/apps/details?id=com.ithebk.expensemanager) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks pro features. | all | -
- -### [📦 `ginlemon.iconpackstudio`](https://play.google.com/store/apps/details?id=ginlemon.iconpackstudio) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all pro features. | all | -
- -### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-pro` | Unlocks all pro features. | all | -
- -### [📦 `com.ticktick.task`](https://play.google.com/store/apps/details?id=com.ticktick.task) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-themes` | Unlocks all themes that are inaccessible until a certain level is reached. | all | -
- -### [📦 `net.dinglisch.android.taskerm`](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm) -
- -| 💊 Patch | 📜 Description | 🏹 Target Version | -|:--------:|:--------------:|:-----------------:| -| `unlock-trial` | Unlocks the trial version. | all | +| `Custom branding name reddit` | Renames the Reddit app to the name specified in options.json. | all | +| `Disable screenshot popup` | Adds an option to disable the popup that shows up when taking a screenshot. | all | +| `Hide ads` | Adds options to hide ads. | all | +| `Hide navigation buttons` | Adds options to hide buttons in the navigation bar. | all | +| `Hide recently visited shelf` | Adds an option to hide the recently visited shelf in the sidebar. | all | +| `Open links directly` | Adds an option to skip over redirection URLs in external links. | all | +| `Open links externally` | Adds an option to always open links in your browser instead of in the in-app-browser. | all | +| `Premium icon` | Unlocks premium app icons. | all | +| `Remove subreddit dialog` | Adds options to remove the NSFW community warning and notifications suggestion dialogs by dismissing them automatically. | all | +| `Sanitize sharing links` | Adds an option to remove tracking query parameters from URLs when sharing links. | all | +| `Settings` | Adds ReVanced Extended settings to Reddit. | all |
@@ -395,95 +46,3 @@ The file contains an array of objects, each object representing a patch. The obj | `compatiblePackages` | An array of packages compatible with this patch. | | `compatiblePackages.name` | The name of the package. | | `compatiblePackages.versions` | An array of versions of the package compatible with this patch. If empty, all versions are seemingly compatible. | - -Example: - -```json -[ - { - "name": "remember-video-quality", - "description": "Adds the ability to remember the video quality you chose in the video quality flyout.", - "version": "0.0.1", - "excluded": false, - "options": [], - "dependencies": [ - "integrations", - "video-id-hook" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [ - "17.22.36", - "17.24.35", - "17.26.35", - "17.27.39", - "17.28.34", - "17.29.34", - "17.32.35", - "17.33.42" - ] - } - ] - }, - { - "name": "theme", - "description": "Enables a custom theme.", - "version": "0.0.1", - "excluded": false, - "deprecated": false, - "options": [ - { - "key": "theme", - "title": "Theme", - "description": "Select a theme.", - "required": true, - "choices": [ - "Amoled" - ] - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - }, - { - "name": "custom-branding", - "description": "Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).", - "version": "0.0.1", - "excluded": false, - "deprecated": false, - "options": [ - { - "key": "appName", - "title": "Application Name", - "description": "The name of the application it will show on your home screen.", - "required": true, - "choices": null - }, - { - "key": "appIconPath", - "title": "Application Icon Path", - "description": "A path to the icon of the application.", - "required": false, - "choices": null - } - ], - "dependencies": [ - "locale-config-fix" - ], - "compatiblePackages": [ - { - "name": "com.google.android.youtube", - "versions": [] - } - ] - } -] -``` \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index dff3d309d..2d62c50e9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,7 @@ +import org.gradle.kotlin.dsl.support.listFilesOrdered + plugins { - kotlin("jvm") version "1.8.10" + kotlin("jvm") version "1.9.23" } group = "app.revanced" @@ -11,19 +13,31 @@ repositories { mavenCentral() mavenLocal() maven { - url = uri("https://maven.pkg.github.com/revanced/revanced-patcher") + url = uri("https://maven.pkg.github.com/revanced/multidexlib2") credentials { username = githubUsername password = githubPassword } } + maven { + url = uri("https://repo.sleeping.town") + content { + includeGroup("com.unascribed") + } + } } dependencies { - implementation("app.revanced:revanced-patcher:7.0.0") + implementation("app.revanced:revanced-patcher:8.0.0-arsclib") implementation("app.revanced:multidexlib2:2.5.3-a3836654") // Required for meta implementation("com.google.code.gson:gson:2.10.1") + // Required for FlexVer-Java + implementation("com.unascribed:flexver-java:1.1.1") +} + +kotlin { + jvmToolchain(17) } tasks { @@ -32,19 +46,20 @@ tasks { dependsOn(build) doLast { - val androidHome = System.getenv("ANDROID_HOME") ?: throw GradleException("ANDROID_HOME not found") - val d8 = "${androidHome}/build-tools/33.0.1/d8" - val input = configurations.archives.get().allArtifacts.files.files.first().absolutePath - val work = File("${buildDir}/libs") + val d8 = File(System.getenv("ANDROID_HOME")).resolve("build-tools") + .listFilesOrdered().last().resolve("d8").absolutePath + + val patchesJar = configurations.archives.get().allArtifacts.files.files.first().absolutePath + val workingDirectory = layout.buildDirectory.dir("libs").get().asFile exec { - workingDir = work - commandLine = listOf(d8, input) + workingDir = workingDirectory + commandLine = listOf(d8, "--release", patchesJar) } exec { - workingDir = work - commandLine = listOf("zip", "-u", input, "classes.dex") + workingDir = workingDirectory + commandLine = listOf("zip", "-u", patchesJar, "classes.dex") } } } diff --git a/gradle.properties b/gradle.properties index d14d383b8..1922a104f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ kotlin.code.style = official -version = 2.172.0 +version = 2.174.0 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79e..e6441136f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2c3425d49..381baa9ce 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,8 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cbb4..1aa94a426 100755 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f1..25da30dbd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/patches.json b/patches.json index 52361d2e4..08a87b10d 100644 --- a/patches.json +++ b/patches.json @@ -1 +1 @@ -[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50","5.48.52"]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]},{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","comments-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"custom-video-speed","description":"Adds more video speed options.","version":"0.0.1","excluded":false,"options":[{"key":"granularity","title":"Video speed granularity","description":"The granularity of the video speeds. The higher the value, the more speeds will be available.","required":true,"choices":null},{"key":"min","title":"Minimum video speed","description":"The minimum video speed.","required":true,"choices":null},{"key":"max","title":"Maximum video speed","description":"The maximum video speed. Must be greater than the minimum video speed and smaller than 5.","required":true,"choices":null}],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"disable-capture-restriction","description":"Allows capturing Spotify\u0027s audio output while screen sharing or screen recording.","version":"0.0.2","excluded":false,"options":[],"dependencies":["disable-capture-restriction-resource-patch"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"downloads","description":"Enables downloading music and videos from YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":true,"options":[{"key":"debuggable","title":"App debugging","description":"Whether to make the app debuggable on Android.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings","enable-android-debugging"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"general-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["GeneralAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"general-reddit-ads","description":"Removes general ads from the Reddit frontpage and subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2021.45.0","2022.43.0","2023.05.0","2023.06.0","2023.07.0","2023.07.1","2023.08.0","2023.09.0","2023.09.1","2023.10.0","2023.11.0","2023.12.0"]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-artist-card","description":"Hides the artist card below the searchbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-create-button","description":"Hides the create button in the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","resource-mapping","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52"]}]},{"name":"hide-get-premium","description":"Hides advertisement for YouTube Premium under the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.15.40"]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-player-overlay","description":"Hides the dark player overlay when player controls are visible.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-shorts-button","description":"Hides the shorts button on the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-subreddit-banner","description":"Hides banner ads from comments on subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2023.05.0","2023.06.0","2023.07.0","2023.07.1","2023.08.0","2023.09.0","2023.09.1","2023.10.0","2023.11.0","2023.12.0"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":[]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["music-microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"premium-unlock","description":"Unlocks premium functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.citra.citra_emu","versions":[]},{"name":"org.citra.citra_emu.canary","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-playback-speed","description":"Adds the ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","video-id-hook","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37","18.15.40"]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37","18.15.40"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-player-button-background","description":"Removes the background from the video player buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.15.40"]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37","18.15.40"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":[]}]},{"name":"spoof-signature-verification","description":"Spoofs a patched client to prevent playback issues.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","player-type-hook","client-spoof","video-id-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.15.40"]}]},{"name":"tasteBuilder-remover","description":"Removes the \"Tell us which artists you like\" card from the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"darkThemeSeekbarColor","title":"Dark theme seekbar color","description":"The background color of the seekbar of the dark theme. Leave empty for default color.","required":false,"choices":null}],"dependencies":["litho-components-theme"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.6.0","8.7.0","8.8.0","8.9.0","8.10.0","8.11.0","8.12.0","8.13.0","8.14.0","8.15.0","8.16.0","8.17.0","8.18.0","8.18.1","8.19.0","8.20.0","8.21.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364"]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]},{"name":"wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37","18.15.40"]}]}] \ No newline at end of file +[{"name":"Custom branding name reddit","description":"Renames the Reddit app to the name specified in options.json.","version":"0.0.0","excluded":false,"options":[{"key":"AppName","title":"App name","description":"The name of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Disable screenshot popup","description":"Adds an option to disable the popup that shows up when taking a screenshot.","version":"0.0.0","excluded":false,"options":[],"dependencies":["Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Hide ads","description":"Adds options to hide ads.","version":"0.0.0","excluded":false,"options":[],"dependencies":["BannerAdsPatch","CommentAdsPatch","Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Hide navigation buttons","description":"Adds options to hide buttons in the navigation bar.","version":"0.0.0","excluded":false,"options":[],"dependencies":["Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Hide recently visited shelf","description":"Adds an option to hide the recently visited shelf in the sidebar.","version":"0.0.0","excluded":false,"options":[],"dependencies":["Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Open links directly","description":"Adds an option to skip over redirection URLs in external links.","version":"0.0.0","excluded":false,"options":[],"dependencies":["Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Open links externally","description":"Adds an option to always open links in your browser instead of in the in-app-browser.","version":"0.0.0","excluded":false,"options":[],"dependencies":["Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Premium icon","description":"Unlocks premium app icons.","version":"0.0.0","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Remove subreddit dialog","description":"Adds options to remove the NSFW community warning and notifications suggestion dialogs by dismissing them automatically.","version":"0.0.0","excluded":false,"options":[],"dependencies":["Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Sanitize sharing links","description":"Adds an option to remove tracking query parameters from URLs when sharing links.","version":"0.0.0","excluded":false,"options":[],"dependencies":["Settings"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"Settings","description":"Adds ReVanced Extended settings to Reddit.","version":"0.0.0","excluded":false,"options":[],"dependencies":["reddit-integrations","SettingsBytecodePatch"],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]}] \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/extensions/Extensions.kt b/src/main/kotlin/app/revanced/extensions/Extensions.kt deleted file mode 100644 index 7c70f90c6..000000000 --- a/src/main/kotlin/app/revanced/extensions/Extensions.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.extensions - -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.util.proxy.mutableTypes.MutableClass -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import org.jf.dexlib2.iface.Method -import org.jf.dexlib2.util.MethodUtil -import org.w3c.dom.Node - -// TODO: populate this to all patches -/** - * Convert a [MethodFingerprint] to a [PatchResultError]. - * - * @return A [PatchResultError] for the [MethodFingerprint]. - */ -fun MethodFingerprint.toErrorResult() = PatchResultError("Failed to resolve $name") - -/** - * Find the [MutableMethod] from a given [Method] in a [MutableClass]. - * - * @param method The [Method] to find. - * @return The [MutableMethod]. - */ -fun MutableClass.findMutableMethodOf(method: Method) = this.methods.first { - MethodUtil.methodSignaturesMatch(it, method) -} - -/** - * apply a transform to all methods of the class - * - * @param transform the transformation function. original method goes in, transformed method goes out - */ -fun MutableClass.transformMethods(transform: MutableMethod.() -> MutableMethod) { - val transformedMethods = methods.map { it.transform() } - methods.clear() - methods.addAll(transformedMethods) -} - -internal fun Node.doRecursively(action: (Node) -> Unit) { - action(this) - for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action) -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt b/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt index 62667a331..6b3145529 100644 --- a/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt +++ b/src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt @@ -1,6 +1,6 @@ package app.revanced.meta -import app.revanced.patcher.data.Context +import app.revanced.patcher.Context import app.revanced.patcher.patch.Patch import app.revanced.patcher.util.patch.PatchBundle import java.io.File @@ -16,7 +16,7 @@ internal interface PatchesFileGenerator { File("build/libs/").listFiles()!!.first { it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar") }.absolutePath - ).loadPatches().also { + ).toList().also { if (it.isEmpty()) throw IllegalStateException("No patches found") }.let { bundle -> arrayOf(JsonGenerator(), ReadmeGenerator()).forEach { it.generate(bundle) } diff --git a/src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt b/src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt index 530ca0500..be7a4cfae 100644 --- a/src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt +++ b/src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt @@ -1,10 +1,11 @@ package app.revanced.meta -import app.revanced.patcher.data.Context +import app.revanced.patcher.Context import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages import app.revanced.patcher.extensions.PatchExtensions.description import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.patch.Patch +import com.unascribed.flexver.FlexVerComparator import java.io.File internal class ReadmeGenerator : PatchesFileGenerator { @@ -37,9 +38,8 @@ internal class ReadmeGenerator : PatchesFileGenerator { } }.let { commonMap -> commonMap.maxByOrNull { it.value }?.value?.let { - // This is not foolproof, because for example v1.0.0-dev.0 will be returned instead of v1.0.0-release. - // Unfortunately this can not be solved easily because versioning can be complex. - commonMap.entries.filter { mostCommon -> mostCommon.value == it }.maxBy { it.key }.key + commonMap.entries.filter { mostCommon -> mostCommon.value == it } + .maxOfWith(FlexVerComparator::compare, Map.Entry::key) } ?: "all" } diff --git a/src/main/kotlin/app/revanced/patches/all/activity/exportAll/patch/ExportAllActivitiesPatch.kt b/src/main/kotlin/app/revanced/patches/all/activity/exportAll/patch/ExportAllActivitiesPatch.kt deleted file mode 100644 index 14d88f8c4..000000000 --- a/src/main/kotlin/app/revanced/patches/all/activity/exportAll/patch/ExportAllActivitiesPatch.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.revanced.patches.all.activity.exportAll.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch - -@Patch(false) -@Name("export-all-activities") -@Description("Makes all app activities exportable.") -@Version("0.0.1") -class ExportAllActivitiesPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - context.xmlEditor["AndroidManifest.xml"].use { editor -> - val document = editor.file - val activities = document.getElementsByTagName("activity") - - for(i in 0..activities.length) { - activities.item(i)?.apply { - val exportedAttribute = attributes.getNamedItem(EXPORTED_FLAG) - - if (exportedAttribute != null) { - if (exportedAttribute.nodeValue != "true") - exportedAttribute.nodeValue = "true" - } - // Reason why the attribute is added in the case it does not exist: - // https://github.com/revanced/revanced-patches/pull/1751/files#r1141481604 - else document.createAttribute(EXPORTED_FLAG) - .apply { value = "true" } - .let(attributes::setNamedItem) - } - } - } - - return PatchResultSuccess() - } - - private companion object { - const val EXPORTED_FLAG = "android:exported" - } -} diff --git a/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt b/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt deleted file mode 100644 index ecdfc0e37..000000000 --- a/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt +++ /dev/null @@ -1,208 +0,0 @@ -package app.revanced.patches.all.connectivity.wifi.spoof.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.patch.annotations.RequiresIntegrations -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.util.patch.* -import org.jf.dexlib2.iface.ClassDef -import org.jf.dexlib2.iface.Method -import org.jf.dexlib2.iface.instruction.Instruction -import java.util.* - -@Patch(false) -@Name("spoof-wifi-connection") -@Description("Spoofs an existing Wi-Fi connection.") -@Version("0.0.1") -@RequiresIntegrations -internal class SpoofWifiPatch : AbstractTransformInstructionsPatch() { - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = "Lapp/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch" - const val INTEGRATIONS_CLASS_DESCRIPTOR = "${INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX};" - } - - // Information about method calls we want to replace - enum class MethodCall( - override val definedClassName: String, - override val methodName: String, - override val methodParams: Array, - override val returnType: String, - ): IMethodCall { - GetSystemService1( - "Landroid/content/Context;", - "getSystemService", - arrayOf("Ljava/lang/String;"), - "Ljava/lang/Object;", - ), - GetSystemService2( - "Landroid/content/Context;", - "getSystemService", - arrayOf("Ljava/lang/Class;"), - "Ljava/lang/Object;", - ), - GetActiveNetworkInfo( - "Landroid/net/ConnectivityManager;", - "getActiveNetworkInfo", - arrayOf(), - "Landroid/net/NetworkInfo;", - ), - IsConnected( - "Landroid/net/NetworkInfo;", - "isConnected", - arrayOf(), - "Z", - ), - IsConnectedOrConnecting( - "Landroid/net/NetworkInfo;", - "isConnectedOrConnecting", - arrayOf(), - "Z", - ), - IsAvailable( - "Landroid/net/NetworkInfo;", - "isAvailable", - arrayOf(), - "Z", - ), - GetState( - "Landroid/net/NetworkInfo;", - "getState", - arrayOf(), - "Landroid/net/NetworkInfo\$State;", - ), - GetDetailedState( - "Landroid/net/NetworkInfo;", - "getDetailedState", - arrayOf(), - "Landroid/net/NetworkInfo\$DetailedState;", - ), - IsActiveNetworkMetered( - "Landroid/net/ConnectivityManager;", - "isActiveNetworkMetered", - arrayOf(), - "Z", - ), - GetActiveNetwork( - "Landroid/net/ConnectivityManager;", - "getActiveNetwork", - arrayOf(), - "Landroid/net/Network;", - ), - GetNetworkInfo( - "Landroid/net/ConnectivityManager;", - "getNetworkInfo", - arrayOf("Landroid/net/Network;"), - "Landroid/net/NetworkInfo;", - ), - HasTransport( - "Landroid/net/NetworkCapabilities;", - "hasTransport", - arrayOf("I"), - "Z", - ), - HasCapability( - "Landroid/net/NetworkCapabilities;", - "hasCapability", - arrayOf("I"), - "Z", - ), - RegisterBestMatchingNetworkCallback( - "Landroid/net/ConnectivityManager;", - "registerBestMatchingNetworkCallback", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"), - "V", - ), - RegisterDefaultNetworkCallback1( - "Landroid/net/ConnectivityManager;", - "registerDefaultNetworkCallback", - arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"), - "V", - ), - RegisterDefaultNetworkCallback2( - "Landroid/net/ConnectivityManager;", - "registerDefaultNetworkCallback", - arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"), - "V", - ), - RegisterNetworkCallback1( - "Landroid/net/ConnectivityManager;", - "registerNetworkCallback", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"), - "V", - ), - RegisterNetworkCallback2( - "Landroid/net/ConnectivityManager;", - "registerNetworkCallback", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"), - "V", - ), - RegisterNetworkCallback3( - "Landroid/net/ConnectivityManager;", - "registerNetworkCallback", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"), - "V", - ), - RequestNetwork1( - "Landroid/net/ConnectivityManager;", - "requestNetwork", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"), - "V", - ), - RequestNetwork2( - "Landroid/net/ConnectivityManager;", - "requestNetwork", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "I"), - "V", - ), - RequestNetwork3( - "Landroid/net/ConnectivityManager;", - "requestNetwork", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"), - "V", - ), - RequestNetwork4( - "Landroid/net/ConnectivityManager;", - "requestNetwork", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"), - "V", - ), - RequestNetwork5( - "Landroid/net/ConnectivityManager;", - "requestNetwork", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;", "I"), - "V", - ), - UnregisterNetworkCallback1( - "Landroid/net/ConnectivityManager;", - "unregisterNetworkCallback", - arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"), - "V", - ), - UnregisterNetworkCallback2( - "Landroid/net/ConnectivityManager;", - "unregisterNetworkCallback", - arrayOf("Landroid/app/PendingIntent;"), - "V", - ); - } - - override fun filterMap( - classDef: ClassDef, - method: Method, - instruction: Instruction, - instructionIndex: Int - ) = filterMapInstruction35c( - INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX, - classDef, - instruction, - instructionIndex - ) - - override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) { - val (methodType, instruction, instructionIndex) = entry - methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex) - } -} diff --git a/src/main/kotlin/app/revanced/patches/all/interaction/gestures/patch/PredictiveBackGesturePatch.kt b/src/main/kotlin/app/revanced/patches/all/interaction/gestures/patch/PredictiveBackGesturePatch.kt deleted file mode 100644 index 05beb7bd5..000000000 --- a/src/main/kotlin/app/revanced/patches/all/interaction/gestures/patch/PredictiveBackGesturePatch.kt +++ /dev/null @@ -1,37 +0,0 @@ -package app.revanced.patches.all.interaction.gestures.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch - -@Patch(false) -@Name("predictive-back-gesture") -@Description("Enables the predictive back gesture introduced on Android 13.") -@Version("0.0.1") -class PredictiveBackGesturePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - context.xmlEditor["AndroidManifest.xml"].use { editor -> - val document = editor.file - - with(document.getElementsByTagName("application").item(0)) { - if (attributes.getNamedItem(FLAG) != null) return@with - - document.createAttribute(FLAG) - .apply { value = "true" } - .let(attributes::setNamedItem) - - } - } - - return PatchResultSuccess() - } - - private companion object { - const val FLAG = "android:enableOnBackInvokedCallback" - } -} diff --git a/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/EnableAndroidDebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/EnableAndroidDebuggingPatch.kt deleted file mode 100644 index 88199d036..000000000 --- a/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/EnableAndroidDebuggingPatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.all.misc.debugging.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.Patch -import org.w3c.dom.Element - -@Patch(false) -@Name("enable-android-debugging") -@Description("Enables Android debugging capabilities.") -@Version("0.0.1") -class EnableAndroidDebuggingPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - if (debuggable == true) { - context.xmlEditor["AndroidManifest.xml"].use { dom -> - val applicationNode = dom - .file - .getElementsByTagName("application") - .item(0) as Element - - // set application as debuggable - applicationNode.setAttribute("android:debuggable", "true") - } - } - - return PatchResultSuccess() - } - - companion object : OptionsContainer() { - var debuggable: Boolean? by option( - PatchOption.BooleanOption( - key = "debuggable", - default = false, - title = "App debugging", - description = "Whether to make the app debuggable on Android.", - ) - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/all/misc/packagename/patch/ChangePackageNamePatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/packagename/patch/ChangePackageNamePatch.kt deleted file mode 100644 index 20a754759..000000000 --- a/src/main/kotlin/app/revanced/patches/all/misc/packagename/patch/ChangePackageNamePatch.kt +++ /dev/null @@ -1,50 +0,0 @@ -package app.revanced.patches.all.misc.packagename.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.Patch -import org.w3c.dom.Element - -@Patch(false) -@Name("change-package-name") -@Description("Changes the package name.") -@Version("0.0.1") -class ChangePackageNamePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - packageName?.let { packageName -> - val packageNameRegex = Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$") - if (!packageName.matches(packageNameRegex)) - return PatchResultError("Invalid package name") - - var originalPackageName = "" - context.xmlEditor["AndroidManifest.xml"].use { editor -> - val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element - originalPackageName = manifest.getAttribute("package") - } - - if (!originalPackageName.matches(packageNameRegex)) - return PatchResultError("Failed to get the original package name") - - context["AndroidManifest.xml"].apply { - readText().replace(originalPackageName, packageName).let(::writeText) - } - - } ?: return PatchResultError("No package name provided") - - return PatchResultSuccess() - } - - companion object : OptionsContainer() { - var packageName: String? by option( - PatchOption.StringOption( - key = "packageName", - default = null, - title = "Package name", - description = "The name of the package to rename of the app.", - ) - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt b/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt deleted file mode 100644 index 8f4c71a31..000000000 --- a/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt +++ /dev/null @@ -1,59 +0,0 @@ -package app.revanced.patches.all.screenshot.removerestriction.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.patch.annotations.RequiresIntegrations -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.util.patch.* -import org.jf.dexlib2.iface.ClassDef -import org.jf.dexlib2.iface.Method -import org.jf.dexlib2.iface.instruction.Instruction -import java.util.* - -@Patch(false) -@Name("remove-screenshot-restriction") -@Description("Removes the restriction of taking screenshots in apps that normally wouldn't allow it.") -@Version("0.0.1") -@RequiresIntegrations -internal class RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch() { - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = - "Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch" - const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;" - } - - // Information about method calls we want to replace - enum class MethodCall( - override val definedClassName: String, - override val methodName: String, - override val methodParams: Array, - override val returnType: String - ): IMethodCall { - SetFlags( - "Landroid/view/Window;", - "setFlags", - arrayOf("I", "I"), - "V", - ); - } - - override fun filterMap( - classDef: ClassDef, - method: Method, - instruction: Instruction, - instructionIndex: Int - ) = filterMapInstruction35c( - INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX, - classDef, - instruction, - instructionIndex - ) - - override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) { - val (methodType, instruction, instructionIndex) = entry - methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex) - } -} diff --git a/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/annotations/ProUnlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/annotations/ProUnlockCompatibility.kt deleted file mode 100644 index 0159508b5..000000000 --- a/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/annotations/ProUnlockCompatibility.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.backdrops.misc.pro.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.backdrops.wallpapers", arrayOf("4.52"))]) -internal annotation class ProUnlockCompatibility diff --git a/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/fingerprints/ProUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/fingerprints/ProUnlockFingerprint.kt deleted file mode 100644 index 7deff0a9c..000000000 --- a/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/fingerprints/ProUnlockFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.backdrops.misc.pro.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object ProUnlockFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ - ), - customFingerprint = { it.definingClass == "Lcom/backdrops/wallpapers/data/local/DatabaseHandlerIAB;" && it.name == "lambda\$existPurchase\$0" } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/patch/ProUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/patch/ProUnlockPatch.kt deleted file mode 100644 index 0365284d8..000000000 --- a/src/main/kotlin/app/revanced/patches/backdrops/misc/pro/patch/ProUnlockPatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.backdrops.misc.pro.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.backdrops.misc.pro.annotations.ProUnlockCompatibility -import app.revanced.patches.backdrops.misc.pro.fingerprints.ProUnlockFingerprint -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@Name("pro-unlock") -@Description("Unlocks pro-only functions.") -@ProUnlockCompatibility -@Version("0.0.1") -class ProUnlockPatch : BytecodePatch( - listOf(ProUnlockFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = ProUnlockFingerprint.result ?: return PatchResultError("${ProUnlockFingerprint.name} not found") - - val moveRegisterInstruction = result.mutableMethod.instruction(result.scanResult.patternScanResult!!.endIndex - 1) - val register = (moveRegisterInstruction as OneRegisterInstruction).registerA - - result.mutableMethod.addInstructions( - result.scanResult.patternScanResult!!.endIndex, - """ - const/4 v$register, 0x1 - """ - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/citra/misc/premium/annotations/PremiumUnlockCompatbility.kt b/src/main/kotlin/app/revanced/patches/citra/misc/premium/annotations/PremiumUnlockCompatbility.kt deleted file mode 100644 index a40ee1443..000000000 --- a/src/main/kotlin/app/revanced/patches/citra/misc/premium/annotations/PremiumUnlockCompatbility.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.citra.misc.premium.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("org.citra.citra_emu"), Package("org.citra.citra_emu.canary")]) -internal annotation class PremiumUnlockCompatbility diff --git a/src/main/kotlin/app/revanced/patches/citra/misc/premium/fingerprints/PremiumUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/citra/misc/premium/fingerprints/PremiumUnlockFingerprint.kt deleted file mode 100644 index 347c31a2d..000000000 --- a/src/main/kotlin/app/revanced/patches/citra/misc/premium/fingerprints/PremiumUnlockFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.citra.misc.premium.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PremiumUnlockFingerprint : MethodFingerprint( - customFingerprint = { it.definingClass == "Lorg/citra/citra_emu/ui/main/MainActivity;" && it.name == "isPremiumActive" } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/citra/misc/premium/patch/PremiumUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/citra/misc/premium/patch/PremiumUnlockPatch.kt deleted file mode 100644 index 10d4eebea..000000000 --- a/src/main/kotlin/app/revanced/patches/citra/misc/premium/patch/PremiumUnlockPatch.kt +++ /dev/null @@ -1,37 +0,0 @@ -package app.revanced.patches.citra.misc.premium.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.citra.misc.premium.annotations.PremiumUnlockCompatbility -import app.revanced.patches.citra.misc.premium.fingerprints.PremiumUnlockFingerprint - -@Patch -@Name("premium-unlock") -@Description("Unlocks premium functions.") -@PremiumUnlockCompatbility -@Version("0.0.1") -class PremiumUnlockPatch : BytecodePatch( - listOf(PremiumUnlockFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = PremiumUnlockFingerprint.result ?: return PatchResultError("${PremiumUnlockFingerprint.name} not found") - - result.mutableMethod.addInstructions( - 0, - """ - const v0, 0x1 - return v0 - """ - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/fingerprints/BootStateFingerprint.kt b/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/fingerprints/BootStateFingerprint.kt deleted file mode 100644 index 766147aca..000000000 --- a/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/fingerprints/BootStateFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.finanzonline.detection.bootloader.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object BootStateFingerprint : MethodFingerprint( - "Z", - access = AccessFlags.PUBLIC.value, - strings = listOf("Boot state of device: %s"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/AttestationHelper;") - } -) diff --git a/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/fingerprints/BootloaderDetectionFingerprint.kt b/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/fingerprints/BootloaderDetectionFingerprint.kt deleted file mode 100644 index 2d24a6ccc..000000000 --- a/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/fingerprints/BootloaderDetectionFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.finanzonline.detection.bootloader.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object BootloaderDetectionFingerprint : MethodFingerprint( - "Z", - access = AccessFlags.PUBLIC.value, - strings = listOf("Creation of attestation key succeeded", "Creation of attestation key failed"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/AttestationHelper;") - } -) diff --git a/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/patch/BootloaderDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/patch/BootloaderDetectionPatch.kt deleted file mode 100644 index 0c763d628..000000000 --- a/src/main/kotlin/app/revanced/patches/finanzonline/detection/bootloader/patch/BootloaderDetectionPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.finanzonline.detection.bootloader.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.BootStateFingerprint -import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.BootloaderDetectionFingerprint -import app.revanced.patches.finanzonline.detection.shared.annotations.DetectionCompatibility - - -@Patch -@Name("remove-bootloader-detection") -@Description("Removes the check for an unlocked bootloader.") -@DetectionCompatibility -@Version("0.0.1") -class BootloaderDetectionPatch : BytecodePatch( - listOf(BootloaderDetectionFingerprint, BootStateFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - arrayOf(BootloaderDetectionFingerprint, BootStateFingerprint).forEach { fingerprint -> - fingerprint.result?.mutableMethod?.addInstruction( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) ?: return fingerprint.toErrorResult() - } - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/fingerprints/RootDetectionFingerprint.kt b/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/fingerprints/RootDetectionFingerprint.kt deleted file mode 100644 index b2e793da4..000000000 --- a/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/fingerprints/RootDetectionFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.finanzonline.detection.root.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object RootDetectionFingerprint : MethodFingerprint( - "L", - customFingerprint = { methodDef -> - methodDef.definingClass == "Lat/gv/bmf/bmf2go/tools/utils/z;" - } -) diff --git a/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/patch/RootDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/patch/RootDetectionPatch.kt deleted file mode 100644 index 4995e0705..000000000 --- a/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/patch/RootDetectionPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.finanzonline.detection.root.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.finanzonline.detection.root.fingerprints.RootDetectionFingerprint -import app.revanced.patches.finanzonline.detection.shared.annotations.DetectionCompatibility - -@Patch -@Name("remove-root-detection") -@Description("Removes the check for root permissions.") -@DetectionCompatibility -@Version("0.0.1") -class RootDetectionPatch : BytecodePatch( - listOf(RootDetectionFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - RootDetectionFingerprint.result?.mutableMethod?.addInstructions( - 0, - """ - sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean; - return-object v0 - """ - ) ?: return RootDetectionFingerprint.toErrorResult() - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/finanzonline/detection/shared/annotations/DetectionCompatibility.kt b/src/main/kotlin/app/revanced/patches/finanzonline/detection/shared/annotations/DetectionCompatibility.kt deleted file mode 100644 index 97ddeadb4..000000000 --- a/src/main/kotlin/app/revanced/patches/finanzonline/detection/shared/annotations/DetectionCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.finanzonline.detection.shared.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("at.gv.bmf.bmf2go", arrayOf("2.2.0"))]) -@Target(AnnotationTarget.CLASS) -internal annotation class DetectionCompatibility diff --git a/src/main/kotlin/app/revanced/patches/hexeditor/ad/annotations/HexEditorAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/hexeditor/ad/annotations/HexEditorAdsCompatibility.kt deleted file mode 100644 index 15fa03761..000000000 --- a/src/main/kotlin/app/revanced/patches/hexeditor/ad/annotations/HexEditorAdsCompatibility.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.hexeditor.ad.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.myprog.hexedit") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HexEditorAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/hexeditor/ad/fingerprints/PrimaryAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/hexeditor/ad/fingerprints/PrimaryAdsFingerprint.kt deleted file mode 100644 index 34c3e94af..000000000 --- a/src/main/kotlin/app/revanced/patches/hexeditor/ad/fingerprints/PrimaryAdsFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.hexeditor.ad.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PrimaryAdsFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("PreferencesHelper;") && methodDef.name == "isAdsDisabled" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/hexeditor/ad/patch/HexEditorAdsPatch.kt b/src/main/kotlin/app/revanced/patches/hexeditor/ad/patch/HexEditorAdsPatch.kt deleted file mode 100644 index 67bc0940d..000000000 --- a/src/main/kotlin/app/revanced/patches/hexeditor/ad/patch/HexEditorAdsPatch.kt +++ /dev/null @@ -1,39 +0,0 @@ -package app.revanced.patches.hexeditor.ad.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.extensions.replaceInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility -import app.revanced.patches.hexeditor.ad.fingerprints.PrimaryAdsFingerprint - -@Patch -@Name("disable-ads") -@Description("Disables ads in HexEditor.") -@HexEditorAdsCompatibility -@Version("0.0.1") -class HexEditorAdsPatch : BytecodePatch( - listOf( - PrimaryAdsFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = PrimaryAdsFingerprint.result!!.mutableMethod - - method.replaceInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/annotations/UnlockProCompatibility.kt b/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/annotations/UnlockProCompatibility.kt deleted file mode 100644 index e7a54f1f9..000000000 --- a/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/annotations/UnlockProCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.iconpackstudio.misc.pro.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("ginlemon.iconpackstudio")]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockProCompatibility diff --git a/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/fingerprints/CheckProFingerprint.kt b/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/fingerprints/CheckProFingerprint.kt deleted file mode 100644 index 945ef2ca9..000000000 --- a/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/fingerprints/CheckProFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.iconpackstudio.misc.pro.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CheckProFingerprint : MethodFingerprint( - "Z", - customFingerprint = { it.definingClass.endsWith("IPSPurchaseRepository;")} -) diff --git a/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/patch/UnlockProPatch.kt b/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/patch/UnlockProPatch.kt deleted file mode 100644 index a4a2d4f99..000000000 --- a/src/main/kotlin/app/revanced/patches/iconpackstudio/misc/pro/patch/UnlockProPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.iconpackstudio.misc.pro.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.iconpackstudio.misc.pro.annotations.UnlockProCompatibility -import app.revanced.patches.iconpackstudio.misc.pro.fingerprints.CheckProFingerprint - -@Patch -@Name("unlock-pro") -@Description("Unlocks all pro features.") -@UnlockProCompatibility -@Version("0.0.1") -class UnlockProPatch : BytecodePatch( - listOf( - CheckProFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = CheckProFingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/idaustria/detection/root/fingerprints/RootDetectionFingerprint.kt b/src/main/kotlin/app/revanced/patches/idaustria/detection/root/fingerprints/RootDetectionFingerprint.kt deleted file mode 100644 index a64808a5f..000000000 --- a/src/main/kotlin/app/revanced/patches/idaustria/detection/root/fingerprints/RootDetectionFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.idaustria.detection.root.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object RootDetectionFingerprint : MethodFingerprint( - "V", - access = AccessFlags.PUBLIC.value, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/DeviceIntegrityCheck;") - } -) diff --git a/src/main/kotlin/app/revanced/patches/idaustria/detection/root/patch/RootDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/idaustria/detection/root/patch/RootDetectionPatch.kt deleted file mode 100644 index 41f5929de..000000000 --- a/src/main/kotlin/app/revanced/patches/idaustria/detection/root/patch/RootDetectionPatch.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.idaustria.detection.root.patch - -import app.revanced.patcher.annotation.* -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.idaustria.detection.root.fingerprints.RootDetectionFingerprint -import app.revanced.patches.idaustria.detection.shared.annotations.DetectionCompatibility - -@Patch -@Name("remove-root-detection") -@Description("Removes the check for root permissions and unlocked bootloader.") -@DetectionCompatibility -@Version("0.0.1") -class RootDetectionPatch : BytecodePatch( - listOf(RootDetectionFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - RootDetectionFingerprint.result!!.mutableMethod.addInstructions(0, "return-void") - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/idaustria/detection/shared/annotations/DetectionCompatibility.kt b/src/main/kotlin/app/revanced/patches/idaustria/detection/shared/annotations/DetectionCompatibility.kt deleted file mode 100644 index dbc8d4619..000000000 --- a/src/main/kotlin/app/revanced/patches/idaustria/detection/shared/annotations/DetectionCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.idaustria.detection.shared.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("at.gv.oe.app")]) -@Target(AnnotationTarget.CLASS) -internal annotation class DetectionCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/fingerprints/SpoofSignatureFingerprint.kt b/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/fingerprints/SpoofSignatureFingerprint.kt deleted file mode 100644 index 34aa826a3..000000000 --- a/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/fingerprints/SpoofSignatureFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.idaustria.detection.signature.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object SpoofSignatureFingerprint : MethodFingerprint( - "L", - parameters = listOf("L"), - access = AccessFlags.PRIVATE.value, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/SL2Step1Task;") && methodDef.name == "getPubKey" - } -) diff --git a/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/patch/SpoofSignaturePatch.kt b/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/patch/SpoofSignaturePatch.kt deleted file mode 100644 index 71d713763..000000000 --- a/src/main/kotlin/app/revanced/patches/idaustria/detection/signature/patch/SpoofSignaturePatch.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.revanced.patches.idaustria.detection.signature.patch - -import app.revanced.patcher.annotation.* -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.idaustria.detection.shared.annotations.DetectionCompatibility -import app.revanced.patches.idaustria.detection.signature.fingerprints.SpoofSignatureFingerprint - -@Patch -@Name("spoof-signature") -@Description("Spoofs the signature of the app.") -@DetectionCompatibility -@Version("0.0.1") -class SpoofSignaturePatch : BytecodePatch( - listOf(SpoofSignatureFingerprint) -) { - companion object { - const val EXPECTED_SIGNATURE = "OpenSSLRSAPublicKey{modulus=ac3e6fd6050aa7e0d6010ae58190404cd89a56935b44f6fee" + - "067c149768320026e10b24799a1339e414605e448e3f264444a327b9ae292be2b62ad567dd1800dbed4a88f718a33dc6db6b" + - "f5178aa41aa0efff8a3409f5ca95dbfccd92c7b4298966df806ea7a0204a00f0e745f6d9f13bdf24f3df715d7b62c1600906" + - "15de1c8a956b9286764985a3b3c060963c435fb9481a5543aaf0671fc2dba6c5c2b17d1ef1d85137f14dc9bbdf3490288087" + - "324cd48341cce64fabf6a9b55d1a7bf23b2fcdff451fd85bf0c7feb0a5e884d7c5c078e413149566a12a686e6efa70ae5161" + - "a0201307692834cda336c55157fef125e67c01c1359886f94742105596b42a790404bbcda5dad6a65f115aaff5e45ef3c28b" + - "2316ff6cef07aa49a45aa58c07bf258051b13ef449ccb37a3679afd5cfb9132f70bb9d931a937897544f90c3bcc80ed012e9" + - "f6ba020b8cdc23f8c29ac092b88f0e370ff9434e4f0f359e614ae0868dc526fa41e4b7596533e8d10279b66e923ecd9f0b20" + - "0def55be2c1f6f9c72c92fb45d7e0a9ac571cb38f0a9a37bb33ea06f223fde8c7a92e8c47769e386f9799776e8f110c21df2" + - "77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" + - "bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}" - } - - override fun execute(context: BytecodeContext): PatchResult { - SpoofSignatureFingerprint.result!!.mutableMethod.addInstructions( - 0, - """ - const-string v0, "$EXPECTED_SIGNATURE" - return-object v0 - """ - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/inshorts/ad/annotations/HideAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/inshorts/ad/annotations/HideAdsCompatibility.kt deleted file mode 100644 index 372929a12..000000000 --- a/src/main/kotlin/app/revanced/patches/inshorts/ad/annotations/HideAdsCompatibility.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.inshorts.ad.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.nis.app")]) - -@Target(AnnotationTarget.CLASS) -internal annotation class HideAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/inshorts/ad/fingerprints/InshortsAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/inshorts/ad/fingerprints/InshortsAdsFingerprint.kt deleted file mode 100644 index 1cbb57933..000000000 --- a/src/main/kotlin/app/revanced/patches/inshorts/ad/fingerprints/InshortsAdsFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.inshorts.ad.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object InshortsAdsFingerprint : MethodFingerprint( - "V", - strings = listOf("GoogleAdLoader","exception in requestAd") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/inshorts/ad/patch/InshortsAdsPatch.kt b/src/main/kotlin/app/revanced/patches/inshorts/ad/patch/InshortsAdsPatch.kt deleted file mode 100644 index 7c809f6f8..000000000 --- a/src/main/kotlin/app/revanced/patches/inshorts/ad/patch/InshortsAdsPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.inshorts.ad.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.inshorts.ad.annotations.HideAdsCompatibility -import app.revanced.patches.inshorts.ad.fingerprints.InshortsAdsFingerprint - -@Patch -@Name("hide-ads") -@Description("Removes ads from Inshorts.") -@HideAdsCompatibility -@Version("0.0.1") -class HideAdsPatch : BytecodePatch( - listOf(InshortsAdsFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - InshortsAdsFingerprint.result?.let { result -> - result.apply { - mutableMethod.addInstruction( - 0, - """ - return-void - """ - ) - } - } ?: return InshortsAdsFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt deleted file mode 100644 index 3ae3fd824..000000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object MediaFingerprint : MethodFingerprint( - strings = listOf("force_overlay", "Media#updateFields", "live_reels_metadata") -) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt deleted file mode 100644 index 55d2dafe5..000000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object ShowAdFingerprint : MethodFingerprint( - "Z", - AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.FINAL, - listOf("L", "L", "Z", "Z"), - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.RETURN, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, - ), -) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt deleted file mode 100644 index f4988a135..000000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import org.jf.dexlib2.Opcode - -object GenericMediaAdFingerprint : MediaAdFingerprint( - opcodes = listOf( - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.CONST_4, - Opcode.RETURN, - ) -) { - override fun toString() = result!!.method.toString() -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt deleted file mode 100644 index d505347af..000000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.Method - -abstract class MediaAdFingerprint( - returnType: String? = "Z", - access: Int? = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters: Iterable? = listOf(), - opcodes: Iterable?, - customFingerprint: ((methodDef: Method) -> Boolean)? = null -) : MethodFingerprint( - returnType, - access, - parameters, - opcodes, - customFingerprint = customFingerprint -) { - abstract override fun toString(): String -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt deleted file mode 100644 index 0dfa62a77..000000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.MethodReference - -object PaidPartnershipAdFingerprint : MediaAdFingerprint( - "V", - null, - listOf("L", "L"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IPUT_BOOLEAN, - Opcode.IPUT_BOOLEAN - ), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("ClipsEditMetadataController;") - } -) { - override fun toString() = result!!.let { - val adCheckIndex = it.scanResult.patternScanResult!!.startIndex - val adCheckInstruction = it.method.implementation!!.instructions.elementAt(adCheckIndex) - - val adCheckMethod = (adCheckInstruction as ReferenceInstruction).reference as MethodReference - - adCheckMethod.toString() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt deleted file mode 100644 index 28bd08a2e..000000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import org.jf.dexlib2.Opcode - -object ShoppingAdFingerprint : MediaAdFingerprint( - opcodes = listOf( - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.XOR_INT_LIT8, - Opcode.IF_EQZ, - ) -) { - override fun toString() = result!!.method.toString() -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/patch/HideTimelineAdsPatch.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/patch/HideTimelineAdsPatch.kt deleted file mode 100644 index 5eb220cfc..000000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/patch/HideTimelineAdsPatch.kt +++ /dev/null @@ -1,108 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.* -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.MediaFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ShowAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.GenericMediaAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.MediaAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.PaidPartnershipAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.ShoppingAdFingerprint -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@Name("hide-timeline-ads") -@Description("Removes ads from the timeline.") -@Compatibility([Package("com.instagram.android")]) -@Version("0.0.1") -class HideTimelineAdsPatch : BytecodePatch( - listOf( - ShowAdFingerprint, - MediaFingerprint, - PaidPartnershipAdFingerprint // Unlike the other ads this one is resolved from all classes. - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - // region Resolve required methods to check for ads. - - ShowAdFingerprint.result ?: return ShowAdFingerprint.toErrorResult() - - PaidPartnershipAdFingerprint.result ?: return PaidPartnershipAdFingerprint.toErrorResult() - - MediaFingerprint.result?.let { - GenericMediaAdFingerprint.resolve(context, it.classDef) - ShoppingAdFingerprint.resolve(context, it.classDef) - - return@let - } ?: return MediaFingerprint.toErrorResult() - - // endregion - - ShowAdFingerprint.result!!.apply { - // region Create instructions. - - val scanStart = scanResult.patternScanResult!!.startIndex - val jumpIndex = scanStart - 1 - - val mediaInstanceRegister = (mutableMethod.instruction(scanStart) as FiveRegisterInstruction).registerC - val freeRegister = (mutableMethod.instruction(jumpIndex) as OneRegisterInstruction).registerA - - val returnFalseLabel = "an_ad" - - val checkForAdInstructions = - listOf(GenericMediaAdFingerprint, PaidPartnershipAdFingerprint, ShoppingAdFingerprint) - .map(MediaAdFingerprint::toString) - .joinToString("\n") { - """ - invoke-virtual {v$mediaInstanceRegister}, $it - move-result v$freeRegister - if-nez v$freeRegister, :$returnFalseLabel - """.trimIndent() - }.let { "$it\nconst/4 v0, 0x1\nreturn v0" } - - // endregion - - // region Patch. - - val insertIndex = scanStart + 3 - - mutableMethod.addInstructions( - insertIndex, - checkForAdInstructions, - listOf( - ExternalLabel( - returnFalseLabel, - mutableMethod.instruction(mutableMethod.implementation!!.instructions.size - 2 /* return false = ad */) - ) - ) - ) - - // endregion - - // region Jump to checks for ads from previous patch. - - mutableMethod.apply { - addInstructions( - jumpIndex + 1, - "if-nez v$freeRegister, :start_check", - listOf(ExternalLabel("start_check", instruction(insertIndex))) - ) - }.removeInstruction(jumpIndex) - - // endregion - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/irplus/ad/annotations/IrplusAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/irplus/ad/annotations/IrplusAdsCompatibility.kt deleted file mode 100644 index c7a4a56f1..000000000 --- a/src/main/kotlin/app/revanced/patches/irplus/ad/annotations/IrplusAdsCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.irplus.ad.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("net.binarymode.android.irplus")]) -@Target(AnnotationTarget.CLASS) -internal annotation class IrplusAdsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/irplus/ad/fingerprints/IrplusAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/irplus/ad/fingerprints/IrplusAdsFingerprint.kt deleted file mode 100644 index 061606b1c..000000000 --- a/src/main/kotlin/app/revanced/patches/irplus/ad/fingerprints/IrplusAdsFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.irplus.ad.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object IrplusAdsFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "Z"), - strings = listOf("TAGGED") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/irplus/ad/patch/IrplusAdsPatch.kt b/src/main/kotlin/app/revanced/patches/irplus/ad/patch/IrplusAdsPatch.kt deleted file mode 100644 index 9a7f0a66e..000000000 --- a/src/main/kotlin/app/revanced/patches/irplus/ad/patch/IrplusAdsPatch.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.revanced.patches.irplus.ad.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.irplus.ad.annotations.IrplusAdsCompatibility -import app.revanced.patches.irplus.ad.fingerprints.IrplusAdsFingerprint - - -@Patch -@Name("remove-ads") -@Description("Removes all ads from the app.") -@IrplusAdsCompatibility -@Version("0.0.1") -class IrplusAdsPatch : BytecodePatch( - listOf(IrplusAdsFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = IrplusAdsFingerprint.result!!.mutableMethod - - // By overwriting the second parameter of the method, - // the view which holds the advertisement is removed. - method.addInstruction(0, "const/4 p2, 0x0") - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/fingerprint/LicenseValidationFingerprint.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/fingerprint/LicenseValidationFingerprint.kt deleted file mode 100644 index 205bca30a..000000000 --- a/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/fingerprint/LicenseValidationFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.memegenerator.detection.license.fingerprint - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object LicenseValidationFingerprint : MethodFingerprint( - returnType = "Z", - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("Landroid/content/Context;"), - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_WIDE, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_WIDE, - Opcode.CMP_LONG, - Opcode.IF_GEZ, - Opcode.CONST_4, - Opcode.RETURN, - Opcode.CONST_4, - Opcode.RETURN - ) -) diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/patch/LicenseValidationPatch.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/patch/LicenseValidationPatch.kt deleted file mode 100644 index 6e514ff70..000000000 --- a/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/patch/LicenseValidationPatch.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.memegenerator.detection.license.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.replaceInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.memegenerator.detection.license.fingerprint.LicenseValidationFingerprint - -@Description("Disables Firebase license validation.") -@Version("0.0.1") -class LicenseValidationPatch : BytecodePatch( - listOf(LicenseValidationFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - LicenseValidationFingerprint.result?.apply { - mutableMethod.replaceInstructions( - 0, - """ - const/4 p0, 0x1 - return p0 - """ - ) - } ?: throw LicenseValidationFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/fingerprint/VerifySignatureFingerprint.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/fingerprint/VerifySignatureFingerprint.kt deleted file mode 100644 index 7c0304ebb..000000000 --- a/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/fingerprint/VerifySignatureFingerprint.kt +++ /dev/null @@ -1,35 +0,0 @@ -package app.revanced.patches.memegenerator.detection.signature.fingerprint - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) -object VerifySignatureFingerprint : MethodFingerprint( - returnType = "Z", - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("Landroid/app/Activity;"), - opcodes = listOf( - Opcode.SGET_OBJECT, - Opcode.IF_NEZ, - Opcode.INVOKE_STATIC, - Opcode.CONST_4, - Opcode.CONST_4, - Opcode.SGET_OBJECT, - Opcode.ARRAY_LENGTH, - Opcode.IF_GE, - Opcode.AGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.CONST_4, - Opcode.RETURN, - Opcode.ADD_INT_LIT8 - ), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/patch/SignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/patch/SignatureVerificationPatch.kt deleted file mode 100644 index 1b9ca3064..000000000 --- a/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/patch/SignatureVerificationPatch.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.memegenerator.detection.signature.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.replaceInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.memegenerator.detection.signature.fingerprint.VerifySignatureFingerprint - -@Description("Disables detection of incorrect signature.") -@Version("0.0.1") -class SignatureVerificationPatch : BytecodePatch( - listOf(VerifySignatureFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - VerifySignatureFingerprint.result?.apply { - mutableMethod.replaceInstructions( - 0, - """ - const/4 p0, 0x1 - return p0 - """ - ) - } ?: throw VerifySignatureFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/annotations/UnlockProCompatibility.kt b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/annotations/UnlockProCompatibility.kt deleted file mode 100644 index bf92bccaa..000000000 --- a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/annotations/UnlockProCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.memegenerator.misc.pro.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.zombodroid.MemeGenerator", arrayOf("4.6364"))]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockProCompatibility diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/fingerprint/IsFreeVersionFingerprint.kt b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/fingerprint/IsFreeVersionFingerprint.kt deleted file mode 100644 index be9b266ba..000000000 --- a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/fingerprint/IsFreeVersionFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.memegenerator.misc.pro.fingerprint - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object IsFreeVersionFingerprint : MethodFingerprint( - returnType = "Ljava/lang/Boolean;", - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - strings = listOf("free"), - parameters = listOf("Landroid/content/Context;"), - opcodes = listOf( - Opcode.SGET, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_STRING, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ - ) -) diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/patch/UnlockProVersionPatch.kt b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/patch/UnlockProVersionPatch.kt deleted file mode 100644 index c0c928e24..000000000 --- a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/patch/UnlockProVersionPatch.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.revanced.patches.memegenerator.misc.pro.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.replaceInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.memegenerator.detection.license.patch.LicenseValidationPatch -import app.revanced.patches.memegenerator.detection.signature.patch.SignatureVerificationPatch -import app.revanced.patches.memegenerator.misc.pro.annotations.UnlockProCompatibility -import app.revanced.patches.memegenerator.misc.pro.fingerprint.IsFreeVersionFingerprint - -@Patch -@Name("unlock-pro") -@Description("Unlocks pro features.") -@DependsOn([ - SignatureVerificationPatch::class, - LicenseValidationPatch::class -]) -@UnlockProCompatibility -@Version("0.0.1") -class UnlockProVersionPatch : BytecodePatch( - listOf( - IsFreeVersionFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - IsFreeVersionFingerprint.result?.apply { - mutableMethod.replaceInstructions(0, - """ - sget-object p0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean; - return-object p0 - """ - ) - } ?: throw IsFreeVersionFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/fingerprints/LoadInboxAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/fingerprints/LoadInboxAdsFingerprint.kt deleted file mode 100644 index c29b94448..000000000 --- a/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/fingerprints/LoadInboxAdsFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.messenger.ads.inbox.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object LoadInboxAdsFingerprint : MethodFingerprint( - returnType = "V", - strings = listOf( - "ads_load_begin", - "inbox_ads_fetch_start" - ), - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - customFingerprint = { - it.definingClass == "Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/InboxAdsItemSupplierImplementation;" - } -) - diff --git a/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/patch/HideInboxAdsPatch.kt b/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/patch/HideInboxAdsPatch.kt deleted file mode 100644 index f18a78d5f..000000000 --- a/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/patch/HideInboxAdsPatch.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patches.messenger.ads.inbox.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.* -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.messenger.ads.inbox.fingerprints.LoadInboxAdsFingerprint - -@Patch -@Name("hide-inbox-ads") -@Description("Hides ads in inbox.") -@Compatibility([Package("com.facebook.orca")]) -@Version("0.0.1") -class HideInboxAdsPatch : BytecodePatch( - listOf(LoadInboxAdsFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - LoadInboxAdsFingerprint.result?.mutableMethod?.apply { - this.replaceInstruction(0, "return-void") - } ?: return LoadInboxAdsFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} - diff --git a/src/main/kotlin/app/revanced/patches/moneymanager/annotations/UnlockProCompatibility.kt b/src/main/kotlin/app/revanced/patches/moneymanager/annotations/UnlockProCompatibility.kt deleted file mode 100644 index 7e4be16ac..000000000 --- a/src/main/kotlin/app/revanced/patches/moneymanager/annotations/UnlockProCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.moneymanager.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.ithebk.expensemanager")]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockProCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/moneymanager/fingerprints/UnlockProFingerprint.kt b/src/main/kotlin/app/revanced/patches/moneymanager/fingerprints/UnlockProFingerprint.kt deleted file mode 100644 index 9ea14f8ac..000000000 --- a/src/main/kotlin/app/revanced/patches/moneymanager/fingerprints/UnlockProFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.moneymanager.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object UnlockProFingerprint : MethodFingerprint( - "Z", - AccessFlags.STATIC or AccessFlags.SYNTHETIC, - parameters = listOf("L"), - opcodes = listOf( - Opcode.IGET_BOOLEAN, - Opcode.RETURN - ), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("MainActivity;") - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/moneymanager/patch/UnlockProPatch.kt b/src/main/kotlin/app/revanced/patches/moneymanager/patch/UnlockProPatch.kt deleted file mode 100644 index e857e7140..000000000 --- a/src/main/kotlin/app/revanced/patches/moneymanager/patch/UnlockProPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.moneymanager.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.moneymanager.annotations.UnlockProCompatibility -import app.revanced.patches.moneymanager.fingerprints.UnlockProFingerprint - -@Patch -@Name("unlock-pro") -@Description("Unlocks pro features.") -@UnlockProCompatibility -@Version("0.0.1") -class UnlockProPatch : BytecodePatch( - listOf(UnlockProFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - UnlockProFingerprint.result!!.mutableMethod.addInstructions( - 0, - """ - const/4 v0, 0x1 - - return v0 - """ - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/annotations/MusicVideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/annotations/MusicVideoAdsCompatibility.kt deleted file mode 100644 index 0910b502d..000000000 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/annotations/MusicVideoAdsCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.ad.video.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class MusicVideoAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsConstructorFingerprint.kt deleted file mode 100644 index dd60e2026..000000000 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsConstructorFingerprint.kt +++ /dev/null @@ -1,27 +0,0 @@ -package app.revanced.patches.music.ad.video.fingerprints -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf( - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST_4, - Opcode.IPUT_BOOLEAN, - Opcode.RETURN_VOID - ) -) diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsFingerprint.kt deleted file mode 100644 index d6d8a138d..000000000 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.music.ad.video.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object ShowMusicVideoAdsFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), listOf( - Opcode.IPUT_BOOLEAN, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) -) diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/patch/MusicVideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/patch/MusicVideoAdsPatch.kt deleted file mode 100644 index bbf484831..000000000 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/patch/MusicVideoAdsPatch.kt +++ /dev/null @@ -1,40 +0,0 @@ -package app.revanced.patches.music.ad.video.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.ad.video.annotations.MusicVideoAdsCompatibility -import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsConstructorFingerprint -import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerprint - -@Patch -@Name("music-video-ads") -@Description("Removes ads in the music player.") -@MusicVideoAdsCompatibility -@Version("0.0.1") -class MusicVideoAdsPatch : BytecodePatch( - listOf( - ShowMusicVideoAdsConstructorFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - ShowMusicVideoAdsFingerprint.resolve(context, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef) - - val result = ShowMusicVideoAdsFingerprint.result!! - - result.mutableMethod.addInstructions( - result.scanResult.patternScanResult!!.startIndex, """ - const/4 p1, 0x0 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt deleted file mode 100644 index cefdb7798..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.audio.codecs.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class CodecsUnlockCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/fingerprints/AllCodecsReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/fingerprints/AllCodecsReferenceFingerprint.kt deleted file mode 100644 index 92f047d54..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/fingerprints/AllCodecsReferenceFingerprint.kt +++ /dev/null @@ -1,52 +0,0 @@ -package app.revanced.patches.music.audio.codecs.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object AllCodecsReferenceFingerprint : MethodFingerprint( - "J", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.MOVE_EXCEPTION, - Opcode.INVOKE_SUPER, - Opcode.MOVE_RESULT_WIDE, - Opcode.RETURN_WIDE - ), listOf("itag") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/fingerprints/CodecsLockFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/fingerprints/CodecsLockFingerprint.kt deleted file mode 100644 index 8ab87777b..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/fingerprints/CodecsLockFingerprint.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patches.music.audio.codecs.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object CodecsLockFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, opcodes = listOf( - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_OBJECT - ), - strings = listOf("eac3_supported") -) diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt deleted file mode 100644 index 9ff6916b8..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt +++ /dev/null @@ -1,56 +0,0 @@ -package app.revanced.patches.music.audio.codecs.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.toInstruction -import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility -import app.revanced.patches.music.audio.codecs.fingerprints.AllCodecsReferenceFingerprint -import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprint -import org.jf.dexlib2.Opcode - -@Patch -@Name("codecs-unlock") -@Description("Adds more audio codec options. The new audio codecs usually result in better audio quality.") -@CodecsUnlockCompatibility -@Version("0.0.1") -class CodecsUnlockPatch : BytecodePatch( - listOf( - CodecsLockFingerprint, AllCodecsReferenceFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val codecsLockResult = CodecsLockFingerprint.result!! - - val implementation = codecsLockResult.mutableMethod.implementation!! - - val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex - val instructionIndex = scanResultStartIndex + - if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) { - // for 5.16.xx and lower - -3 - } else { - // since 5.17.xx - -2 - } - - val allCodecsResult = AllCodecsReferenceFingerprint.result!! - val allCodecsMethod = - context.toMethodWalker(allCodecsResult.method) - .nextMethod(allCodecsResult.scanResult.patternScanResult!!.startIndex) - .getMethod() - - implementation.replaceInstruction( - instructionIndex, - "invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction() - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt deleted file mode 100644 index ac0ec5ba3..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.audio.exclusiveaudio.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class ExclusiveAudioCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/AudioOnlyEnablerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/AudioOnlyEnablerFingerprint.kt deleted file mode 100644 index 29c90b666..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/AudioOnlyEnablerFingerprint.kt +++ /dev/null @@ -1,28 +0,0 @@ -package app.revanced.patches.music.audio.exclusiveaudio.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object AudioOnlyEnablerFingerprint: MethodFingerprint( - "Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.GOTO, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.RETURN - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/ExclusiveAudioFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/ExclusiveAudioFingerprint.kt deleted file mode 100644 index 02eb60adc..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/fingerprints/ExclusiveAudioFingerprint.kt +++ /dev/null @@ -1,51 +0,0 @@ -package app.revanced.patches.music.audio.exclusiveaudio.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object ExclusiveAudioFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L", "Z"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQ, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.NOP, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_EQZ, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/patch/ExclusiveAudioPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/patch/ExclusiveAudioPatch.kt deleted file mode 100644 index d679e8702..000000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/patch/ExclusiveAudioPatch.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.revanced.patches.music.audio.exclusiveaudio.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility -import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AudioOnlyEnablerFingerprint - -@Patch -@Name("exclusive-audio-playback") -@Description("Enables the option to play music without video.") -@ExclusiveAudioCompatibility -@Version("0.0.1") -class ExclusiveAudioPatch : BytecodePatch( - listOf( - AudioOnlyEnablerFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = AudioOnlyEnablerFingerprint.result!!.mutableMethod - method.replaceInstruction(method.implementation!!.instructions.count() - 1, "const/4 v0, 0x1") - method.addInstruction("return v0") - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/annotations/CompactHeaderCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/annotations/CompactHeaderCompatibility.kt deleted file mode 100644 index 573e6452e..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/annotations/CompactHeaderCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.layout.compactheader.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class CompactHeaderCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/CompactHeaderConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/CompactHeaderConstructorFingerprint.kt deleted file mode 100644 index 661c138d7..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/CompactHeaderConstructorFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.music.layout.compactheader.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object CompactHeaderConstructorFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L"), listOf( - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST - ) -) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/patch/CompactHeaderPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/patch/CompactHeaderPatch.kt deleted file mode 100644 index 879dfa0c0..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/patch/CompactHeaderPatch.kt +++ /dev/null @@ -1,41 +0,0 @@ -package app.revanced.patches.music.layout.compactheader.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.layout.compactheader.annotations.CompactHeaderCompatibility -import app.revanced.patches.music.layout.compactheader.fingerprints.CompactHeaderConstructorFingerprint -import org.jf.dexlib2.builder.instruction.BuilderInstruction11x - -@Patch(false) -@Name("compact-header") -@Description("Hides the music category bar at the top of the homepage.") -@CompactHeaderCompatibility -@Version("0.0.1") -class CompactHeaderPatch : BytecodePatch( - listOf( - CompactHeaderConstructorFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = CompactHeaderConstructorFingerprint.result!! - val method = result.mutableMethod - - val insertIndex = result.scanResult.patternScanResult!!.endIndex - val register = (method.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA - method.addInstructions( - insertIndex, """ - const/16 v2, 0x8 - invoke-virtual {v${register}, v2}, Landroid/view/View;->setVisibility(I)V - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt deleted file mode 100644 index 7045f279e..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.layout.minimizedplayback.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class MinimizedPlaybackCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt deleted file mode 100644 index eb3d28a08..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.music.layout.minimizedplayback.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object MinimizedPlaybackManagerFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("I", "L", "Z"), - listOf( - Opcode.IGET, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.IF_NE, - Opcode.IGET_BOOLEAN, - Opcode.IF_EQ, - Opcode.GOTO, - Opcode.RETURN_VOID, - Opcode.SGET_OBJECT, - Opcode.CONST_4, - Opcode.IF_NE, - Opcode.IPUT_BOOLEAN, - ) -) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/patch/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/patch/MinimizedPlaybackPatch.kt deleted file mode 100644 index dcfdb9f05..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/patch/MinimizedPlaybackPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.layout.minimizedplayback.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility -import app.revanced.patches.music.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint - -@Patch -@Name("minimized-playback-music") -@Description("Enables minimized playback on Kids music.") -@MinimizedPlaybackCompatibility -@Version("0.0.1") -class MinimizedPlaybackPatch : BytecodePatch( - listOf( - MinimizedPlaybackManagerFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - MinimizedPlaybackManagerFingerprint.result!!.mutableMethod.addInstructions( - 0, """ - return-void - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/premium/annotations/HideGetPremiumCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/premium/annotations/HideGetPremiumCompatibility.kt deleted file mode 100644 index 134720211..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/premium/annotations/HideGetPremiumCompatibility.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.music.layout.premium.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.apps.youtube.music", - arrayOf( - "5.14.53", - "5.16.51", - "5.17.51", - "5.21.52", - "5.22.54", - "5.23.50", - "5.25.51", - "5.25.52", - "5.26.52", - "5.27.51", - "5.28.52", - "5.29.52", - "5.31.50", - "5.34.51", - "5.36.51", - "5.38.53", - "5.39.52" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideGetPremiumCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumFingerprint.kt deleted file mode 100644 index 5b89674cc..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.music.layout.premium.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object HideGetPremiumFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.IF_NEZ, - Opcode.CONST_16, - Opcode.GOTO, - Opcode.NOP, - Opcode.INVOKE_VIRTUAL - ) -) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumParentFingerprint.kt deleted file mode 100644 index d91ff64a4..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumParentFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.music.layout.premium.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object HideGetPremiumParentFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.IGET_BOOLEAN, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC - ), - listOf("FEmusic_history"), -) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/premium/patch/HideGetPremiumPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/premium/patch/HideGetPremiumPatch.kt deleted file mode 100644 index 727ff9dd9..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/premium/patch/HideGetPremiumPatch.kt +++ /dev/null @@ -1,51 +0,0 @@ -package app.revanced.patches.music.layout.premium.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.layout.premium.annotations.HideGetPremiumCompatibility -import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint -import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumParentFingerprint - -@Patch -@Name("hide-get-premium") -@Description("Removes all \"Get Premium\" evidences from the avatar menu.") -@HideGetPremiumCompatibility -@Version("0.0.1") -class HideGetPremiumPatch : BytecodePatch( - listOf( - HideGetPremiumParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val parentResult = HideGetPremiumParentFingerprint.result!! - HideGetPremiumFingerprint.resolve(context, parentResult.classDef) - - val startIndex = parentResult.scanResult.patternScanResult!!.startIndex - - val parentMethod = parentResult.mutableMethod - parentMethod.replaceInstruction( - startIndex, """ - const/4 v1, 0x0 - """ - ) - - val result = HideGetPremiumFingerprint.result!! - val method = result.mutableMethod - method.addInstructions( - startIndex, """ - const/16 v0, 0x8 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt deleted file mode 100644 index ce2b14d87..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.music.layout.tastebuilder.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -/** - * -- Note 2022-08-05 -- - * Since 5.17.xx the tastebuilder component is dismissible, so this patch is less useful - * also it is partly litho now - */ -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class RemoveTasteBuilderCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt deleted file mode 100644 index e72193c6f..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.layout.tastebuilder.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object TasteBuilderConstructorFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf( - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.CONST - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt deleted file mode 100644 index d3b61a3f7..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt +++ /dev/null @@ -1,41 +0,0 @@ -package app.revanced.patches.music.layout.tastebuilder.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.layout.tastebuilder.annotations.RemoveTasteBuilderCompatibility -import app.revanced.patches.music.layout.tastebuilder.fingerprints.TasteBuilderConstructorFingerprint -import org.jf.dexlib2.iface.instruction.formats.Instruction22c - -@Patch -@Name("tasteBuilder-remover") -@Description("Removes the \"Tell us which artists you like\" card from the home screen.") -@RemoveTasteBuilderCompatibility -@Version("0.0.1") -class RemoveTasteBuilderPatch : BytecodePatch( - listOf( - TasteBuilderConstructorFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = TasteBuilderConstructorFingerprint.result!! - val method = result.mutableMethod - - val insertIndex = result.scanResult.patternScanResult!!.endIndex - 8 - val register = (method.implementation!!.instructions[insertIndex] as Instruction22c).registerA - method.addInstructions( - insertIndex, """ - const/16 v1, 0x8 - invoke-virtual {v${register}, v1}, Landroid/view/View;->setVisibility(I)V - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt deleted file mode 100644 index e68303061..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.layout.upgradebutton.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class RemoveUpgradeButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt deleted file mode 100644 index e62225b25..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches.music.layout.upgradebutton.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object PivotBarConstructorFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "Z"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.CONST_4, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.GOTO, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.NOP, - Opcode.IPUT_OBJECT, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt deleted file mode 100644 index 9bf8ad011..000000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt +++ /dev/null @@ -1,78 +0,0 @@ -package app.revanced.patches.music.layout.upgradebutton.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.toInstructions -import app.revanced.patches.music.layout.upgradebutton.annotations.RemoveUpgradeButtonCompatibility -import app.revanced.patches.music.layout.upgradebutton.fingerprints.PivotBarConstructorFingerprint -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction22t -import org.jf.dexlib2.iface.instruction.formats.Instruction22c -import org.jf.dexlib2.iface.instruction.formats.Instruction35c - - -@Patch -@Name("upgrade-button-remover") -@Description("Removes the upgrade tab from the pivot bar.") -@RemoveUpgradeButtonCompatibility -@Version("0.0.1") -class RemoveUpgradeButtonPatch : BytecodePatch( - listOf( - PivotBarConstructorFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = PivotBarConstructorFingerprint.result!! - val implementation = result.mutableMethod.implementation!! - - val pivotBarElementFieldRef = - (implementation.instructions[result.scanResult.patternScanResult!!.endIndex - 1] as Instruction22c).reference - - val register = (implementation.instructions.first() as Instruction35c).registerC - // first compile all the needed instructions - val instructionList = """ - invoke-interface { v0 }, Ljava/util/List;->size()I - move-result v1 - const/4 v2, 0x3 - invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object; - iput-object v0, v$register, $pivotBarElementFieldRef - """.toInstructions().toMutableList() - - - val endIndex = result.scanResult.patternScanResult!!.endIndex - - // replace the instruction to retain the label at given index - implementation.replaceInstruction( - endIndex - 1, instructionList[0] // invoke-interface - ) - // do not forget to remove this instruction since we added it already - instructionList.removeFirst() - - val exitInstruction = instructionList.last() // iput-object - implementation.addInstruction( - endIndex, exitInstruction - ) - // do not forget to remove this instruction since we added it already - instructionList.removeLast() - - // add the necessary if statement to remove the upgrade tab button in case it exists - instructionList.add( - 2, // if-le - BuilderInstruction22t( - Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(endIndex) - ) - ) - - implementation.addInstructions( - endIndex, instructionList - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/annotations/BypassCertificateChecksCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/annotations/BypassCertificateChecksCompatibility.kt deleted file mode 100644 index dbbd31992..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/annotations/BypassCertificateChecksCompatibility.kt +++ /dev/null @@ -1,35 +0,0 @@ -package app.revanced.patches.music.misc.androidauto.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.apps.youtube.music", - arrayOf( - "5.14.53", - "5.16.51", - "5.17.51", - "5.21.52", - "5.22.54", - "5.23.50", - "5.25.51", - "5.25.52", - "5.26.52", - "5.27.51", - "5.28.52", - "5.29.52", - "5.31.50", - "5.34.51", - "5.36.51", - "5.38.53", - "5.39.52", - "5.40.51", - "5.41.50", - "5.48.52" - ) - )] -) -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.RUNTIME) -internal annotation class BypassCertificateChecksCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt deleted file mode 100644 index f0a261588..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.music.misc.androidauto.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.music.misc.androidauto.patch.BypassCertificateChecksPatch - - -object CheckCertificateFingerprint : MethodFingerprint( - "Z", - strings = listOf("No match") // Unique in combination with boolean return type -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/patch/BypassCertificateChecksPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/patch/BypassCertificateChecksPatch.kt deleted file mode 100644 index db5af5baf..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/patch/BypassCertificateChecksPatch.kt +++ /dev/null @@ -1,41 +0,0 @@ -package app.revanced.patches.music.misc.androidauto.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.misc.androidauto.annotations.BypassCertificateChecksCompatibility -import app.revanced.patches.music.misc.androidauto.fingerprints.CheckCertificateFingerprint - -@Patch -@Name("bypass-certificate-checks") -@Description("Bypasses certificate checks which prevent YouTube Music from working on Android Auto.") -@BypassCertificateChecksCompatibility -@Version("0.0.1") -class BypassCertificateChecksPatch : BytecodePatch( - listOf( - CheckCertificateFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - CheckCertificateFingerprint.result?.let { result -> - val noMatchIndex = result.scanResult.stringsScanResult!!.matches.first().index - - result.mutableMethod.apply { - val isPartnerIndex = noMatchIndex + 2 - - replaceInstruction(isPartnerIndex, "const/4 p1, 0x1") - addInstruction(isPartnerIndex + 1, "return p1") - } - } ?: return CheckCertificateFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/annotations/MusicMicroGPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/annotations/MusicMicroGPatchCompatibility.kt deleted file mode 100644 index 8128a9af6..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/annotations/MusicMicroGPatchCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.misc.microg.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class MusicMicroGPatchCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastContextFetchFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastContextFetchFingerprint.kt deleted file mode 100644 index 04d0430f0..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastContextFetchFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CastContextFetchFingerprint : MethodFingerprint( - strings = listOf("Error fetching CastContext.") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastDynamiteModuleFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastDynamiteModuleFingerprint.kt deleted file mode 100644 index a4d39a8dd..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastDynamiteModuleFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CastDynamiteModuleFingerprint : MethodFingerprint( - strings = listOf("com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastDynamiteModuleV2Fingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastDynamiteModuleV2Fingerprint.kt deleted file mode 100644 index f4119e588..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/CastDynamiteModuleV2Fingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CastDynamiteModuleV2Fingerprint : MethodFingerprint( - strings = listOf("Failed to load module via V2: ") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/GooglePlayUtilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/GooglePlayUtilityFingerprint.kt deleted file mode 100644 index eaefab9b2..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/GooglePlayUtilityFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.music.misc.microg.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object GooglePlayUtilityFingerprint : MethodFingerprint( - "I", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L", "I"), - strings = listOf( - "This should never happen.", - "MetadataValueReader", - "GooglePlayServicesUtil", - "com.android.vending", - "android.hardware.type.embedded" - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/PrimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/PrimeFingerprint.kt deleted file mode 100644 index e1fcc27d4..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/PrimeFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PrimeFingerprint : MethodFingerprint( - strings = listOf("com.google.android.GoogleCamera", "com.android.vending") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/ServiceCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/ServiceCheckFingerprint.kt deleted file mode 100644 index dd0833144..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/fingerprints/ServiceCheckFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.music.misc.microg.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object ServiceCheckFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L", "I"), - strings = listOf("Google Play Services not available") -) diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/patch/bytecode/MusicMicroGBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/patch/bytecode/MusicMicroGBytecodePatch.kt deleted file mode 100644 index 7fca848f8..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/patch/bytecode/MusicMicroGBytecodePatch.kt +++ /dev/null @@ -1,65 +0,0 @@ -package app.revanced.patches.music.misc.microg.patch.bytecode - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.misc.microg.annotations.MusicMicroGPatchCompatibility -import app.revanced.patches.music.misc.microg.fingerprints.* -import app.revanced.patches.music.misc.microg.patch.resource.MusicMicroGResourcePatch -import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME -import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME -import app.revanced.patches.youtube.misc.microg.shared.Constants -import app.revanced.util.microg.MicroGBytecodeHelper - -@Patch -@DependsOn([MusicMicroGResourcePatch::class]) -@Name("music-microg-support") -@Description("Allows YouTube Music ReVanced to run without root and under a different package name.") -@MusicMicroGPatchCompatibility -@Version("0.0.2") -class MusicMicroGBytecodePatch : BytecodePatch( - listOf( - ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, - CastDynamiteModuleFingerprint, - CastDynamiteModuleV2Fingerprint, - CastContextFetchFingerprint, - PrimeFingerprint, - ) -) { - // NOTE: the previous patch also replaced the following strings, but it seems like they are not needed: - // - "com.google.android.gms.chimera.GmsIntentOperationService", - // - "com.google.android.gms.phenotype.internal.IPhenotypeCallbacks", - // - "com.google.android.gms.phenotype.internal.IPhenotypeService", - // - "com.google.android.gms.phenotype.PACKAGE_NAME", - // - "com.google.android.gms.phenotype.UPDATE", - // - "com.google.android.gms.phenotype", - override fun execute(context: BytecodeContext) = - // apply common microG patch - MicroGBytecodeHelper.patchBytecode( - context, - arrayOf( - MicroGBytecodeHelper.packageNameTransform( - Constants.PACKAGE_NAME, - Constants.REVANCED_PACKAGE_NAME - ) - ), - MicroGBytecodeHelper.PrimeMethodTransformationData( - PrimeFingerprint, - MUSIC_PACKAGE_NAME, - REVANCED_MUSIC_PACKAGE_NAME - ), - listOf( - ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, - CastDynamiteModuleFingerprint, - CastDynamiteModuleV2Fingerprint, - CastContextFetchFingerprint - ) - ).let { PatchResultSuccess() } -} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/patch/resource/MusicMicroGResourcePatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/patch/resource/MusicMicroGResourcePatch.kt deleted file mode 100644 index 19daba368..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/patch/resource/MusicMicroGResourcePatch.kt +++ /dev/null @@ -1,41 +0,0 @@ -package app.revanced.patches.music.misc.microg.patch.resource - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patches.music.misc.microg.annotations.MusicMicroGPatchCompatibility -import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME -import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_APP_NAME -import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME -import app.revanced.patches.music.misc.microg.shared.Constants.SPOOFED_PACKAGE_NAME -import app.revanced.patches.music.misc.microg.shared.Constants.SPOOFED_PACKAGE_SIGNATURE -import app.revanced.util.microg.MicroGManifestHelper -import app.revanced.util.microg.MicroGResourceHelper - -@Name("music-microg-resource-patch") -@Description("Resource patch to allow YouTube Music ReVanced to run without root and under a different package name.") -@MusicMicroGPatchCompatibility -@Version("0.0.2") -class MusicMicroGResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - // update manifest - MicroGResourceHelper.patchManifest( - context, - MUSIC_PACKAGE_NAME, - REVANCED_MUSIC_PACKAGE_NAME, - REVANCED_MUSIC_APP_NAME - ) - - // add metadata to the manifest - MicroGManifestHelper.addSpoofingMetadata( - context, - SPOOFED_PACKAGE_NAME, - SPOOFED_PACKAGE_SIGNATURE - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/shared/Constants.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/shared/Constants.kt deleted file mode 100644 index a7405cc4e..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/microg/shared/Constants.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.music.misc.microg.shared - -object Constants { - internal const val REVANCED_MUSIC_APP_NAME = "YT Music ReVanced" - internal const val REVANCED_MUSIC_PACKAGE_NAME = "app.revanced.android.apps.youtube.music" - internal const val MUSIC_PACKAGE_NAME = "com.google.android.apps.youtube.music" - internal const val SPOOFED_PACKAGE_NAME = MUSIC_PACKAGE_NAME - internal const val SPOOFED_PACKAGE_SIGNATURE = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875" -} diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt deleted file mode 100644 index 31dd505f3..000000000 --- a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.premium.backgroundplay.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.apps.youtube.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class BackgroundPlayCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/fingerprints/BackgroundPlaybackDisableFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/fingerprints/BackgroundPlaybackDisableFingerprint.kt deleted file mode 100644 index fdaea7760..000000000 --- a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/fingerprints/BackgroundPlaybackDisableFingerprint.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.music.premium.backgroundplay.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object BackgroundPlaybackDisableFingerprint : MethodFingerprint( - "Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf( - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET, - Opcode.AND_INT_LIT16, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_EQZ, - Opcode.CONST_4, - Opcode.RETURN, - Opcode.RETURN, - Opcode.RETURN - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/patch/BackgroundPlayPatch.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/patch/BackgroundPlayPatch.kt deleted file mode 100644 index 9c860a9c3..000000000 --- a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/patch/BackgroundPlayPatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.music.premium.backgroundplay.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.music.premium.backgroundplay.annotations.BackgroundPlayCompatibility -import app.revanced.patches.music.premium.backgroundplay.fingerprints.BackgroundPlaybackDisableFingerprint - -@Patch -@Name("background-play") -@Description("Enables playing music in the background.") -@BackgroundPlayCompatibility -@Version("0.0.1") -class BackgroundPlayPatch : BytecodePatch( - listOf( - BackgroundPlaybackDisableFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - BackgroundPlaybackDisableFingerprint.result!!.mutableMethod.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/annotations/UnlockProCompatibility.kt b/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/annotations/UnlockProCompatibility.kt deleted file mode 100644 index 8ab7f6adf..000000000 --- a/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/annotations/UnlockProCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.myexpenses.misc.pro.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("org.totschnig.myexpenses", arrayOf("3.4.9"))]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockProCompatibility diff --git a/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/fingerprints/IsEnabledFingerprint.kt b/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/fingerprints/IsEnabledFingerprint.kt deleted file mode 100644 index caebe9e50..000000000 --- a/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/fingerprints/IsEnabledFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.myexpenses.misc.pro.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object IsEnabledFingerprint : MethodFingerprint( - "Z", - strings = listOf("feature", "feature.licenceStatus") -) diff --git a/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/patch/UnlockProPatch.kt b/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/patch/UnlockProPatch.kt deleted file mode 100644 index ebf34e63e..000000000 --- a/src/main/kotlin/app/revanced/patches/myexpenses/misc/pro/patch/UnlockProPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.myexpenses.misc.pro.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.myexpenses.misc.pro.annotations.UnlockProCompatibility -import app.revanced.patches.myexpenses.misc.pro.fingerprints.IsEnabledFingerprint - -@Patch -@Name("unlock-pro") -@Description("Unlocks all professional features.") -@UnlockProCompatibility -@Version("0.0.1") -class UnlockProPatch : BytecodePatch( - listOf( - IsEnabledFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = IsEnabledFingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/annotations/RemoveBroadcastsRestrictionCompatibility.kt b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/annotations/RemoveBroadcastsRestrictionCompatibility.kt deleted file mode 100644 index 94bbbe9f5..000000000 --- a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/annotations/RemoveBroadcastsRestrictionCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.netguard.broadcasts.removerestriction.resource.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("eu.faircode.netguard")]) -@Target(AnnotationTarget.CLASS) -annotation class RemoveBroadcastsRestrictionCompatibility diff --git a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/patch/RemoveBroadcastsRestrictionPatch.kt b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/patch/RemoveBroadcastsRestrictionPatch.kt deleted file mode 100644 index 728e44813..000000000 --- a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/patch/RemoveBroadcastsRestrictionPatch.kt +++ /dev/null @@ -1,40 +0,0 @@ -package app.revanced.patches.netguard.broadcasts.removerestriction.resource.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.netguard.broadcasts.removerestriction.resource.annotations.RemoveBroadcastsRestrictionCompatibility -import org.w3c.dom.Element - -@Patch(false) -@Name("remove-broadcasts-restriction") -@Description("Enables starting/stopping NetGuard via broadcasts.") -@RemoveBroadcastsRestrictionCompatibility -@Version("0.0.1") -class RemoveBroadcastsRestrictionPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - context.xmlEditor["AndroidManifest.xml"].use { dom -> - val applicationNode = dom - .file - .getElementsByTagName("application") - .item(0) as Element - - applicationNode.getElementsByTagName("receiver").also { list -> - for (i in 0 until list.length) { - val element = list.item(i) as? Element ?: continue - if (element.getAttribute("android:name") == "eu.faircode.netguard.WidgetAdmin") { - element.removeAttribute("android:permission") - break - } - } - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/nova/prime/annotations/UnlockPrimeCompatibility.kt b/src/main/kotlin/app/revanced/patches/nova/prime/annotations/UnlockPrimeCompatibility.kt deleted file mode 100644 index 8ab3cc780..000000000 --- a/src/main/kotlin/app/revanced/patches/nova/prime/annotations/UnlockPrimeCompatibility.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.nova.prime.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.teslacoilsw.launcher") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockPrimeCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/nova/prime/fingerprints/UnlockPrimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/nova/prime/fingerprints/UnlockPrimeFingerprint.kt deleted file mode 100644 index 69d2902a4..000000000 --- a/src/main/kotlin/app/revanced/patches/nova/prime/fingerprints/UnlockPrimeFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.nova.prime.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object UnlockPrimeFingerprint : MethodFingerprint( - "V", - opcodes = listOf( - Opcode.IPUT_OBJECT, - Opcode.CONST_STRING, - Opcode.CONST_4, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT - ), - strings = listOf("1") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/nova/prime/patch/UnlockPrimePatch.kt b/src/main/kotlin/app/revanced/patches/nova/prime/patch/UnlockPrimePatch.kt deleted file mode 100644 index 0b6ae48e0..000000000 --- a/src/main/kotlin/app/revanced/patches/nova/prime/patch/UnlockPrimePatch.kt +++ /dev/null @@ -1,50 +0,0 @@ -package app.revanced.patches.nova.prime.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.nova.prime.annotations.UnlockPrimeCompatibility -import app.revanced.patches.nova.prime.fingerprints.UnlockPrimeFingerprint -import org.jf.dexlib2.builder.instruction.BuilderInstruction11x - -@Patch -@Name("unlock-prime") -@Description("Unlocks Nova Prime and all functions of the app.") -@UnlockPrimeCompatibility -@Version("0.0.1") -class UnlockPrimePatch : BytecodePatch( - listOf( - UnlockPrimeFingerprint - ) -) { - private companion object { - // Any value except 0 unlocks prime, but 512 is needed for a protection mechanism - // which would reset the preferences if the value on disk had changed after a restart. - const val PRIME_STATUS: Int = 512 - } - - override fun execute(context: BytecodeContext): PatchResult { - UnlockPrimeFingerprint.result?.apply { - val insertIndex = scanResult.patternScanResult!!.endIndex + 1 - - val primeStatusRegister = - (mutableMethod.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA - - mutableMethod.addInstruction( - insertIndex, - """ - const/16 v$primeStatusRegister, $PRIME_STATUS - """ - ) - } ?: UnlockPrimeFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/nyx/misc/pro/annotations/UnlockProCompatibility.kt b/src/main/kotlin/app/revanced/patches/nyx/misc/pro/annotations/UnlockProCompatibility.kt deleted file mode 100644 index c8aef11cb..000000000 --- a/src/main/kotlin/app/revanced/patches/nyx/misc/pro/annotations/UnlockProCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.nyx.misc.pro.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.awedea.nyx")]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockProCompatibility diff --git a/src/main/kotlin/app/revanced/patches/nyx/misc/pro/fingerprints/CheckProFingerprint.kt b/src/main/kotlin/app/revanced/patches/nyx/misc/pro/fingerprints/CheckProFingerprint.kt deleted file mode 100644 index 90b0af58d..000000000 --- a/src/main/kotlin/app/revanced/patches/nyx/misc/pro/fingerprints/CheckProFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.nyx.misc.pro.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CheckProFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("BillingManager;") && methodDef.name == "isProVersion" - } -) diff --git a/src/main/kotlin/app/revanced/patches/nyx/misc/pro/patch/UnlockProPatch.kt b/src/main/kotlin/app/revanced/patches/nyx/misc/pro/patch/UnlockProPatch.kt deleted file mode 100644 index bb0ee5960..000000000 --- a/src/main/kotlin/app/revanced/patches/nyx/misc/pro/patch/UnlockProPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.nyx.misc.pro.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.nyx.misc.pro.annotations.UnlockProCompatibility -import app.revanced.patches.nyx.misc.pro.fingerprints.CheckProFingerprint - -@Patch -@Name("unlock-pro") -@Description("Unlocks all pro features.") -@UnlockProCompatibility -@Version("0.0.1") -class UnlockProPatch : BytecodePatch( - listOf( - CheckProFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = CheckProFingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/CheckSignatureFingerprint.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/CheckSignatureFingerprint.kt deleted file mode 100644 index 2f460c694..000000000 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/CheckSignatureFingerprint.kt +++ /dev/null @@ -1,30 +0,0 @@ -package app.revanced.patches.photomath.detection.signature.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object CheckSignatureFingerprint : MethodFingerprint( - returnType = "V", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - customFingerprint = { - (it.definingClass == "Lcom/microblink/photomath/main/activity/LauncherActivity;" || - it.definingClass == "Lcom/microblink/photomath/PhotoMath;") && - it.name == "onCreate" - }, - strings = listOf( - "currentSignature" - ), - opcodes = listOf( - Opcode.CONST_STRING, - Opcode.CONST_STRING, - Opcode.INVOKE_STATIC, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - ) -) diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt deleted file mode 100644 index d8c5beaae..000000000 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.revanced.patches.photomath.detection.signature.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.photomath.detection.signature.fingerprints.CheckSignatureFingerprint -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Description("Disables detection of incorrect signature.") -@Version("0.0.2") -class SignatureDetectionPatch : BytecodePatch( - listOf( - CheckSignatureFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - CheckSignatureFingerprint.result?.apply { - val signatureCheckInstruction = mutableMethod.instruction(scanResult.patternScanResult!!.endIndex) - val checkRegister = (signatureCheckInstruction as OneRegisterInstruction).registerA - - mutableMethod.replaceInstruction(signatureCheckInstruction.location.index, "const/4 v$checkRegister, 0x1") - } ?: throw CheckSignatureFingerprint.toErrorResult() - - return PatchResultSuccess() - } - -} diff --git a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/annotations/UnlockPlusCompatibilty.kt b/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/annotations/UnlockPlusCompatibilty.kt deleted file mode 100644 index 29f8379df..000000000 --- a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/annotations/UnlockPlusCompatibilty.kt +++ /dev/null @@ -1,30 +0,0 @@ -package app.revanced.patches.photomath.misc.unlockplus.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.microblink.photomath", arrayOf( - "8.6.0", - "8.7.0", - "8.8.0", - "8.9.0", - "8.10.0", - "8.11.0", - "8.12.0", - "8.13.0", - "8.14.0", - "8.15.0", - "8.16.0", - "8.17.0", - "8.18.0", - "8.18.1", - "8.19.0", - "8.20.0", - "8.21.0", - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockPlusCompatibilty diff --git a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/fingerprints/IsPlusUnlockedFingerprint.kt b/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/fingerprints/IsPlusUnlockedFingerprint.kt deleted file mode 100644 index eb2f74644..000000000 --- a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/fingerprints/IsPlusUnlockedFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.photomath.misc.unlockplus.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object IsPlusUnlockedFingerprint : MethodFingerprint( - returnType = "Z", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - strings = listOf( - "genius" - ), - customFingerprint = { - methodDef -> methodDef.definingClass.endsWith("/User;") - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/patch/UnlockPlusPatch.kt b/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/patch/UnlockPlusPatch.kt deleted file mode 100644 index eb5cb8064..000000000 --- a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/patch/UnlockPlusPatch.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.photomath.misc.unlockplus.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.photomath.detection.signature.patch.SignatureDetectionPatch -import app.revanced.patches.photomath.misc.unlockplus.annotations.UnlockPlusCompatibilty -import app.revanced.patches.photomath.misc.unlockplus.fingerprints.IsPlusUnlockedFingerprint - -@Patch -@Name("unlock-plus") -@DependsOn([SignatureDetectionPatch::class]) -@Description("Unlocks plus features.") -@UnlockPlusCompatibilty -@Version("0.0.1") -class UnlockPlusPatch : BytecodePatch( - listOf( - IsPlusUnlockedFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - IsPlusUnlockedFingerprint.result?.mutableMethod?.apply { - addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - } ?: return IsPlusUnlockedFingerprint.toErrorResult() - - return PatchResultSuccess() - } - -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/BannerAdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/BannerAdsPatch.kt new file mode 100644 index 000000000..c9af4aa03 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/BannerAdsPatch.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.reddit.ad.banner + +import app.revanced.patcher.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.util.ResourceUtils.base + +class BannerAdsPatch : ResourcePatch { + companion object { + private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml" + } + override fun execute(context: ResourceContext) { + context.base.openXmlFile(RESOURCE_FILE_PATH).use { + it.file.getElementsByTagName("merge").item(0).childNodes.apply { + val attributes = arrayOf("height", "width") + + for (i in 1 until length) { + val view = item(i) + if ( + view.hasAttributes() && + view.attributes.getNamedItem("android:id").nodeValue.endsWith("ad_view_stub") + ) { + attributes.forEach { attribute -> + view.attributes.getNamedItem("android:layout_$attribute").nodeValue = + "0.0dip" + } + + break + } + } + } + } + + } +} + diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/annotations/HideBannerCompatibility.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/annotations/HideBannerCompatibility.kt deleted file mode 100644 index ffac6ed55..000000000 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/annotations/HideBannerCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.reddit.ad.banner.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.reddit.frontpage", arrayOf( - "2023.05.0", - "2023.06.0", - "2023.07.0", - "2023.07.1", - "2023.08.0", - "2023.09.0", - "2023.09.1", - "2023.10.0", - "2023.11.0", - "2023.12.0" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideBannerCompatibility diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/patch/HideBannerPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/patch/HideBannerPatch.kt deleted file mode 100644 index c6d06c808..000000000 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/patch/HideBannerPatch.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.reddit.ad.banner.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.reddit.ad.banner.annotations.HideBannerCompatibility - -@Patch -@Name("hide-subreddit-banner") -@Description("Hides banner ads from comments on subreddits.") -@HideBannerCompatibility -@Version("0.0.1") -class HideBannerPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - - context.xmlEditor[RESOURCE_FILE_PATH].use { - it.file.getElementsByTagName("merge").item(0).childNodes.apply { - val attributes = arrayOf("height", "width") - - for (i in 1 until length) { - val view = item(i) - if ( - view.hasAttributes() && - view.attributes.getNamedItem("android:id").nodeValue.endsWith("ad_view_stub") - ) { - attributes.forEach { attribute -> - view.attributes.getNamedItem("android:layout_$attribute").nodeValue = "0.0dip" - } - - break - } - } - } - } - - return PatchResultSuccess() - } - - private companion object { - const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml" - } -} - diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/comments/CommentAdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/comments/CommentAdsPatch.kt new file mode 100644 index 000000000..72f9621d0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/comments/CommentAdsPatch.kt @@ -0,0 +1,39 @@ +package app.revanced.patches.reddit.ad.comments + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.reddit.ad.comments.fingerprints.CommentAdsFingerprint +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.util.getInstruction +import app.revanced.util.getWalkerMethod +import app.revanced.util.resultOrThrow + +class CommentAdsPatch : BytecodePatch( + setOf(CommentAdsFingerprint) +) { + companion object { + private const val INTEGRATION_METHOD_DESCRIPTOR = + "$PATCHES_PATH/GeneralAdsPatch;->hideCommentAds()Z" + } + + override fun execute(context: BytecodeContext) { + CommentAdsFingerprint.resultOrThrow().apply { + val walkerMethod = getWalkerMethod(context, scanResult.patternScanResult!!.startIndex) + walkerMethod.apply { + addInstructions( + 0, """ + invoke-static {}, $INTEGRATION_METHOD_DESCRIPTOR + move-result v0 + if-eqz v0, :show + new-instance v0, Ljava/lang/Object; + invoke-direct {v0}, Ljava/lang/Object;->()V + return-object v0 + """, listOf(ExternalLabel("show", getInstruction(0))) + ) + } + } + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/comments/fingerprints/CommentAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/comments/fingerprints/CommentAdsFingerprint.kt new file mode 100644 index 000000000..a3d1419dc --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/comments/fingerprints/CommentAdsFingerprint.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.reddit.ad.comments.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +internal object CommentAdsFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.RETURN_OBJECT + ), + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/PostDetailPresenter\$loadAd\$1;") + && methodDef.name == "invokeSuspend" + }, +) diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/general/AdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/general/AdsPatch.kt new file mode 100644 index 000000000..a179790f5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/general/AdsPatch.kt @@ -0,0 +1,80 @@ +package app.revanced.patches.reddit.ad.general + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.annotations.RequiresIntegrations +import app.revanced.patches.reddit.ad.banner.BannerAdsPatch +import app.revanced.patches.reddit.ad.comments.CommentAdsPatch +import app.revanced.patches.reddit.ad.general.fingerprints.AdPostFingerprint +import app.revanced.patches.reddit.ad.general.fingerprints.NewAdPostFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.getTargetIndexWithFieldReferenceName +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.resultOrThrow +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction + +@Patch +@Name("Hide ads") +@Description("Adds options to hide ads.") +@DependsOn([BannerAdsPatch::class, CommentAdsPatch::class, SettingsPatch::class]) +@RedditCompatibility +@RequiresIntegrations +@Suppress("unused") +class AdsPatch : BytecodePatch( + listOf( + AdPostFingerprint, + NewAdPostFingerprint + ) +) { + companion object { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "$PATCHES_PATH/GeneralAdsPatch;" + } + + override fun execute(context: BytecodeContext) { + // region Filter promoted ads (does not work in popular or latest feed) + AdPostFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = getTargetIndexWithFieldReferenceName("children") + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex, """ + invoke-static {v$targetRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideOldPostAds(Ljava/util/List;)Ljava/util/List; + move-result-object v$targetRegister + """ + ) + } + } + + // The new feeds work by inserting posts into lists. + // AdElementConverter is conveniently responsible for inserting all feed ads. + // By removing the appending instruction no ad posts gets appended to the feed. + NewAdPostFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = getTargetIndexWithMethodReferenceName("add") + val targetInstruction = getInstruction(targetIndex) + + replaceInstruction( + targetIndex, + "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + + "$INTEGRATIONS_CLASS_DESCRIPTOR->hideNewPostAds(Ljava/util/ArrayList;Ljava/lang/Object;)V" + ) + } + } + + updateSettingsStatus("enableGeneralAds") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/general/annotations/GeneralAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/general/annotations/GeneralAdsCompatibility.kt deleted file mode 100644 index e513e941e..000000000 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/general/annotations/GeneralAdsCompatibility.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.reddit.ad.general.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.reddit.frontpage", arrayOf( - "2021.45.0", - "2022.43.0", - "2023.05.0", - "2023.06.0", - "2023.07.0", - "2023.07.1", - "2023.08.0", - "2023.09.0", - "2023.09.1", - "2023.10.0", - "2023.11.0", - "2023.12.0" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class GeneralAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/general/fingerprints/AdPostFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/general/fingerprints/AdPostFingerprint.kt new file mode 100644 index 000000000..cc6caaecb --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/general/fingerprints/AdPostFingerprint.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.reddit.ad.general.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +internal object AdPostFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + opcodes = listOf( + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT + ), + // "children" are present throughout multiple versions + strings = listOf( + "children", + "uxExperiences" + ), + customFingerprint = { methodDef, classDef -> + methodDef.definingClass.endsWith("/Listing;") + && methodDef.name == "" + && classDef.sourceFile == "Listing.kt" + }, +) diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/general/fingerprints/NewAdPostFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/general/fingerprints/NewAdPostFingerprint.kt new file mode 100644 index 000000000..448b3e71d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/general/fingerprints/NewAdPostFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.reddit.ad.general.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +internal object NewAdPostFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf(Opcode.INVOKE_VIRTUAL), + strings = listOf( + "chain", + "feedElement" + ), + customFingerprint = { _, classDef -> classDef.sourceFile == "AdElementConverter.kt" }, +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/general/patch/GeneralAdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/general/patch/GeneralAdsPatch.kt deleted file mode 100644 index 86341a62a..000000000 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/general/patch/GeneralAdsPatch.kt +++ /dev/null @@ -1,54 +0,0 @@ -package app.revanced.patches.reddit.ad.general.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.reddit.ad.general.annotations.GeneralAdsCompatibility -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction21c -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.StringReference -import org.jf.dexlib2.immutable.reference.ImmutableStringReference - -@Patch -@Name("general-reddit-ads") -@Description("Removes general ads from the Reddit frontpage and subreddits.") -@GeneralAdsCompatibility -@Version("0.0.1") -class GeneralAdsPatch : BytecodePatch() { - override fun execute(context: BytecodeContext): PatchResult { - context.classes.forEach { classDef -> - classDef.methods.forEach methodLoop@{ method -> - val implementation = method.implementation ?: return@methodLoop - - implementation.instructions.forEachIndexed { i, instruction -> - if (instruction.opcode != Opcode.CONST_STRING) return@forEachIndexed - if (((instruction as ReferenceInstruction).reference as StringReference).string != "AdPost") return@forEachIndexed - - val proxiedClass = context.proxy(classDef).mutableClass - - val proxiedImplementation = proxiedClass.methods.first { - it.name == method.name && it.parameterTypes.containsAll(method.parameterTypes) - }.implementation!! - - var newString = "AdPost1" - if (proxiedImplementation.instructions[i - 1].opcode == Opcode.CONST_STRING) { - newString = "SubredditPost" - } - proxiedImplementation.replaceInstruction( - i, BuilderInstruction21c( - Opcode.CONST_STRING, (proxiedImplementation.instructions[i] as BuilderInstruction21c).registerA, ImmutableStringReference(newString) - ) - ) - } - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/branding/name/CustomBrandingNamePatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/branding/name/CustomBrandingNamePatch.kt new file mode 100644 index 000000000..ae9e618b1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/branding/name/CustomBrandingNamePatch.kt @@ -0,0 +1,48 @@ +package app.revanced.patches.reddit.layout.branding.name + +import app.revanced.patcher.ResourceContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.patch.OptionsContainer +import app.revanced.patcher.patch.PatchOption +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.util.ResourceUtils.base +import app.revanced.util.ResourceUtils.setString + +@Patch +@Name("Custom branding name reddit") +@Description("Renames the Reddit app to the name specified in options.json.") +@RedditCompatibility +@Suppress("unused") +class CustomBrandingNamePatch : ResourcePatch { + companion object : OptionsContainer() { + private const val ORIGINAL_APP_NAME = "Reddit" + private const val APP_NAME = "RVX Reddit" + + private var AppName: String? by option( + PatchOption.StringOption( + key = "AppName", + default = ORIGINAL_APP_NAME, + title = "App name", + description = "The name of the app." + ) + ) + } + + override fun execute(context: ResourceContext) { + val appName = if (AppName != null) { + AppName!! + } else { + println("WARNING: Invalid name name. Does not apply patches.") + ORIGINAL_APP_NAME + } + + if (appName != ORIGINAL_APP_NAME) { + context.base.setString("app_name", appName) + } else { + println("INFO: App name will remain unchanged as it matches the original.") + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt new file mode 100644 index 000000000..50cb364e6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt @@ -0,0 +1,51 @@ +package app.revanced.patches.reddit.layout.navigation + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.reddit.layout.navigation.fingerprints.BottomNavScreenFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.resultOrThrow +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction + +@Patch +@Name("Hide navigation buttons") +@Description("Adds options to hide buttons in the navigation bar.") +@DependsOn([SettingsPatch::class]) +@RedditCompatibility +@Suppress("unused") +class NavigationButtonsPatch : BytecodePatch( + listOf(BottomNavScreenFingerprint) +) { + companion object { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "$PATCHES_PATH/NavigationButtonsPatch;->hideNavigationButtons(Landroid/view/ViewGroup;)V" + } + + override fun execute(context: BytecodeContext) { + + BottomNavScreenFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val startIndex = it.scanResult.patternScanResult!!.startIndex + val targetRegister = + getInstruction(startIndex).registerC + + addInstruction( + startIndex + 1, + "invoke-static {v$targetRegister}, $INTEGRATIONS_METHOD_DESCRIPTOR" + ) + } + } + + updateSettingsStatus("enableNavigationButtons") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/fingerprints/BottomNavScreenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/fingerprints/BottomNavScreenFingerprint.kt new file mode 100644 index 000000000..9f4364421 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/fingerprints/BottomNavScreenFingerprint.kt @@ -0,0 +1,20 @@ +package app.revanced.patches.reddit.layout.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +internal object BottomNavScreenFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + opcodes = listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.RETURN_VOID + ), + customFingerprint = { methodDef, classDef -> + methodDef.name == "onGlobalLayout" + && classDef.type.startsWith("Lcom/reddit/launch/bottomnav/BottomNavScreen\$") + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/PremiumIconPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/PremiumIconPatch.kt new file mode 100644 index 000000000..ffd09f95d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/PremiumIconPatch.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.reddit.layout.premiumicon + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.reddit.layout.premiumicon.fingerprints.PremiumIconFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.util.resultOrThrow + +@Patch +@Name("Premium icon") +@Description("Unlocks premium app icons.") +@RedditCompatibility +@Suppress("unused") +class PremiumIconPatch : BytecodePatch( + listOf(PremiumIconFingerprint) +) { + override fun execute(context: BytecodeContext) { + + PremiumIconFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructions( + 0, """ + const/4 v0, 0x1 + return v0 + """ + ) + } + } + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/fingerprints/PremiumIconFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/fingerprints/PremiumIconFingerprint.kt index bb8bf0d35..37de5d599 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/fingerprints/PremiumIconFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/fingerprints/PremiumIconFingerprint.kt @@ -2,9 +2,11 @@ package app.revanced.patches.reddit.layout.premiumicon.fingerprints import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -object PremiumIconFingerprint : MethodFingerprint( - "Z", - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("MyAccount;") && methodDef.name == "isPremiumSubscriber" +internal object PremiumIconFingerprint : MethodFingerprint( + returnType = "Z", + customFingerprint = { methodDef, classDef -> + methodDef.definingClass.endsWith("/MyAccount;") + && methodDef.name == "isPremiumSubscriber" + && classDef.sourceFile == "MyAccount.kt" } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/patch/PremiumIconPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/patch/PremiumIconPatch.kt deleted file mode 100644 index 156c746b9..000000000 --- a/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/patch/PremiumIconPatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.reddit.layout.premiumicon.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.reddit.layout.premiumicon.annotations.PremiumIconCompatibility -import app.revanced.patches.reddit.layout.premiumicon.fingerprints.PremiumIconFingerprint - -@Patch -@Name("premium-icon-reddit") -@Description("Unlocks premium Reddit app icons.") -@PremiumIconCompatibility -@Version("0.0.1") -class PremiumIconPatch : BytecodePatch( - listOf( - PremiumIconFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = PremiumIconFingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt new file mode 100644 index 000000000..7c13141c0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt @@ -0,0 +1,81 @@ +package app.revanced.patches.reddit.layout.recentlyvisited + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.reddit.layout.recentlyvisited.fingerprints.CommunityDrawerPresenterFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexReversed +import app.revanced.util.getTargetIndexWithFieldReferenceName +import app.revanced.util.getTargetIndexWithReference +import app.revanced.util.resultOrThrow +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.ReferenceInstruction +import org.jf.dexlib2.iface.reference.Reference + +@Patch +@Name("Hide recently visited shelf") +@Description("Adds an option to hide the recently visited shelf in the sidebar.") +@DependsOn([SettingsPatch::class]) +@RedditCompatibility +@Suppress("unused") +class RecentlyVisitedShelfPatch : BytecodePatch( + listOf(CommunityDrawerPresenterFingerprint) +) { + companion object { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "$PATCHES_PATH/RecentlyVisitedShelfPatch;" + + "->" + + "hideRecentlyVisitedShelf(Ljava/util/List;)Ljava/util/List;" + } + + override fun execute(context: BytecodeContext) { + + CommunityDrawerPresenterFingerprint.resultOrThrow().let { + lateinit var recentlyVisitedReference: Reference + + it.mutableClass.methods.find { method -> method.name == "" } + ?.apply { + val recentlyVisitedFieldIndex = + getTargetIndexWithFieldReferenceName("RECENTLY_VISITED") + val recentlyVisitedObjectIndex = + getTargetIndex(recentlyVisitedFieldIndex, Opcode.IPUT_OBJECT) + recentlyVisitedReference = + getInstruction(recentlyVisitedObjectIndex).reference + } ?: throw PatchException("Constructor method not found!") + + it.mutableMethod.apply { + val recentlyVisitedObjectIndex = + getTargetIndexWithReference(recentlyVisitedReference.toString()) + arrayOf( + getTargetIndex(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC), + getTargetIndexReversed(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC) + ).forEach { staticIndex -> + val insertRegister = + getInstruction(staticIndex + 1).registerA + + addInstructions( + staticIndex + 2, """ + invoke-static {v$insertRegister}, $INTEGRATIONS_METHOD_DESCRIPTOR + move-result-object v$insertRegister + """ + ) + } + } + } + + updateSettingsStatus("enableRecentlyVisitedShelf") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/fingerprints/CommunityDrawerPresenterFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/fingerprints/CommunityDrawerPresenterFingerprint.kt new file mode 100644 index 000000000..685d97fd0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/fingerprints/CommunityDrawerPresenterFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.reddit.layout.recentlyvisited.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +internal object CommunityDrawerPresenterFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + opcodes = listOf(Opcode.AGET), + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/CommunityDrawerPresenter;") + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt new file mode 100644 index 000000000..847d51a05 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt @@ -0,0 +1,51 @@ +package app.revanced.patches.reddit.layout.screenshotpopup + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.reddit.layout.screenshotpopup.fingerprints.ScreenshotTakenBannerFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.resultOrThrow + +@Patch +@Name("Disable screenshot popup") +@Description("Adds an option to disable the popup that shows up when taking a screenshot.") +@DependsOn([SettingsPatch::class]) +@RedditCompatibility +@Suppress("unused") +class ScreenshotPopupPatch : BytecodePatch( + listOf(ScreenshotTakenBannerFingerprint) +) { + companion object { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "$PATCHES_PATH/ScreenshotPopupPatch;->disableScreenshotPopup()Z" + } + + override fun execute(context: BytecodeContext) { + + ScreenshotTakenBannerFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructions( + 0, """ + invoke-static {}, $INTEGRATIONS_METHOD_DESCRIPTOR + move-result v0 + if-eqz v0, :dismiss + return-void + """, listOf(ExternalLabel("dismiss", getInstruction(0))) + ) + } + } + + updateSettingsStatus("enableScreenshotPopup") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/fingerprints/ScreenshotTakenBannerFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/fingerprints/ScreenshotTakenBannerFingerprint.kt new file mode 100644 index 000000000..c37d4377c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/fingerprints/ScreenshotTakenBannerFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.reddit.layout.screenshotpopup.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +internal object ScreenshotTakenBannerFingerprint : MethodFingerprint( + returnType = "V", + parameters = listOf("Landroidx/compose/runtime/", "I"), + customFingerprint = custom@{ methodDef, classDef -> + if (!classDef.type.endsWith("\$ScreenshotTakenBannerKt\$lambda-1\$1;")) + return@custom false + + methodDef.name == "invoke" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt new file mode 100644 index 000000000..592945ed8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt @@ -0,0 +1,71 @@ +package app.revanced.patches.reddit.layout.subredditdialog + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.reddit.layout.subredditdialog.fingerprints.FrequentUpdatesSheetScreenFingerprint +import app.revanced.patches.reddit.layout.subredditdialog.fingerprints.RedditAlertDialogsFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.resultOrThrow +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch +@Name("Remove subreddit dialog") +@Description("Adds options to remove the NSFW community warning and notifications suggestion dialogs by dismissing them automatically.") +@DependsOn([SettingsPatch::class]) +@RedditCompatibility +@Suppress("unused") +class SubRedditDialogPatch : BytecodePatch( + listOf( + FrequentUpdatesSheetScreenFingerprint, + RedditAlertDialogsFingerprint + ) +) { + companion object { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "$PATCHES_PATH/RemoveSubRedditDialogPatch;" + } + + override fun execute(context: BytecodeContext) { + + FrequentUpdatesSheetScreenFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val cancelButtonViewIndex = it.scanResult.patternScanResult!!.startIndex + 2 + val cancelButtonViewRegister = + getInstruction(cancelButtonViewIndex).registerA + + addInstruction( + cancelButtonViewIndex + 1, + "invoke-static {v$cancelButtonViewRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->dismissDialog(Landroid/view/View;)V" + ) + } + } + + RedditAlertDialogsFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val backgroundTintIndex = RedditAlertDialogsFingerprint.indexOfSetBackgroundTintListInstruction(this) + val insertIndex = + getTargetIndexWithMethodReferenceName(backgroundTintIndex, "setTextAppearance") + val insertRegister = getInstruction(insertIndex).registerC + + addInstruction( + insertIndex, + "invoke-static {v$insertRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->confirmDialog(Landroid/widget/TextView;)V" + ) + } + } + + updateSettingsStatus("enableSubRedditDialog") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/fingerprints/FrequentUpdatesSheetScreenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/fingerprints/FrequentUpdatesSheetScreenFingerprint.kt new file mode 100644 index 000000000..0ff507f83 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/fingerprints/FrequentUpdatesSheetScreenFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.reddit.layout.subredditdialog.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +internal object FrequentUpdatesSheetScreenFingerprint : MethodFingerprint( + returnType = "Landroid/view/View;", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf( + Opcode.CONST, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IF_EQZ + ), + strings = listOf("inflater"), + customFingerprint = { _, classDef -> + classDef.sourceFile == "FrequentUpdatesSheetScreen.kt" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/fingerprints/RedditAlertDialogsFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/fingerprints/RedditAlertDialogsFingerprint.kt new file mode 100644 index 000000000..b914c222a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/fingerprints/RedditAlertDialogsFingerprint.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.reddit.layout.subredditdialog.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.reddit.layout.subredditdialog.fingerprints.RedditAlertDialogsFingerprint.indexOfSetBackgroundTintListInstruction +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.Method +import org.jf.dexlib2.iface.reference.MethodReference + +internal object RedditAlertDialogsFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + customFingerprint = { methodDef, _ -> + methodDef.definingClass == "Lcom/reddit/screen/dialog/RedditAlertDialog;" + && indexOfSetBackgroundTintListInstruction(methodDef) >= 0 + } +) { + fun indexOfSetBackgroundTintListInstruction(methodDef: Method) = + methodDef.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "setBackgroundTintList" + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/ToolBarButtonPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/ToolBarButtonPatch.kt new file mode 100644 index 000000000..5e33fe845 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/ToolBarButtonPatch.kt @@ -0,0 +1,54 @@ +package app.revanced.patches.reddit.layout.toolbar + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.reddit.layout.toolbar.fingerprints.HomePagerScreenFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.Companion.ToolBarNavSearchCtaContainer +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.resultOrThrow +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction + +// @Patch +// @Name("Hide toolbar button") +@Description("Adds an option to hide the r/place or Reddit recap button in the toolbar.") +@DependsOn([SettingsPatch::class, SharedResourceIdPatch::class]) +@RedditCompatibility +@Suppress("unused") +@Deprecated("This patch is deprecated until Reddit adds a button like r/place or Reddit recap button to the toolbar.") +class ToolBarButtonPatch : BytecodePatch( + listOf(HomePagerScreenFingerprint) +) { + companion object { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "$PATCHES_PATH/ToolBarButtonPatch;->hideToolBarButton(Landroid/view/View;)V" + } + + override fun execute(context: BytecodeContext) { + + HomePagerScreenFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = + getWideLiteralInstructionIndex(ToolBarNavSearchCtaContainer) + 3 + val targetRegister = + getInstruction(targetIndex - 1).registerA + + addInstruction( + targetIndex, + "invoke-static {v$targetRegister}, $INTEGRATIONS_METHOD_DESCRIPTOR" + ) + } + } + + updateSettingsStatus("enableToolBarButton") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/fingerprints/HomePagerScreenFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/fingerprints/HomePagerScreenFingerprint.kt new file mode 100644 index 000000000..b31758a09 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/fingerprints/HomePagerScreenFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.reddit.layout.toolbar.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.Companion.ToolBarNavSearchCtaContainer +import app.revanced.util.containsWideLiteralInstructionIndex +import org.jf.dexlib2.AccessFlags + +internal object HomePagerScreenFingerprint : MethodFingerprint( + returnType = "Landroid/view/View;", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Landroid/view/LayoutInflater;", "Landroid/view/ViewGroup;"), + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/HomePagerScreen;") + && methodDef.containsWideLiteralInstructionIndex(ToolBarNavSearchCtaContainer) + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksDirectlyPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksDirectlyPatch.kt new file mode 100644 index 000000000..70300fb20 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksDirectlyPatch.kt @@ -0,0 +1,48 @@ +package app.revanced.patches.reddit.misc.openlink + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.reddit.misc.openlink.fingerprints.ScreenNavigatorFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.resultOrThrow + +@Patch +@Name("Open links directly") +@Description("Adds an option to skip over redirection URLs in external links.") +@DependsOn([SettingsPatch::class]) +@RedditCompatibility +@Suppress("unused") +class OpenLinksDirectlyPatch : BytecodePatch( + listOf(ScreenNavigatorFingerprint) +) { + companion object { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "$PATCHES_PATH/OpenLinksDirectlyPatch;" + + "->" + + "parseRedirectUri(Landroid/net/Uri;)Landroid/net/Uri;" + } + + override fun execute(context: BytecodeContext) { + ScreenNavigatorFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructions( + 0, """ + invoke-static {p2}, $INTEGRATIONS_METHOD_DESCRIPTOR + move-result-object p2 + """ + ) + } + } + + updateSettingsStatus("enableOpenLinksDirectly") + + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksExternallyPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksExternallyPatch.kt new file mode 100644 index 000000000..21d9d5dc2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksExternallyPatch.kt @@ -0,0 +1,53 @@ +package app.revanced.patches.reddit.misc.openlink + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.reddit.misc.openlink.fingerprints.ScreenNavigatorFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.getStringInstructionIndex +import app.revanced.util.resultOrThrow + +@Patch +@Name("Open links externally") +@Description("Adds an option to always open links in your browser instead of in the in-app-browser.") +@DependsOn([SettingsPatch::class]) +@RedditCompatibility +@Suppress("unused") +class OpenLinksExternallyPatch : BytecodePatch( + listOf(ScreenNavigatorFingerprint) +) { + companion object { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "$PATCHES_PATH/OpenLinksExternallyPatch;" + } + + override fun execute(context: BytecodeContext) { + ScreenNavigatorFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = getStringInstructionIndex("uri") + 2 + + addInstructions( + insertIndex, """ + invoke-static {p1, p2}, $INTEGRATIONS_METHOD_DESCRIPTOR->openLinksExternally(Landroid/app/Activity;Landroid/net/Uri;)Z + move-result v0 + if-eqz v0, :dismiss + return-void + """, listOf(ExternalLabel("dismiss", getInstruction(insertIndex))) + ) + } + } + + updateSettingsStatus("enableOpenLinksExternally") + + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/fingerprints/ScreenNavigatorFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/fingerprints/ScreenNavigatorFingerprint.kt new file mode 100644 index 000000000..5f632fd17 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/fingerprints/ScreenNavigatorFingerprint.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.reddit.misc.openlink.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +internal object ScreenNavigatorFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf( + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC + ), + strings = listOf("activity", "uri"), + customFingerprint = { _, classDef -> classDef.sourceFile == "RedditScreenNavigator.kt" } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/SanitizeUrlQueryPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/SanitizeUrlQueryPatch.kt new file mode 100644 index 000000000..ace12c2d5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/SanitizeUrlQueryPatch.kt @@ -0,0 +1,51 @@ +package app.revanced.patches.reddit.misc.tracking.url + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.reddit.misc.tracking.url.fingerprints.ShareLinkFormatterFingerprint +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH +import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.Companion.updateSettingsStatus +import app.revanced.patches.reddit.utils.settings.SettingsPatch +import app.revanced.util.getInstruction +import app.revanced.util.resultOrThrow + +@Patch +@Name("Sanitize sharing links") +@Description("Adds an option to remove tracking query parameters from URLs when sharing links.") +@DependsOn([SettingsPatch::class]) +@RedditCompatibility +@Suppress("unused") +class SanitizeUrlQueryPatch : BytecodePatch( + listOf(ShareLinkFormatterFingerprint) +) { + companion object { + private const val SANITIZE_METHOD_DESCRIPTOR = + "$PATCHES_PATH/SanitizeUrlQueryPatch;->stripQueryParameters()Z" + } + + override fun execute(context: BytecodeContext) { + ShareLinkFormatterFingerprint.resultOrThrow().let { result -> + result.mutableMethod.apply { + addInstructions( + 0, + """ + invoke-static {}, $SANITIZE_METHOD_DESCRIPTOR + move-result v0 + if-eqz v0, :off + return-object p0 + """, listOf(ExternalLabel("off", getInstruction(0))) + ) + } + } + + updateSettingsStatus("enableSanitizeUrlQuery") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/fingerprints/ShareLinkFormatterFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/fingerprints/ShareLinkFormatterFingerprint.kt new file mode 100644 index 000000000..58bf9a76b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/fingerprints/ShareLinkFormatterFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.reddit.misc.tracking.url.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +internal object ShareLinkFormatterFingerprint : MethodFingerprint( + returnType = "Ljava/lang/String;", + parameters = listOf("Ljava/lang/String;", "Ljava/util/Map;"), + customFingerprint = { methodDef, classDef -> + methodDef.definingClass.startsWith("Lcom/reddit/sharing/") + && classDef.sourceFile == "UrlUtil.kt" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/annotations/PremiumIconCompatibility.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/annotation/RedditCompatibility.kt similarity index 60% rename from src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/annotations/PremiumIconCompatibility.kt rename to src/main/kotlin/app/revanced/patches/reddit/utils/annotation/RedditCompatibility.kt index 079d5f6ca..53fc4b581 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/annotations/PremiumIconCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/annotation/RedditCompatibility.kt @@ -1,8 +1,9 @@ -package app.revanced.patches.reddit.layout.premiumicon.annotations +package app.revanced.patches.reddit.utils.annotation import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package @Compatibility([Package("com.reddit.frontpage")]) @Target(AnnotationTarget.CLASS) -internal annotation class PremiumIconCompatibility +internal annotation class RedditCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/Constants.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/Constants.kt new file mode 100644 index 000000000..566b1f23a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/Constants.kt @@ -0,0 +1,6 @@ +package app.revanced.patches.reddit.utils.integrations + +object Constants { + const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/reddit" + const val PATCHES_PATH = "$INTEGRATIONS_PATH/patches" +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/IntegrationsPatch.kt new file mode 100644 index 000000000..f1090a437 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/IntegrationsPatch.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.reddit.utils.integrations + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.patch.annotations.RequiresIntegrations +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.fingerprints.InitFingerprint +import app.revanced.patches.shared.integrations.BaseIntegrationsPatch + +@Name("reddit-integrations") +@RedditCompatibility +@RequiresIntegrations +internal class IntegrationsPatch : BaseIntegrationsPatch( + setOf(InitFingerprint), +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/fingerprints/InitFingerprint.kt new file mode 100644 index 000000000..e98bb6820 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/integrations/fingerprints/InitFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.utils.integrations.fingerprints + +import app.revanced.patches.shared.integrations.BaseIntegrationsPatch.IntegrationsFingerprint + +internal object InitFingerprint : IntegrationsFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/FrontpageApplication;") && + methodDef.name == "onCreate" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt new file mode 100644 index 000000000..43fd09b93 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.reddit.utils.resourceid + +import app.revanced.patcher.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.shared.mapping.ResourceMappingPatch +import app.revanced.patches.shared.mapping.ResourceMappingPatch.Companion.getId +import app.revanced.patches.shared.mapping.ResourceType.ID + +@DependsOn([ResourceMappingPatch::class]) +class SharedResourceIdPatch : ResourcePatch { + internal companion object { + var ToolBarNavSearchCtaContainer = -1L + } + + override fun execute(context: ResourceContext) { + + ToolBarNavSearchCtaContainer = getId(ID, "toolbar_nav_search_cta_container") + + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsBytecodePatch.kt new file mode 100644 index 000000000..cfc13cd02 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsBytecodePatch.kt @@ -0,0 +1,97 @@ +package app.revanced.patches.reddit.utils.settings + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotations.RequiresIntegrations +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.reddit.utils.integrations.Constants.INTEGRATIONS_PATH +import app.revanced.patches.reddit.utils.settings.fingerprints.AcknowledgementsLabelBuilderFingerprint +import app.revanced.patches.reddit.utils.settings.fingerprints.OssLicensesMenuActivityOnCreateFingerprint +import app.revanced.patches.reddit.utils.settings.fingerprints.SettingsStatusLoadFingerprint +import app.revanced.patches.shared.settings.fingerprints.SharedSettingFingerprint +import app.revanced.util.getInstruction +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.resultOrThrow +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction + +@RequiresIntegrations +class SettingsBytecodePatch : BytecodePatch( + listOf( + AcknowledgementsLabelBuilderFingerprint, + OssLicensesMenuActivityOnCreateFingerprint, + SharedSettingFingerprint, + SettingsStatusLoadFingerprint, + ) +) { + companion object { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "$INTEGRATIONS_PATH/settings/ActivityHook;->initialize(Landroid/app/Activity;)V" + + private lateinit var settingsStatusLoadMethod: MutableMethod + + internal fun updateSettingsStatus(description: String) { + settingsStatusLoadMethod.addInstruction( + 0, + "invoke-static {}, $INTEGRATIONS_PATH/settings/SettingsStatus;->$description()V" + ) + } + } + + override fun execute(context: BytecodeContext) { + + /** + * Set SharedPrefCategory + */ + SharedSettingFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val stringIndex = getTargetIndex(Opcode.CONST_STRING) + val stringRegister = getInstruction(stringIndex).registerA + + replaceInstruction( + stringIndex, + "const-string v$stringRegister, \"reddit_revanced\"" + ) + } + } + + /** + * Replace settings label + */ + AcknowledgementsLabelBuilderFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = + getTargetIndexWithMethodReferenceName("getString") + 2 + val insertRegister = + getInstruction(insertIndex - 1).registerA + + addInstruction( + insertIndex, + "const-string v$insertRegister, \"ReVanced Extended\"" + ) + } + } + + /** + * Initialize settings activity + */ + OssLicensesMenuActivityOnCreateFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + 1 + + addInstructions( + insertIndex, """ + invoke-static {p0}, $INTEGRATIONS_METHOD_DESCRIPTOR + return-void + """ + ) + } + } + + settingsStatusLoadMethod = SettingsStatusLoadFingerprint.resultOrThrow().mutableMethod + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt new file mode 100644 index 000000000..dde6e19b6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt @@ -0,0 +1,41 @@ +package app.revanced.patches.reddit.utils.settings + +import app.revanced.patcher.ResourceContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.apk.Apk +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.annotations.RequiresIntegrations +import app.revanced.patches.reddit.utils.annotation.RedditCompatibility +import app.revanced.patches.reddit.utils.integrations.IntegrationsPatch +import app.revanced.util.ResourceUtils.editText +import app.revanced.util.ResourceUtils.getResourcePath +import kotlin.io.path.exists + +@Patch +@Name("Settings") +@Description("Adds ReVanced Extended settings to Reddit.") +@DependsOn([IntegrationsPatch::class, SettingsBytecodePatch::class]) +@RedditCompatibility +@RequiresIntegrations +class SettingsPatch : ResourcePatch { + override fun execute(context: ResourceContext) { + /** + * Replace settings icon and label + */ + arrayOf("preferences", "preferences_logged_in").forEach { targetXML -> + fun Apk.transform() { + resources.openFile("res/xml/$targetXML.xml").editText { + it.replace( + "\"@drawable/icon_text_post\" android:title=\"@string/label_acknowledgements\"", + "\"@drawable/icon_beta_planet\" android:title=\"ReVanced Extended\"" + ) + } + } + context.apkBundle.all.forEach(Apk::transform) + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/AcknowledgementsLabelBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/AcknowledgementsLabelBuilderFingerprint.kt new file mode 100644 index 000000000..83816d620 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/AcknowledgementsLabelBuilderFingerprint.kt @@ -0,0 +1,15 @@ +package app.revanced.patches.reddit.utils.settings.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags + +internal object AcknowledgementsLabelBuilderFingerprint : MethodFingerprint( + returnType = "Z", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Landroidx/preference/Preference;"), + strings = listOf("onboardingAnalytics"), + customFingerprint = { methodDef, _ -> + methodDef.definingClass.startsWith("Lcom/reddit/screen/settings/preferences/") + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/OssLicensesMenuActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/OssLicensesMenuActivityOnCreateFingerprint.kt new file mode 100644 index 000000000..c1b72b8a0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/OssLicensesMenuActivityOnCreateFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.reddit.utils.settings.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +internal object OssLicensesMenuActivityOnCreateFingerprint : MethodFingerprint( + returnType = "V", + opcodes = listOf( + Opcode.IGET_BOOLEAN, + Opcode.IF_EQZ, + Opcode.INVOKE_STATIC + ), + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/OssLicensesMenuActivity;") && + methodDef.name == "onCreate" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/SettingsStatusLoadFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/SettingsStatusLoadFingerprint.kt new file mode 100644 index 000000000..cbf23e036 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/SettingsStatusLoadFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.reddit.utils.settings.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.reddit.utils.integrations.Constants.INTEGRATIONS_PATH + +internal object SettingsStatusLoadFingerprint : MethodFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("$INTEGRATIONS_PATH/settings/SettingsStatus;") && + methodDef.name == "load" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/fingerprints/SeekbarFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/SeekbarFingerprint.kt deleted file mode 100644 index 572ec2193..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/fingerprints/SeekbarFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.shared.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SeekbarFingerprint : MethodFingerprint( - "V", - strings = listOf("timed_markers_width") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/fingerprints/SeekbarOnDrawFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/SeekbarOnDrawFingerprint.kt deleted file mode 100644 index 7afcdae85..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/fingerprints/SeekbarOnDrawFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.shared.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SeekbarOnDrawFingerprint : MethodFingerprint( - customFingerprint = { it.name == "onDraw" } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/fingerprints/WatchWhileActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/WatchWhileActivityFingerprint.kt deleted file mode 100644 index b10c5e23e..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/fingerprints/WatchWhileActivityFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.shared.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object WatchWhileActivityFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "" - } -) diff --git a/src/main/kotlin/app/revanced/patches/shared/integrations/BaseIntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/shared/integrations/BaseIntegrationsPatch.kt new file mode 100644 index 000000000..2264875d2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/integrations/BaseIntegrationsPatch.kt @@ -0,0 +1,76 @@ +package app.revanced.patches.shared.integrations + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patches.shared.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver +import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_UTILS_CLASS_DESCRIPTOR +import app.revanced.util.resultOrThrow +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.ClassDef +import org.jf.dexlib2.iface.Method + +abstract class BaseIntegrationsPatch( + private val hooks: Set, +) : BytecodePatch(hooks) { + + override fun execute(context: BytecodeContext) { + if (context.classes.find { it.type == INTEGRATIONS_UTILS_CLASS_DESCRIPTOR } == null) { + throw PatchException( + "Integrations have not been merged yet. This patch can not succeed without merging the integrations.", + ) + } + + hooks.forEach { hook -> + hook.invoke(INTEGRATIONS_UTILS_CLASS_DESCRIPTOR) + } + } + + /** + * [MethodFingerprint] for integrations. + * + * @param contextRegisterResolver A [IRegisterResolver] to get the register. + * @see MethodFingerprint + */ + abstract class IntegrationsFingerprint( + returnType: String? = null, + accessFlags: Int? = null, + parameters: Iterable? = null, + opcodes: Iterable? = null, + strings: Iterable? = null, + customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, + private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {}, + private val contextRegisterResolver: (Method) -> String = object : IRegisterResolver {}, + ) : MethodFingerprint( + returnType, + accessFlags, + parameters, + opcodes, + strings, + customFingerprint, + ) { + + fun invoke(integrationsDescriptor: String) { + resultOrThrow().mutableMethod.let { method -> + val insertIndex = insertIndexResolver(method) + val contextRegister = contextRegisterResolver(method) + + method.addInstruction( + insertIndex, + "invoke-static/range { $contextRegister .. $contextRegister }, " + + "$integrationsDescriptor->setContext(Landroid/content/Context;)V", + ) + } + } + + interface IHookInsertIndexResolver : (Method) -> Int { + override operator fun invoke(method: Method) = 0 + } + + interface IRegisterResolver : (Method) -> String { + override operator fun invoke(method: Method) = "p0" + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/integrations/Constants.kt b/src/main/kotlin/app/revanced/patches/shared/integrations/Constants.kt new file mode 100644 index 000000000..ea038473d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/integrations/Constants.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.shared.integrations + +object Constants { + private const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/shared" + + const val INTEGRATIONS_SETTING_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/settings/Setting;" + const val INTEGRATIONS_UTILS_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/utils/Utils;" +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/integrations/patch/AbstractIntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/shared/integrations/patch/AbstractIntegrationsPatch.kt deleted file mode 100644 index 2ef2e48dc..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/integrations/patch/AbstractIntegrationsPatch.kt +++ /dev/null @@ -1,66 +0,0 @@ -package app.revanced.patches.shared.integrations.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import org.jf.dexlib2.iface.Method - -@Description("Applies mandatory patches to implement the ReVanced integrations into the application.") -@Version("0.0.1") -abstract class AbstractIntegrationsPatch( - private val integrationsDescriptor: String, - private val hooks: Iterable -) : BytecodePatch(hooks) { - /** - * [MethodFingerprint] for integrations. - * - * @param contextRegisterResolver A [RegisterResolver] to get the register. - * @see MethodFingerprint - */ - abstract class IntegrationsFingerprint( - strings: Iterable? = null, - customFingerprint: ((methodDef: Method) -> Boolean)? = null, - private val contextRegisterResolver: (Method) -> Int = object : RegisterResolver {} - ) : MethodFingerprint(strings = strings, customFingerprint = customFingerprint) { - fun invoke(integrationsDescriptor: String): PatchResult { - result?.mutableMethod?.let { method -> - val contextRegister = contextRegisterResolver(method) - - method.addInstruction( - 0, - "sput-object v$contextRegister, " + - "$integrationsDescriptor->context:Landroid/content/Context;" - ) - } ?: return PatchResultError("Could not find hook target fingerprint.") - - return PatchResultSuccess() - } - - interface RegisterResolver : (Method) -> Int { - override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1 - } - } - - override fun execute(context: BytecodeContext): PatchResult { - if (context.findClass(integrationsDescriptor) == null) return MISSING_INTEGRATIONS - - for (hook in hooks) hook.invoke(integrationsDescriptor).let { - if (it is PatchResultError) return it - } - - return PatchResultSuccess() - } - - private companion object { - val MISSING_INTEGRATIONS = PatchResultError( - "Integrations have not been merged yet. " + - "This patch can not succeed without merging the integrations." - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt b/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt new file mode 100644 index 000000000..38e20bbc9 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt @@ -0,0 +1,30 @@ +package app.revanced.patches.shared.mapping + +import app.revanced.patcher.ResourceContext +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.util.ResourceUtils.resourceIdOf + +class ResourceMappingPatch : ResourcePatch { + companion object { + private var resourceContext: ResourceContext? = null + + fun getId(resourceType: ResourceType, name: String): Long = + resourceIdOf(resourceType.value, name) + + /** + * Resolve a resource id for the specified resource. + * + * @param type The type of the resource. + * @param name The name of the resource. + * @return The id of the resource. + */ + private fun resourceIdOf(type: String, name: String): Long = resourceContext?.resourceIdOf(type, name) + ?: -1L + } + + override fun execute(context: ResourceContext) { + resourceContext = context + + } +} diff --git a/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceType.kt b/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceType.kt new file mode 100644 index 000000000..ba86dfe3e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceType.kt @@ -0,0 +1,15 @@ +package app.revanced.patches.shared.mapping + +@Suppress("unused") +enum class ResourceType(val value: String) { + ATTR("attr"), + BOOL("bool"), + COLOR("color"), + DIMEN("dimen"), + DRAWABLE("drawable"), + ID("id"), + INTEGER("integer"), + LAYOUT("layout"), + STRING("string"), + STYLE("style") +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/mapping/misc/patch/ResourceMappingPatch.kt b/src/main/kotlin/app/revanced/patches/shared/mapping/misc/patch/ResourceMappingPatch.kt deleted file mode 100644 index b607dc283..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/mapping/misc/patch/ResourceMappingPatch.kt +++ /dev/null @@ -1,73 +0,0 @@ -package app.revanced.patches.shared.mapping.misc.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import org.w3c.dom.Element -import java.util.* -import java.util.concurrent.Executors -import java.util.concurrent.TimeUnit - - -@Name("resource-mapping") -@Description("Creates a map of public resources.") -@Version("0.0.1") -class ResourceMappingPatch : ResourcePatch { - companion object { - internal lateinit var resourceMappings: List - private set - - private val THREAD_COUNT = Runtime.getRuntime().availableProcessors() - private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT) - } - - override fun execute(context: ResourceContext): PatchResult { - // save the file in memory to concurrently read from - val resourceXmlFile = context["res/values/public.xml"].readBytes() - - // create a synchronized list to store the resource mappings - val mappings = Collections.synchronizedList(mutableListOf()) - - for (threadIndex in 0 until THREAD_COUNT) { - threadPoolExecutor.execute thread@{ - context.xmlEditor[resourceXmlFile.inputStream()].use { editor -> - val resources = editor.file.documentElement.childNodes - val resourcesLength = resources.length - val jobSize = resourcesLength / THREAD_COUNT - - val batchStart = jobSize * threadIndex - val batchEnd = jobSize * (threadIndex + 1) - element@ for (i in batchStart until batchEnd) { - // make sure to not to go out of bounds when rounding errors occur at calculating the jobSize - if (i >= resourcesLength) return@thread - - val node = resources.item(i) - if (node !is Element) continue - - val nameAttribute = node.getAttribute("name") - val typeAttribute = node.getAttribute("type") - - if (node.nodeName != "public" || nameAttribute.startsWith("APKTOOL")) continue - - val id = node.getAttribute("id").substring(2).toLong(16) - mappings.add(ResourceElement(typeAttribute, nameAttribute, id)) - } - } - } - } - - threadPoolExecutor - .also { it.shutdown() } - .awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS) - - resourceMappings = mappings - - return PatchResultSuccess() - } -} - -data class ResourceElement(val type: String, val name: String, val id: Long) diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/annotations/ClientSpoofCompatibility.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/annotations/ClientSpoofCompatibility.kt deleted file mode 100644 index 8ed8a4716..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/annotations/ClientSpoofCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.shared.misc.fix.spoof.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.google.android.youtube"), - Package("com.vanced.android.youtube") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class ClientSpoofCompatibility diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/fingerprints/UserAgentHeaderBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/fingerprints/UserAgentHeaderBuilderFingerprint.kt deleted file mode 100644 index f3cf363e3..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/fingerprints/UserAgentHeaderBuilderFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.shared.misc.fix.spoof.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object UserAgentHeaderBuilderFingerprint : MethodFingerprint( - parameters = listOf("L", "L", "L"), - opcodes = listOf(Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_VIRTUAL), - strings = listOf("(Linux; U; Android "), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt deleted file mode 100644 index 49c91185d..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.shared.misc.fix.spoof.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.misc.fix.spoof.annotations.ClientSpoofCompatibility -import app.revanced.patches.shared.misc.fix.spoof.fingerprints.UserAgentHeaderBuilderFingerprint -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction - -@Patch -@Name("client-spoof") -@Description("Spoofs a patched client to allow playback.") -@ClientSpoofCompatibility -@Version("0.0.1") -class ClientSpoofPatch : BytecodePatch( - listOf(UserAgentHeaderBuilderFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - UserAgentHeaderBuilderFingerprint.result?.let { result -> - val insertIndex = result.scanResult.patternScanResult!!.endIndex - result.mutableMethod.apply { - val packageNameRegister = (instruction(insertIndex) as FiveRegisterInstruction).registerD - addInstruction(insertIndex, "const-string v$packageNameRegister, \"$ORIGINAL_PACKAGE_NAME\"") - } - - } ?: return UserAgentHeaderBuilderFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube" - } -} diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/annotations/VerticalScrollCompatibility.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/annotations/VerticalScrollCompatibility.kt deleted file mode 100644 index bd19fbc45..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/annotations/VerticalScrollCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.shared.misc.fix.verticalscroll.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.google.android.youtube"), - Package("com.vanced.android.youtube") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class VerticalScrollCompatibility diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/fingerprints/CanScrollVerticallyFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/fingerprints/CanScrollVerticallyFingerprint.kt deleted file mode 100644 index e5d137ca6..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/fingerprints/CanScrollVerticallyFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.shared.misc.fix.verticalscroll.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object CanScrollVerticallyFingerprint : MethodFingerprint( - "Z", - parameters = emptyList(), - opcodes = listOf( - Opcode.MOVE_RESULT, - Opcode.RETURN, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - ), - customFingerprint = { methodDef -> methodDef.definingClass.endsWith("SwipeRefreshLayout;") } -) diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/patch/VerticalScrollPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/patch/VerticalScrollPatch.kt deleted file mode 100644 index 557ccb5a3..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/verticalscroll/patch/VerticalScrollPatch.kt +++ /dev/null @@ -1,39 +0,0 @@ -package app.revanced.patches.shared.misc.fix.verticalscroll.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.shared.misc.fix.verticalscroll.annotations.VerticalScrollCompatibility -import app.revanced.patches.shared.misc.fix.verticalscroll.fingerprints.CanScrollVerticallyFingerprint -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Description("Fixes issues with scrolling on the home screen when the first component is of type EmptyComponent.") -@VerticalScrollCompatibility -@Version("0.0.1") -class VerticalScrollPatch : BytecodePatch( - listOf(CanScrollVerticallyFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = CanScrollVerticallyFingerprint.result ?: return CanScrollVerticallyFingerprint.toErrorResult() - - with(result) { - val method = mutableMethod - - val moveResultIndex = scanResult.patternScanResult!!.endIndex - val moveResultRegister = (method.instruction(moveResultIndex) as OneRegisterInstruction).registerA - - method.addInstruction( - moveResultIndex + 1, - "const/4 v$moveResultRegister, 0x0" - ) - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/fingerprints/SharedSettingFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/settings/fingerprints/SharedSettingFingerprint.kt new file mode 100644 index 000000000..094e642f6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/settings/fingerprints/SharedSettingFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.shared.settings.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_SETTING_CLASS_DESCRIPTOR + +internal object SharedSettingFingerprint : MethodFingerprint( + returnType = "V", + customFingerprint = { methodDef, _ -> + methodDef.definingClass == INTEGRATIONS_SETTING_CLASS_DESCRIPTOR + && methodDef.name == "" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/BasePreference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/BasePreference.kt deleted file mode 100644 index 1853a97c6..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/BasePreference.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.shared.settings.preference - -import app.revanced.patches.shared.settings.preference.impl.StringResource -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Base preference class for all preferences. - * - * @param key The key of the preference. - * @param title The title of the preference. - */ -internal abstract class BasePreference( - override val key: String, - override val title: StringResource, -) : IPreference { - - /** - * Serialize preference element to XML. - * Overriding methods should invoke super and operate on its return value. - * @param ownerDocument Target document to create elements from. - * @param resourceCallback Called when a resource has been processed. - */ - open fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)? = null): Element { - return ownerDocument.createElement(tag).apply { - if(key.isNotEmpty()) - setAttribute("android:key", key) - setAttribute("android:title", "@string/${title.also { resourceCallback?.invoke(it) }.name}") - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/BaseResource.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/BaseResource.kt deleted file mode 100644 index 5c5e4174b..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/BaseResource.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.shared.settings.preference - -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Base resource class for all resources. - * - * @param name The name of the resource. - */ -internal abstract class BaseResource( - override val name: String -) : IResource { - - /** - * Serialize resource element to XML. - * Overriding methods should invoke super and operate on its return value. - * @param ownerDocument Target document to create elements from. - * @param resourceCallback Called when a resource has been processed. - */ - open fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)? = null): Element { - return ownerDocument.createElement(tag).apply { - setAttribute("name", name) - } - } -} \ 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 deleted file mode 100644 index b0e8ddbd6..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/ComponentsExtensions.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.shared.settings.preference - -import app.revanced.patches.shared.settings.preference.impl.StringResource -import org.w3c.dom.Element -import org.w3c.dom.Node - -/** - * Add a resource node child - * - * @param resource The resource to add. - * @param resourceCallback Called when a resource has been processed. - */ -internal fun Node.addResource(resource: BaseResource, resourceCallback: ((IResource) -> Unit)? = null) { - appendChild(resource.serialize(ownerDocument, resourceCallback)) -} - -/** - * Add a preference node child to the settings. - * - * @param preference The preference to add. - * @param resourceCallback Called when a resource has been processed. - */ -internal fun Node.addPreference(preference: BasePreference, resourceCallback: ((IResource) -> Unit)? = null) { - appendChild(preference.serialize(ownerDocument, resourceCallback)) -} - -internal fun Element.addSummary(summaryResource: StringResource?, summaryType: SummaryType = SummaryType.DEFAULT) = - summaryResource?.let { summary -> - setAttribute("android:${summaryType.type}", "@string/${summary.name}") - } - -internal fun Element.addDefault(default: T) { - default?.let { - setAttribute( - "android:defaultValue", when (it) { - is Boolean -> if (it) "true" else "false" - is String -> it - else -> throw IllegalArgumentException("Unsupported default value type: ${it::class.java.name}") - } - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/IPreference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/IPreference.kt deleted file mode 100644 index ec31835ba..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/IPreference.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.shared.settings.preference - -import app.revanced.patches.shared.settings.preference.impl.StringResource - -/** - * Preference - */ -internal interface IPreference { - /** - * Key of the preference. - */ - val key: String - - /** - * Title of the preference. - */ - val title: StringResource - - /** - * Tag name of the preference. - */ - val tag: String -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/IResource.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/IResource.kt deleted file mode 100644 index dc3fe610e..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/IResource.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.shared.settings.preference - -/** - * Resource - */ -internal interface IResource { - /** - * Name of the resource. - */ - val name: String - - /** - * Tag name of the resource. - */ - val tag: String -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/SummaryType.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/SummaryType.kt deleted file mode 100644 index 006f6986c..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/SummaryType.kt +++ /dev/null @@ -1,5 +0,0 @@ -package app.revanced.patches.shared.settings.preference - -enum class SummaryType(val type: String) { - DEFAULT("summary"), ON("summaryOn"), OFF("summaryOff") -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ArrayResource.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ArrayResource.kt deleted file mode 100644 index 90795e1f7..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ArrayResource.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BaseResource -import app.revanced.patches.shared.settings.preference.IResource -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Represents an array resource. - * - * @param name The name of the array resource. - * @param items The items of the array resource. - */ -// TODO: allow specifying an array resource file instead of using a list of StringResources -internal data class ArrayResource( - override val name: String, - val items: List -) : BaseResource(name) { - override val tag = "string-array" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - setAttribute("name", name) - - items.forEach { item -> - resourceCallback?.invoke(item) - - this.appendChild(ownerDocument.createElement("item").also { itemNode -> - itemNode.textContent = "@string/${item.name}" - }) - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/InputType.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/InputType.kt deleted file mode 100644 index 09432143b..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/InputType.kt +++ /dev/null @@ -1,6 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -enum class InputType(val type: String) { - STRING("text"), - NUMBER("number"), -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ListPreference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ListPreference.kt deleted file mode 100644 index 9f2f9f84e..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ListPreference.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import app.revanced.patches.shared.settings.preference.addDefault -import app.revanced.patches.shared.settings.preference.addSummary -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * List preference. - * - * @param key The key of the list preference. - * @param title The title of the list preference. - * @param entries The human-readable entries of the list preference. - * @param entryValues The entry values of the list preference. - * @param default The default entry value of the list preference. - * @param summary The summary of the list preference. - */ -internal class ListPreference( - key: String, - title: StringResource, - val entries: ArrayResource, - val entryValues: ArrayResource, - val default: String? = null, - val summary: StringResource? = null -) : BasePreference(key, title) { - override val tag: String = "ListPreference" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - setAttribute("android:entries", "@array/${entries.also { resourceCallback?.invoke(it) }.name}") - setAttribute("android:entryValues", "@array/${entryValues.also { resourceCallback?.invoke(it) }.name}") - addDefault(default) - addSummary(summary) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/NonInteractivePreference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/NonInteractivePreference.kt deleted file mode 100644 index 9332bd17d..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/NonInteractivePreference.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import app.revanced.patches.shared.settings.preference.addSummary -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * A simple static title and summary that is not backed by any preference key/value, - * and cannot be changed by or interacted with by the user, - */ -internal class NonInteractivePreference( - title: StringResource, - val summary: StringResource, -) : BasePreference("", title) { - override val tag: String = "Preference" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - addSummary(summary.also { resourceCallback?.invoke(it) - setAttribute("android:selectable", false.toString()) - }) - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/Preference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/Preference.kt deleted file mode 100644 index fcacd61d7..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/Preference.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import app.revanced.patches.shared.settings.preference.addSummary -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * A Preference object. - * - * @param title The title of the preference. - * @param intent The intent of the preference. - * @param summary The summary of the text preference. - */ -internal class Preference( - key: String, - title: StringResource, - val intent: Intent, - val summary: StringResource? = null -) : BasePreference(key, title) { - override val tag: String = "Preference" - - /* Key-less constructor */ - constructor( - title: StringResource, - intent: Intent, - summary: StringResource? = null - ) : this("", title, intent, summary) - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - addSummary(summary?.also { resourceCallback?.invoke(it) }) - - this.appendChild(ownerDocument.createElement("intent").also { intentNode -> - intentNode.setAttribute("android:targetPackage", intent.targetPackage) - intentNode.setAttribute("android:data", intent.data) - intentNode.setAttribute("android:targetClass", intent.targetClass) - }) - } - } - - data class Intent(val targetPackage: String, val data: String, val targetClass: String) -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/PreferenceCategory.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/PreferenceCategory.kt deleted file mode 100644 index f575dfe3a..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/PreferenceCategory.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Preference category. - * - * @param key The key of the preference. - * @param title The title of the preference. - * @param preferences Child preferences of this category. - */ -internal open class PreferenceCategory( - key: String, - title: StringResource, - var preferences: List -) : BasePreference(key, title) { - override val tag: String = "PreferenceCategory" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - for (childPreference in preferences) { - this.appendChild(childPreference.serialize(ownerDocument, resourceCallback)) - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/PreferenceScreen.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/PreferenceScreen.kt deleted file mode 100644 index b7c82ba6f..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/PreferenceScreen.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import app.revanced.patches.shared.settings.preference.addSummary -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Preference screen. - * - * @param key The key of the preference. - * @param title The title of the preference. - * @param preferences Child preferences of this screen. - * @param summary The summary of the text preference. - */ -internal open class PreferenceScreen( - key: String, - title: StringResource, - var preferences: List, - val summary: StringResource? = null -) : BasePreference(key, title) { - override val tag: String = "PreferenceScreen" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - addSummary(summary?.also { resourceCallback?.invoke(it) }) - - for (childPreference in preferences) { - this.appendChild(childPreference.serialize(ownerDocument, resourceCallback)) - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/StringResource.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/StringResource.kt deleted file mode 100644 index 49471faa8..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/StringResource.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BaseResource -import app.revanced.patches.shared.settings.preference.IResource -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Represents a string value in the strings.xml file - * - * @param name The name of the string - * @param value The value of the string - * @param formatted If the string is formatted. If false, the attribute will be set - */ -internal data class StringResource( - override val name: String, - val value: String, - val formatted: Boolean = true -) : BaseResource(name) { - override val tag = "string" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - // if the string is un-formatted, explicitly add the formatted attribute - if (!formatted) - setAttribute("formatted", "false") - - textContent = value - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/SwitchPreference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/SwitchPreference.kt deleted file mode 100644 index 2845849bc..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/SwitchPreference.kt +++ /dev/null @@ -1,37 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.* -import app.revanced.patches.shared.settings.resource.patch.AbstractSettingsResourcePatch.Companion.include -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Switch preference. - * - * @param key The key of the switch. - * @param title The title of the switch. - * @param default The default value of the switch. - * @param summaryOn The summary to show when the preference is enabled. - * @param summaryOff The summary to show when the preference is disabled. - * @param userDialogMessage The message to show in a dialog when the user toggles the preference. - */ -internal class SwitchPreference( - key: String, title: StringResource, - val default: Boolean = false, - val summaryOn: StringResource? = null, - val summaryOff: StringResource? = null, - val userDialogMessage: StringResource? = null -) : BasePreference(key, title) { - override val tag: String = "SwitchPreference" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - // dialog message is stored as a regular string and later referenced by SettingsEnum - userDialogMessage?.include() - - return super.serialize(ownerDocument, resourceCallback).apply { - addDefault(default) - addSummary(summaryOn?.also { resourceCallback?.invoke(it) }, SummaryType.ON) - addSummary(summaryOff?.also { resourceCallback?.invoke(it) }, SummaryType.OFF) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/TextPreference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/TextPreference.kt deleted file mode 100644 index 907a4a160..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/TextPreference.kt +++ /dev/null @@ -1,35 +0,0 @@ -package app.revanced.patches.shared.settings.preference.impl - -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import app.revanced.patches.shared.settings.preference.addDefault -import app.revanced.patches.shared.settings.preference.addSummary -import org.w3c.dom.Document -import org.w3c.dom.Element - -/** - * Text preference. - * - * @param key The key of the text preference. - * @param title The title of the text preference. - * @param inputType The input type of the text preference. - * @param default The default value of the text preference. - * @param summary The summary of the text preference. - */ -internal class TextPreference( - key: String, - title: StringResource, - var inputType: InputType = InputType.STRING, - val default: String? = null, - val summary: StringResource? = null -) : BasePreference(key, title) { - override val tag: String = "EditTextPreference" - - override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { - return super.serialize(ownerDocument, resourceCallback).apply { - setAttribute("android:inputType", inputType.type) - addDefault(default) - addSummary(summary?.also { resourceCallback?.invoke(it) }) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/resource/patch/AbstractSettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/settings/resource/patch/AbstractSettingsResourcePatch.kt deleted file mode 100644 index 778916b55..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/resource/patch/AbstractSettingsResourcePatch.kt +++ /dev/null @@ -1,136 +0,0 @@ -package app.revanced.patches.shared.settings.resource.patch - -import app.revanced.patcher.data.DomFileEditor -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import app.revanced.patches.shared.settings.preference.addPreference -import app.revanced.patches.shared.settings.preference.addResource -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources -import org.w3c.dom.Node - -/** - * Abstract settings resource patch - * - * @param preferenceFileName Name of the settings preference xml file - * @param sourceDirectory Source directory to copy the preference template from - */ -abstract class AbstractSettingsResourcePatch( - private val preferenceFileName: String, - private val sourceDirectory: String, -) : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - /* - * used for self-restart - * TODO: do this only, when necessary - */ - context.xmlEditor["AndroidManifest.xml"].use { editor -> - editor.file.getElementsByTagName("manifest").item(0).also { - it.appendChild(it.ownerDocument.createElement("uses-permission").also { element -> - element.setAttribute("android:name", "android.permission.SCHEDULE_EXACT_ALARM") - }) - } - } - - /* copy preference template from source dir */ - context.copyResources( - sourceDirectory, - ResourceUtils.ResourceGroup( - "xml", "$preferenceFileName.xml" - ) - ) - - /* prepare xml editors */ - stringsEditor = context.xmlEditor["res/values/strings.xml"] - arraysEditor = context.xmlEditor["res/values/arrays.xml"] - revancedPreferencesEditor = context.xmlEditor["res/xml/$preferenceFileName.xml"] - - return PatchResultSuccess() - } - - internal companion object { - private var revancedPreferenceNode: Node? = null - private var stringsNode: Node? = null - private var arraysNode: Node? = null - - private var strings = mutableListOf() - - private var revancedPreferencesEditor: DomFileEditor? = null - set(value) { - field = value - revancedPreferenceNode = value.getNode("PreferenceScreen") - } - private var stringsEditor: DomFileEditor? = null - set(value) { - field = value - stringsNode = value.getNode("resources") - } - private var arraysEditor: DomFileEditor? = null - set(value) { - field = value - arraysNode = value.getNode("resources") - } - - /** - * Add a new string to the resources. - * - * @param identifier The key of the string. - * @param value The value of the string. - * @throws IllegalArgumentException if the string already exists. - */ - fun addString(identifier: String, value: String, formatted: Boolean) = - StringResource(identifier, value, formatted).include() - - /** - * Add an array to the resources. - * - * @param arrayResource The array resource to add. - */ - fun addArray(arrayResource: ArrayResource) = - arraysNode!!.addResource(arrayResource) { it.include() } - - /** - * Add a preference to the settings. - * - * @param preference The preference to add. - */ - fun addPreference(preference: BasePreference) = - revancedPreferenceNode!!.addPreference(preference) { it.include() } - - /** - * Add a new resource to the resources. - * - * @throws IllegalArgumentException if the resource already exists. - */ - internal fun IResource.include() { - when (this) { - is StringResource -> { - if (strings.any { it.name == name }) return - strings.add(this) - } - - is ArrayResource -> addArray(this) - else -> throw NotImplementedError("Unsupported resource type") - } - } - - internal fun DomFileEditor?.getNode(tagName: String) = this!!.file.getElementsByTagName(tagName).item(0) - } - - override fun close() { - // merge all strings, skip duplicates - strings.forEach { - stringsNode!!.addResource(it) - } - - revancedPreferencesEditor?.close() - stringsEditor?.close() - arraysEditor?.close() - } -} \ 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 deleted file mode 100644 index a257af9a2..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/settings/util/AbstractPreferenceScreen.kt +++ /dev/null @@ -1,89 +0,0 @@ -package app.revanced.patches.shared.settings.util - -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 java.io.Closeable - -internal abstract class AbstractPreferenceScreen( - private val root: MutableList = mutableListOf() -) : Closeable { - - override fun close() { - if (root.isEmpty()) - return - - for (preference in root.sortedBy { it.title }) { - commit(preference.transform()) - } - } - - /** - * Finalize and insert root preference into resource patch - */ - abstract fun commit(screen: PreferenceScreen) - - open inner class Screen( - key: String, - title: String, - val summary: String? = null, - preferences: MutableList = mutableListOf(), - val categories: MutableList = mutableListOf() - ) : BasePreferenceCollection(key, title, preferences) { - override fun transform(): PreferenceScreen { - return PreferenceScreen( - key, - StringResource("${key}_title", title), - preferences.sortedBy { it.title.value } + - categories.sortedBy { it.title }.map { it.transform() }, - summary?.let { summary -> - StringResource("${key}_summary", summary) - } - ) - } - - private fun ensureScreenInserted() { - // Add to screens if not yet done - if(!this@AbstractPreferenceScreen.root.contains(this)) - this@AbstractPreferenceScreen.root.add(this) - } - - fun addPreferences(vararg preferences: BasePreference) { - ensureScreenInserted() - this.preferences.addAll(preferences) - } - - open inner class Category( - key: String, - title: String, - preferences: MutableList = mutableListOf() - ): BasePreferenceCollection(key, title, preferences) { - override fun transform(): PreferenceCategory { - return PreferenceCategory( - key, - StringResource("${key}_title", title), - preferences.sortedBy { it.title.value } - ) - } - - fun addPreferences(vararg preferences: BasePreference) { - ensureScreenInserted() - - // Add to categories if not yet done - if(!this@Screen.categories.contains(this)) - this@Screen.categories.add(this) - - this.preferences.addAll(preferences) - } - } - } - - abstract class BasePreferenceCollection( - val key: String, - val title: String, - val preferences: MutableList = mutableListOf() - ) { - abstract fun transform(): BasePreference - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/audio/annotation/DisableCaptureRestrictionCompatibility.kt b/src/main/kotlin/app/revanced/patches/spotify/audio/annotation/DisableCaptureRestrictionCompatibility.kt deleted file mode 100644 index 849e34b5d..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/audio/annotation/DisableCaptureRestrictionCompatibility.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.spotify.audio.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package("com.spotify.music")] -) -@Target(AnnotationTarget.CLASS) -internal annotation class DisableCaptureRestrictionCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/spotify/audio/bytecode/patch/DisableCaptureRestrictionBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/spotify/audio/bytecode/patch/DisableCaptureRestrictionBytecodePatch.kt deleted file mode 100644 index 88aae6a28..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/audio/bytecode/patch/DisableCaptureRestrictionBytecodePatch.kt +++ /dev/null @@ -1,86 +0,0 @@ -package app.revanced.patches.spotify.audio.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.spotify.audio.annotation.DisableCaptureRestrictionCompatibility -import app.revanced.patches.spotify.audio.fingerprints.DisableCaptureRestrictionAudioDriverFingerprint -import app.revanced.patches.spotify.audio.resource.patch.DisableCaptureRestrictionResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.MethodReference - -@Patch -@Name("disable-capture-restriction") -@DependsOn([DisableCaptureRestrictionResourcePatch::class]) -@Description("Allows capturing Spotify's audio output while screen sharing or screen recording.") -@DisableCaptureRestrictionCompatibility -@Version("0.0.2") -class DisableCaptureRestrictionBytecodePatch : BytecodePatch( - listOf( - DisableCaptureRestrictionAudioDriverFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = DisableCaptureRestrictionAudioDriverFingerprint.result!!.mutableMethod - - var invokePosition: Int? = null - var invokeParamRegister: Int? = null - - // Find INVOKE_VIRTUAL opcode with call to AudioAttributesBuilder.setAllowedCapturePolicy(I) - for ((index, instruction) in method.implementation!!.instructions.withIndex()) { - if(instruction.opcode != Opcode.INVOKE_VIRTUAL) - continue - - val methodName = ((instruction as ReferenceInstruction).reference as MethodReference).name - if (methodName != "setAllowedCapturePolicy") - continue - - // Store register of the integer parameter for setAllowedCapturePolicy - invokeParamRegister = (instruction as FiveRegisterInstruction).registerD - invokePosition = index - } - - if(invokePosition == null || invokeParamRegister == null) - return PatchResultError("Cannot find setAllowedCapturePolicy method call") - - // Walk back to the const/4 instruction that sets the parameter register - var matchFound = false - for (index in invokePosition downTo 0) { - val instruction = method.instruction(index) - if(instruction.opcode != Opcode.CONST_4) - continue - - val register = (instruction as OneRegisterInstruction).registerA - if(register != invokeParamRegister) - continue - - // Replace parameter value - method.replaceInstruction( - index, "const/4 v$register, $ALLOW_CAPTURE_BY_ALL" - ) - matchFound = true - break - } - - return if (matchFound) - PatchResultSuccess() - else - PatchResultError("Const instruction not found") - } - - private companion object { - const val ALLOW_CAPTURE_BY_ALL = 0x01 - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/audio/fingerprints/DisableCaptureRestrictionAudioDriverFingerprint.kt b/src/main/kotlin/app/revanced/patches/spotify/audio/fingerprints/DisableCaptureRestrictionAudioDriverFingerprint.kt deleted file mode 100644 index 191755518..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/audio/fingerprints/DisableCaptureRestrictionAudioDriverFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.spotify.audio.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object DisableCaptureRestrictionAudioDriverFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/spotify/playback/playbacknative/AudioDriver;" && methodDef.name == "constructAudioAttributes" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/audio/resource/patch/DisableCaptureRestrictionResourcePatch.kt b/src/main/kotlin/app/revanced/patches/spotify/audio/resource/patch/DisableCaptureRestrictionResourcePatch.kt deleted file mode 100644 index 5088cce81..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/audio/resource/patch/DisableCaptureRestrictionResourcePatch.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.revanced.patches.spotify.audio.resource.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patches.spotify.audio.annotation.DisableCaptureRestrictionCompatibility -import org.w3c.dom.Element - -@Name("disable-capture-restriction-resource-patch") -@Description("Sets allowAudioPlaybackCapture in manifest to true.") -@DisableCaptureRestrictionCompatibility -@Version("0.0.2") -class DisableCaptureRestrictionResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - // create an xml editor instance - context.xmlEditor["AndroidManifest.xml"].use { dom -> - // get the application node - val applicationNode = dom - .file - .getElementsByTagName("application") - .item(0) as Element - - // set allowAudioPlaybackCapture attribute to true - applicationNode.setAttribute("android:allowAudioPlaybackCapture", "true") - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/annotations/ThemeCompatibility.kt b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/annotations/ThemeCompatibility.kt deleted file mode 100644 index 5a855c9fd..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/annotations/ThemeCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.spotify.layout.theme.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.spotify.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class ThemeCompatibility diff --git a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/patch/ThemePatch.kt b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/patch/ThemePatch.kt deleted file mode 100644 index 731f1b3d1..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/patch/ThemePatch.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.patches.spotify.layout.theme.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.spotify.layout.theme.annotations.ThemeCompatibility -import org.w3c.dom.Element - -@Patch -@Name("spotify-theme") -@Description("Applies a custom theme.") -@ThemeCompatibility -@Version("0.0.1") -class ThemePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - context.xmlEditor["res/values/colors.xml"].use { editor -> - val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element - - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue - - node.textContent = when (node.getAttribute("name")) { - "gray_7" -> backgroundColor!! - "dark_brightaccent_background_base", "dark_base_text_brightaccent", "green_light" -> accentColor!! - "dark_brightaccent_background_press" -> accentPressedColor!! - else -> continue - } - } - } - - return PatchResultSuccess() - } - - companion object : OptionsContainer() { - var backgroundColor: String? by option( - PatchOption.StringOption( - key = "backgroundColor", - default = "@android:color/black", - title = "Background color", - description = "The background color. Can be a hex color or a resource reference.", - ) - ) - var accentColor: String? by option( - PatchOption.StringOption( - key = "accentColor", - default = "#ff1ed760", - title = "Accent color", - description = "The accent color ('spotify green' by default). Can be a hex color or a resource reference.", - ) - ) - var accentPressedColor: String? by option( - PatchOption.StringOption( - 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.", - ) - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt deleted file mode 100644 index 2550824b2..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.spotify.lite.ondemand.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package("com.spotify.lite")] -) -@Target(AnnotationTarget.CLASS) -internal annotation class OnDemandCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt deleted file mode 100644 index 099eaa438..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.spotify.lite.ondemand.fingerprints - -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) -object OnDemandFingerprint : MethodFingerprint( - "L", - parameters = listOf(), - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_EQZ, - Opcode.SGET_OBJECT, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IPUT, - Opcode.RETURN_OBJECT - ) -) diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt deleted file mode 100644 index bbb5159ef..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.spotify.lite.ondemand.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.spotify.lite.ondemand.annotations.OnDemandCompatibility -import app.revanced.patches.spotify.lite.ondemand.fingerprints.OnDemandFingerprint - -@Patch -@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.") -@OnDemandCompatibility -@Version("0.0.1") -class OnDemandPatch : BytecodePatch( - listOf( - OnDemandFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - OnDemandFingerprint.result?.apply { - val insertIndex = scanResult.patternScanResult!!.endIndex - 1 - // Spoof a premium account - mutableMethod.addInstruction(insertIndex, "const/4 v0, 0x2") - } ?: return OnDemandFingerprint.toErrorResult() - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/annotations/PremiumNavbarTabCompatibility.kt b/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/annotations/PremiumNavbarTabCompatibility.kt deleted file mode 100644 index 6924ba5d4..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/annotations/PremiumNavbarTabCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.spotify.premium_navbar_tab.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.spotify.music")]) -@Target(AnnotationTarget.CLASS) -internal annotation class PremiumNavbarTabCompatibility diff --git a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/fingerprints/AddPremiumNavbarTabFingerprint.kt b/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/fingerprints/AddPremiumNavbarTabFingerprint.kt deleted file mode 100644 index 296c87f8d..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/fingerprints/AddPremiumNavbarTabFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.spotify.premium_navbar_tab.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object AddPremiumNavbarTabFingerprint : MethodFingerprint( - parameters = listOf("L", "L", "L", "L", "L", "L") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/fingerprints/AddPremiumNavbarTabParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/fingerprints/AddPremiumNavbarTabParentFingerprint.kt deleted file mode 100644 index e67bd8f6b..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/fingerprints/AddPremiumNavbarTabParentFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.spotify.premium_navbar_tab.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object AddPremiumNavbarTabParentFingerprint : MethodFingerprint( - strings = listOf("com.samsung.android.samsungaccount.action.REQUEST_AUTHCODE") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/patch/PremiumNavbarTabPatch.kt b/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/patch/PremiumNavbarTabPatch.kt deleted file mode 100644 index e45bb6fbe..000000000 --- a/src/main/kotlin/app/revanced/patches/spotify/premium_navbar_tab/patch/PremiumNavbarTabPatch.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.patches.spotify.premium_navbar_tab.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.spotify.premium_navbar_tab.annotations.PremiumNavbarTabCompatibility -import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabFingerprint -import app.revanced.patches.spotify.premium_navbar_tab.fingerprints.AddPremiumNavbarTabParentFingerprint -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -@Patch -@Name("hide-premium-navbar") -@Description("Removes the premium tab from the navbar.") -@PremiumNavbarTabCompatibility -@Version("0.0.1") -@DependsOn([ResourceMappingPatch::class]) -class PremiumNavbarTabPatch : BytecodePatch( - listOf( - AddPremiumNavbarTabParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val parentResult = AddPremiumNavbarTabParentFingerprint.result!! - AddPremiumNavbarTabFingerprint.resolve(context, parentResult.classDef) - - val result = AddPremiumNavbarTabFingerprint.result!! - - val method = result.mutableMethod - val methodInstructions = method.implementation!!.instructions - val lastInstructionIdx = methodInstructions.size - 1 - - val premiumTabId = - ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "premium_tab" }.id - - var removeAmount = 2 - // 2nd const remove method - for ((i, instruction) in methodInstructions.asReversed().withIndex()) { - if (instruction.opcode.ordinal != Opcode.CONST.ordinal) continue - if ((instruction as WideLiteralInstruction).wideLiteral != premiumTabId) continue - - val findThreshold = 10 - val constIndex = lastInstructionIdx - i - val invokeInstruction = methodInstructions.subList(constIndex, constIndex + findThreshold).first { - it.opcode.ordinal == Opcode.INVOKE_VIRTUAL_RANGE.ordinal - } - method.removeInstruction(methodInstructions.indexOf(invokeInstruction)) - - if (--removeAmount == 0) break - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/annotations/UnlockTrialCompatibility.kt b/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/annotations/UnlockTrialCompatibility.kt deleted file mode 100644 index 3f1c42eae..000000000 --- a/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/annotations/UnlockTrialCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.tasker.trial.unlock.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("net.dinglisch.android.taskerm")]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockTrialCompatibility diff --git a/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/fingerprints/CheckLicenseFingerprint.kt b/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/fingerprints/CheckLicenseFingerprint.kt deleted file mode 100644 index d02ce9261..000000000 --- a/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/fingerprints/CheckLicenseFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.tasker.trial.unlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CheckLicenseFingerprint : MethodFingerprint( - strings = listOf("Can't check license") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/patch/UnlockLicensePatch.kt b/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/patch/UnlockLicensePatch.kt deleted file mode 100644 index 9d644faa0..000000000 --- a/src/main/kotlin/app/revanced/patches/tasker/trial/unlock/patch/UnlockLicensePatch.kt +++ /dev/null @@ -1,32 +0,0 @@ -package app.revanced.patches.tasker.trial.unlock.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.tasker.trial.unlock.annotations.UnlockTrialCompatibility -import app.revanced.patches.tasker.trial.unlock.fingerprints.CheckLicenseFingerprint - -@Patch -@Name("unlock-trial") -@Description("Unlocks the trial version.") -@UnlockTrialCompatibility -@Version("0.0.1") -class UnlockLicensePatch : BytecodePatch( - listOf( - CheckLicenseFingerprint - ) -) { - override fun execute(context: BytecodeContext) = CheckLicenseFingerprint - .result - ?.mutableMethod - // Return the method early, which prompts the user with a non dismissible dialog, when the trial period is over. - ?.addInstruction(0, "return-void") - ?.let { PatchResultSuccess() } - ?: CheckLicenseFingerprint.toErrorResult() -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/annotations/UnlockThemesCompatibility.kt b/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/annotations/UnlockThemesCompatibility.kt deleted file mode 100644 index 3fa4619e6..000000000 --- a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/annotations/UnlockThemesCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.ticktick.misc.themeunlock.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.ticktick.task")]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockThemesCompatibility diff --git a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/fingerprints/CheckLockedThemesFingerprint.kt b/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/fingerprints/CheckLockedThemesFingerprint.kt deleted file mode 100644 index dccab403f..000000000 --- a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/fingerprints/CheckLockedThemesFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.ticktick.misc.themeunlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CheckLockedThemesFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("Theme;") && methodDef.name == "isLockedTheme" - } -) diff --git a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/fingerprints/SetThemeFingerprint.kt b/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/fingerprints/SetThemeFingerprint.kt deleted file mode 100644 index dc22b02c5..000000000 --- a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/fingerprints/SetThemeFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.ticktick.misc.themeunlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SetThemeFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("ThemePreviewActivity;") && methodDef.name == "lambda\$updateUserBtn\$1" - } -) diff --git a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/patch/UnlockThemePatch.kt b/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/patch/UnlockThemePatch.kt deleted file mode 100644 index 8cc8fdd9c..000000000 --- a/src/main/kotlin/app/revanced/patches/ticktick/misc/themeunlock/patch/UnlockThemePatch.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.ticktick.misc.themeunlock.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility -import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.CheckLockedThemesFingerprint -import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.SetThemeFingerprint - -@Patch -@Name("unlock-themes") -@Description("Unlocks all themes that are inaccessible until a certain level is reached.") -@UnlockThemesCompatibility -@Version("0.0.1") -class UnlockProPatch : BytecodePatch( - listOf( - CheckLockedThemesFingerprint, - SetThemeFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val lockedThemesMethod = CheckLockedThemesFingerprint.result!!.mutableMethod - lockedThemesMethod.addInstructions( - 0, - """ - const/4 v0, 0x0 - return v0 - """ - ) - - val setThemeMethod = SetThemeFingerprint.result!!.mutableMethod - setThemeMethod.removeInstructions(0, 9) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/tiktok/ad/annotations/HideAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/ad/annotations/HideAdsCompatibility.kt deleted file mode 100644 index a6c21590f..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/ad/annotations/HideAdsCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.ad.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill"), - Package("com.zhiliaoapp.musically") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/ConvertHelpFeedItemListFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/ConvertHelpFeedItemListFingerprint.kt deleted file mode 100644 index fc252a24c..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/ConvertHelpFeedItemListFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.tiktok.ad.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object ConvertHelpFeedItemListFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/ConvertHelp;") && - methodDef.name.endsWith("${'$'}FeedItemList") - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/FeedItemListCloneFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/FeedItemListCloneFingerprint.kt deleted file mode 100644 index 4f9de5d3a..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/FeedItemListCloneFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.tiktok.ad.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object FeedItemListCloneFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/FeedItemList;") && methodDef.name == "clone" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/ad/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/ad/patch/HideAdsPatch.kt deleted file mode 100644 index 862f80517..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/ad/patch/HideAdsPatch.kt +++ /dev/null @@ -1,57 +0,0 @@ -package app.revanced.patches.tiktok.ad.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.tiktok.ad.annotations.HideAdsCompatibility -import app.revanced.patches.tiktok.ad.fingerprints.ConvertHelpFeedItemListFingerprint -import app.revanced.patches.tiktok.ad.fingerprints.FeedItemListCloneFingerprint -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction -import org.jf.dexlib2.iface.reference.FieldReference - -@Patch -@Name("hide-ads") -@Description("Removes ads from TikTok.") -@HideAdsCompatibility -@Version("0.0.1") -class HideAdsPatch : BytecodePatch( - listOf( - FeedItemListCloneFingerprint, - ConvertHelpFeedItemListFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - listOf( - FeedItemListCloneFingerprint, - ConvertHelpFeedItemListFingerprint - ).forEach { fingerprint -> - val method = fingerprint.result!!.mutableMethod - // iterate all instructions in the clone method - for ((index, instruction) in method.implementation!!.instructions.withIndex()) { - // conditions for the instruction we need - if (instruction.opcode.ordinal != Opcode.IPUT_OBJECT.ordinal) continue - val preloadAdsFieldInstruction = (instruction as? ReferenceInstruction) - if ((preloadAdsFieldInstruction?.reference as? FieldReference)?.name != "preloadAds") continue - - // set null instead of the field "preloadAds" - val overrideRegister = (preloadAdsFieldInstruction as TwoRegisterInstruction).registerA - method.addInstruction( - index, - "const/4 v$overrideRegister, 0x0" - ) - return@forEach - } - return PatchResultError("Can not find required instruction.") - } - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/annotations/FeedFilterCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/annotations/FeedFilterCompatibility.kt deleted file mode 100644 index a4c40c748..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/annotations/FeedFilterCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.feedfilter.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill", arrayOf("27.8.3")), - Package("com.zhiliaoapp.musically", arrayOf("27.8.3")) - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class FeedFilterCompatibility diff --git a/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/fingerprints/FeedApiServiceLIZFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/fingerprints/FeedApiServiceLIZFingerprint.kt deleted file mode 100644 index 667e5abcd..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/fingerprints/FeedApiServiceLIZFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.tiktok.feedfilter.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object FeedApiServiceLIZFingerprint : MethodFingerprint( - access = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.SYNTHETIC, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/FeedApiService;") && methodDef.name == "LIZ" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/patch/FeedFilterPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/patch/FeedFilterPatch.kt deleted file mode 100644 index fb6ba0b32..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/feedfilter/patch/FeedFilterPatch.kt +++ /dev/null @@ -1,51 +0,0 @@ -package app.revanced.patches.tiktok.feedfilter.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.tiktok.feedfilter.annotations.FeedFilterCompatibility -import app.revanced.patches.tiktok.feedfilter.fingerprints.FeedApiServiceLIZFingerprint -import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint -import app.revanced.patches.tiktok.misc.settings.patch.SettingsPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("feed-filter") -@Description("Filters tiktok videos: removing ads, removing livestreams.") -@FeedFilterCompatibility -@Version("0.0.1") -class FeedFilterPatch : BytecodePatch( - listOf( - FeedApiServiceLIZFingerprint, - SettingsStatusLoadFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = FeedApiServiceLIZFingerprint.result!!.mutableMethod - for ((index, instruction) in method.implementation!!.instructions.withIndex()) { - if (instruction.opcode != Opcode.RETURN_OBJECT) continue - val feedItemsRegister = (instruction as OneRegisterInstruction).registerA - method.addInstruction( - index, - "invoke-static {v$feedItemsRegister}, Lapp/revanced/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V" - ) - break - } - val method2 = SettingsStatusLoadFingerprint.result!!.mutableMethod - method2.addInstruction( - 0, - "invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableFeedFilter()V" - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/annotations/DownloadsCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/annotations/DownloadsCompatibility.kt deleted file mode 100644 index a193c100f..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/annotations/DownloadsCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.interaction.downloads.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill", arrayOf("27.8.3")), - Package("com.zhiliaoapp.musically", arrayOf("27.8.3")) - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class DownloadsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint.kt deleted file mode 100644 index f1e851661..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.tiktok.interaction.downloads.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object ACLCommonShareFingerprint : MethodFingerprint( - "I", - AccessFlags.PUBLIC or AccessFlags.FINAL, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/ACLCommonShare;") && - methodDef.name == "getCode" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint2.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint2.kt deleted file mode 100644 index 384530db7..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint2.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.tiktok.interaction.downloads.fingerprints - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.tiktok.interaction.downloads.annotations.DownloadsCompatibility -import org.jf.dexlib2.AccessFlags - -@Name("acl-common-share-get-show-type") -@DownloadsCompatibility -@Version("0.0.1") -object ACLCommonShareFingerprint2 : MethodFingerprint( - "I", - AccessFlags.PUBLIC or AccessFlags.FINAL, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/ACLCommonShare;") && - methodDef.name == "getShowType" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint3.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint3.kt deleted file mode 100644 index cf585dd21..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/ACLCommonShareFingerprint3.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.tiktok.interaction.downloads.fingerprints - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.tiktok.interaction.downloads.annotations.DownloadsCompatibility -import org.jf.dexlib2.AccessFlags - -@Name("acl-common-share-get-transcode") -@DownloadsCompatibility -@Version("0.0.1") -object ACLCommonShareFingerprint3 : MethodFingerprint( - "I", - AccessFlags.PUBLIC or AccessFlags.FINAL, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/ACLCommonShare;") && - methodDef.name == "getTranscode" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/DownloadPathParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/DownloadPathParentFingerprint.kt deleted file mode 100644 index 8daff09e4..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/fingerprints/DownloadPathParentFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.tiktok.interaction.downloads.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object DownloadPathParentFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - strings = listOf( - "code", - "reason", - "params insufficient" - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/patch/DownloadsPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/patch/DownloadsPatch.kt deleted file mode 100644 index a3ea7572f..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/downloads/patch/DownloadsPatch.kt +++ /dev/null @@ -1,131 +0,0 @@ -package app.revanced.patches.tiktok.interaction.downloads.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.extensions.replaceInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.tiktok.interaction.downloads.annotations.DownloadsCompatibility -import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint -import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint2 -import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint3 -import app.revanced.patches.tiktok.interaction.downloads.fingerprints.DownloadPathParentFingerprint -import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint -import app.revanced.patches.tiktok.misc.settings.patch.SettingsPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.StringReference - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("downloads") -@Description("Removes download restrictions and changes the default path to download to.") -@DownloadsCompatibility -@Version("0.0.1") -class DownloadsPatch : BytecodePatch( - listOf( - ACLCommonShareFingerprint, - ACLCommonShareFingerprint2, - ACLCommonShareFingerprint3, - DownloadPathParentFingerprint, - SettingsStatusLoadFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method1 = ACLCommonShareFingerprint.result!!.mutableMethod - method1.replaceInstructions( - 0, - """ - const/4 v0, 0x0 - return v0 - """ - ) - val method2 = ACLCommonShareFingerprint2.result!!.mutableMethod - method2.replaceInstructions( - 0, - """ - const/4 v0, 0x2 - return v0 - """ - ) - //Download videos without watermark. - val method3 = ACLCommonShareFingerprint3.result!!.mutableMethod - method3.addInstructions( - 0, - """ - invoke-static {}, Lapp/revanced/tiktok/download/DownloadsPatch;->shouldRemoveWatermark()Z - move-result v0 - if-eqz v0, :noremovewatermark - const/4 v0, 0x1 - return v0 - :noremovewatermark - nop - """ - ) - //Change the download path patch - val method4 = DownloadPathParentFingerprint.result!!.mutableMethod - val implementation4 = method4.implementation - val instructions = implementation4!!.instructions - var targetOffset = -1 - //Search for the target method called instruction offset. - for ((index, instruction) in instructions.withIndex()) { - if (instruction.opcode != Opcode.CONST_STRING) continue - val reference = (instruction as ReferenceInstruction).reference as StringReference - if (reference.string != "video/mp4") continue - val targetInstruction = instructions[index + 1] - if (targetInstruction.opcode != Opcode.INVOKE_STATIC) continue - targetOffset = index + 1 - break - } - if (targetOffset == -1) return PatchResultError("Can not find download path uri method.") - //Change videos' download path. - val downloadUriMethod = context - .toMethodWalker(DownloadPathParentFingerprint.result!!.method) - .nextMethod(targetOffset, true) - .getMethod() as MutableMethod - downloadUriMethod.implementation!!.instructions.forEachIndexed { index, instruction -> - if (instruction.opcode == Opcode.SGET_OBJECT) { - val overrideRegister = (instruction as OneRegisterInstruction).registerA - downloadUriMethod.addInstructions( - index + 1, - """ - invoke-static {}, Lapp/revanced/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String; - move-result-object v$overrideRegister - """ - ) - } - if (instruction.opcode == Opcode.CONST_STRING) { - val string = ((instruction as ReferenceInstruction).reference as StringReference).string - if (string.contains("/Camera")) { - val overrideRegister = (instruction as OneRegisterInstruction).registerA - val overrideString = string.replace("/Camera", "") - downloadUriMethod.replaceInstruction( - index, - """ - const-string v$overrideRegister, "$overrideString" - """ - ) - } - } - } - val method5 = SettingsStatusLoadFingerprint.result!!.mutableMethod - method5.addInstruction( - 0, - "invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableDownload()V" - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/annotations/ShowSeekbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/annotations/ShowSeekbarCompatibility.kt deleted file mode 100644 index 3326e9f2a..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/annotations/ShowSeekbarCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.interaction.seekbar.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill"), - Package("com.zhiliaoapp.musically") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class ShowSeekbarCompatibility diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/fingerprints/AwemeGetVideoControlFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/fingerprints/AwemeGetVideoControlFingerprint.kt deleted file mode 100644 index fb6463186..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/fingerprints/AwemeGetVideoControlFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.tiktok.interaction.seekbar.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object AwemeGetVideoControlFingerprint : MethodFingerprint( - "L", - AccessFlags.PUBLIC.value, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/Aweme;") && methodDef.name == "getVideoControl" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/patch/ShowSeekbarPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/patch/ShowSeekbarPatch.kt deleted file mode 100644 index 31d6d1289..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/seekbar/patch/ShowSeekbarPatch.kt +++ /dev/null @@ -1,52 +0,0 @@ -package app.revanced.patches.tiktok.interaction.seekbar.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.tiktok.interaction.seekbar.annotations.ShowSeekbarCompatibility -import app.revanced.patches.tiktok.interaction.seekbar.fingerprints.AwemeGetVideoControlFingerprint -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction11n -import org.jf.dexlib2.builder.instruction.BuilderInstruction21t -import org.jf.dexlib2.builder.instruction.BuilderInstruction22c - -@Patch -@Name("show-seekbar") -@Description("Shows progress bar for all video.") -@ShowSeekbarCompatibility -@Version("0.0.1") -class ShowSeekbarPatch : BytecodePatch( - listOf( - AwemeGetVideoControlFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - //Get VideoControl FieldReference - val videoControl = context.findClass { it.type.endsWith("/VideoControl;") } - ?: return PatchResultError("Can not find target class") - val fieldList = videoControl.immutableClass.fields.associateBy { field -> field.name } - - AwemeGetVideoControlFingerprint.result?.mutableMethod?.implementation?.apply { - val ifNullLabel = newLabelForIndex(1) - addInstructions( - 1, - listOf( - BuilderInstruction11n(Opcode.CONST_4, 1, 1), - BuilderInstruction21t(Opcode.IF_EQZ, 0, ifNullLabel), - BuilderInstruction22c(Opcode.IPUT, 1, 0, fieldList["showProgressBar"]!!), - BuilderInstruction22c(Opcode.IPUT, 1, 0, fieldList["draftProgressBar"]!!) - ) - ) - } ?: return AwemeGetVideoControlFingerprint.toErrorResult() - return PatchResultSuccess() - } - -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/annotations/PlaybackSpeedCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/annotations/PlaybackSpeedCompatibility.kt deleted file mode 100644 index fbb92e8b1..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/annotations/PlaybackSpeedCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.interaction.speed.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill"), - Package("com.zhiliaoapp.musically") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class PlaybackSpeedCompatibility diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SpeedControlParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SpeedControlParentFingerprint.kt deleted file mode 100644 index 4e70ca812..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/fingerprints/SpeedControlParentFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.tiktok.interaction.speed.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object SpeedControlParentFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PRIVATE or AccessFlags.FINAL, - parameters = listOf( - "L" - ), - strings = listOf( - "playback_speed" - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/patch/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/patch/PlaybackSpeedPatch.kt deleted file mode 100644 index c1f15a75d..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/interaction/speed/patch/PlaybackSpeedPatch.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.tiktok.interaction.speed.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.tiktok.interaction.speed.annotations.PlaybackSpeedCompatibility -import app.revanced.patches.tiktok.interaction.speed.fingerprints.SpeedControlParentFingerprint -import org.jf.dexlib2.Opcode - -@Patch -@Name("playback-speed") -@Description("Enables the playback speed option for all videos.") -@PlaybackSpeedCompatibility -@Version("0.0.1") -class PlaybackSpeedPatch : BytecodePatch( - listOf( - SpeedControlParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val parentMethod = SpeedControlParentFingerprint.result!!.mutableMethod - val parentMethodInstructions = parentMethod.implementation!!.instructions - for ((index, instruction) in parentMethodInstructions.withIndex()) { - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) continue - val isSpeedEnableMethod = context - .toMethodWalker(parentMethod) - .nextMethod(index, true) - .getMethod() as MutableMethod - isSpeedEnableMethod.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - break - } - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/annotations/IntegrationsCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/annotations/IntegrationsCompatibility.kt deleted file mode 100644 index 4ece97d66..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/annotations/IntegrationsCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.misc.integrations.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill"), - Package("com.zhiliaoapp.musically") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class IntegrationsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/fingerprints/InitFingerprint.kt deleted file mode 100644 index 9afc4eccf..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/fingerprints/InitFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.tiktok.misc.integrations.fingerprints - -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint - -object InitFingerprint : IntegrationsFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/AwemeHostApplication;") && - methodDef.name == "onCreate" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/patch/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/patch/IntegrationsPatch.kt deleted file mode 100644 index b7b182b6c..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/patch/IntegrationsPatch.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.tiktok.misc.integrations.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.patch.annotations.RequiresIntegrations -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch -import app.revanced.patches.tiktok.misc.integrations.annotations.IntegrationsCompatibility -import app.revanced.patches.tiktok.misc.integrations.fingerprints.InitFingerprint - -@Name("integrations") -@IntegrationsCompatibility -@RequiresIntegrations -class IntegrationsPatch : AbstractIntegrationsPatch( - "Lapp/revanced/tiktok/utils/ReVancedUtils;", - listOf(InitFingerprint) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/annotations/DisableLoginRequirementCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/annotations/DisableLoginRequirementCompatibility.kt deleted file mode 100644 index faaaa0744..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/annotations/DisableLoginRequirementCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.disablerequirement.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill"), - Package("com.zhiliaoapp.musically") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class DisableLoginRequirementCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/fingerprints/MandatoryLoginServiceFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/fingerprints/MandatoryLoginServiceFingerprint.kt deleted file mode 100644 index 842dcae2d..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/fingerprints/MandatoryLoginServiceFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.disablerequirement.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -object MandatoryLoginServiceFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/MandatoryLoginService;") && - methodDef.name == "enableForcedLogin" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/fingerprints/MandatoryLoginServiceFingerprint2.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/fingerprints/MandatoryLoginServiceFingerprint2.kt deleted file mode 100644 index 59015a6b6..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/fingerprints/MandatoryLoginServiceFingerprint2.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.disablerequirement.fingerprints - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.tiktok.misc.login.disablerequirement.annotations.DisableLoginRequirementCompatibility - -@Name("mandatory-login-service-fingerprint2") -@DisableLoginRequirementCompatibility -@Version("0.0.1") -object MandatoryLoginServiceFingerprint2 : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/MandatoryLoginService;") && - methodDef.name == "shouldShowForcedLogin" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/patch/DisableLoginRequirementPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/patch/DisableLoginRequirementPatch.kt deleted file mode 100644 index 0967f7269..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/patch/DisableLoginRequirementPatch.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.disablerequirement.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.tiktok.misc.login.disablerequirement.annotations.DisableLoginRequirementCompatibility -import app.revanced.patches.tiktok.misc.login.disablerequirement.fingerprints.MandatoryLoginServiceFingerprint -import app.revanced.patches.tiktok.misc.login.disablerequirement.fingerprints.MandatoryLoginServiceFingerprint2 - -@Patch -@Name("disable-login-requirement") -@Description("Do not force login.") -@DisableLoginRequirementCompatibility -@Version("0.0.1") -class DisableLoginRequirementPatch : BytecodePatch( - listOf( - MandatoryLoginServiceFingerprint, - MandatoryLoginServiceFingerprint2 - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - listOf( - MandatoryLoginServiceFingerprint, - MandatoryLoginServiceFingerprint2 - ).forEach { fingerprint -> - val method = fingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/4 v0, 0x0 - return v0 - """ - ) - } - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/annotations/FixGoogleLoginCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/annotations/FixGoogleLoginCompatibility.kt deleted file mode 100644 index 62d7e5795..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/annotations/FixGoogleLoginCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.fixgoogle.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill"), - Package("com.zhiliaoapp.musically") - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class FixGoogleLoginCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/fingerprints/GoogleAuthAvailableFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/fingerprints/GoogleAuthAvailableFingerprint.kt deleted file mode 100644 index 2e1a1eaf1..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/fingerprints/GoogleAuthAvailableFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.fixgoogle.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object GoogleAuthAvailableFingerprint : MethodFingerprint( - returnType = "Z", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf(), - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/bytedance/lobby/google/GoogleAuth;" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/fingerprints/GoogleOneTapAuthAvailableFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/fingerprints/GoogleOneTapAuthAvailableFingerprint.kt deleted file mode 100644 index 26e51a522..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/fingerprints/GoogleOneTapAuthAvailableFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.fixgoogle.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object GoogleOneTapAuthAvailableFingerprint : MethodFingerprint( - returnType = "Z", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf(), - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/bytedance/lobby/google/GoogleOneTapAuth;" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/patch/FixGoogleLoginPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/patch/FixGoogleLoginPatch.kt deleted file mode 100644 index 9e27025c7..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/login/fixgoogle/patch/FixGoogleLoginPatch.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.tiktok.misc.login.fixgoogle.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.tiktok.misc.login.fixgoogle.annotations.FixGoogleLoginCompatibility -import app.revanced.patches.tiktok.misc.login.fixgoogle.fingerprints.GoogleAuthAvailableFingerprint -import app.revanced.patches.tiktok.misc.login.fixgoogle.fingerprints.GoogleOneTapAuthAvailableFingerprint - -@Patch -@Name("fix-google-login") -@Description("Allows logging in with a Google account.") -@FixGoogleLoginCompatibility -@Version("0.0.1") -class FixGoogleLoginPatch : BytecodePatch( - listOf( - GoogleOneTapAuthAvailableFingerprint, - GoogleAuthAvailableFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - listOf( - GoogleOneTapAuthAvailableFingerprint, - GoogleAuthAvailableFingerprint - ).forEach { - with(it.result!!.mutableMethod) { - addInstructions( - 0, - """ - const/4 v0, 0x0 - return v0 - """ - ) - } - } - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/annotations/SettingsCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/annotations/SettingsCompatibility.kt deleted file mode 100644 index cb994126b..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/annotations/SettingsCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.misc.settings.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill", arrayOf("27.8.3")), - Package("com.zhiliaoapp.musically", arrayOf("27.8.3")) - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class SettingsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/AboutViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/AboutViewFingerprint.kt deleted file mode 100644 index e4b680c31..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/AboutViewFingerprint.kt +++ /dev/null @@ -1,37 +0,0 @@ -package app.revanced.patches.tiktok.misc.settings.fingerprints - -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -@FuzzyPatternScanMethod(4) -object AboutViewFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.NEW_INSTANCE, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.CONST_4, - Opcode.CONST_STRING, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.CONST - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/AdPersonalizationActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/AdPersonalizationActivityOnCreateFingerprint.kt deleted file mode 100644 index 69778a650..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/AdPersonalizationActivityOnCreateFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.tiktok.misc.settings.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object AdPersonalizationActivityOnCreateFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/AdPersonalizationActivity;") && - methodDef.name == "onCreate" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/SettingsOnViewCreatedFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/SettingsOnViewCreatedFingerprint.kt deleted file mode 100644 index 46f2ba697..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/SettingsOnViewCreatedFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.tiktok.misc.settings.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SettingsOnViewCreatedFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/SettingNewVersionFragment;") && - methodDef.name == "onViewCreated" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/SettingsStatusLoadFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/SettingsStatusLoadFingerprint.kt deleted file mode 100644 index c2f1d3c51..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/fingerprints/SettingsStatusLoadFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.tiktok.misc.settings.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SettingsStatusLoadFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("Lapp/revanced/tiktok/settingsmenu/SettingsStatus;") && - methodDef.name == "load" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/patch/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/patch/SettingsPatch.kt deleted file mode 100644 index 0fcd0943d..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/patch/SettingsPatch.kt +++ /dev/null @@ -1,120 +0,0 @@ -package app.revanced.patches.tiktok.misc.settings.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.tiktok.misc.settings.annotations.SettingsCompatibility -import app.revanced.patches.tiktok.misc.settings.fingerprints.AboutViewFingerprint -import app.revanced.patches.tiktok.misc.settings.fingerprints.AdPersonalizationActivityOnCreateFingerprint -import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsOnViewCreatedFingerprint -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.instruction.formats.Instruction35c -import org.jf.dexlib2.iface.reference.StringReference -import org.jf.dexlib2.iface.reference.TypeReference - -@Patch -@DependsOn([IntegrationsPatch::class]) -@Name("settings") -@Description("Adds ReVanced settings to TikTok.") -@SettingsCompatibility -@Version("0.0.1") -class SettingsPatch : BytecodePatch( - listOf( - AdPersonalizationActivityOnCreateFingerprint, - SettingsOnViewCreatedFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsOnViewCreatedFingerprint.result?.let { - AboutViewFingerprint.resolve(context, it.method, it.classDef) - } - // Patch Settings UI to add 'Revanced Settings'. - val targetIndexes = findOptionsOnClickIndex() - with(SettingsOnViewCreatedFingerprint.result!!.mutableMethod) { - for (index in targetIndexes) { - if ( - instruction(index).opcode != Opcode.NEW_INSTANCE || - instruction(index - 4).opcode != Opcode.MOVE_RESULT_OBJECT - ) - return PatchResultError("Hardcode offset changed.") - patchOptionNameAndOnClickEvent(index, context) - } - } - // Implement settings screen in `AdPersonalizationActivity` - with(AdPersonalizationActivityOnCreateFingerprint.result!!.mutableMethod) { - for ((index, instruction) in implementation!!.instructions.withIndex()) { - if (instruction.opcode != Opcode.INVOKE_SUPER) continue - val thisRegister = (instruction as Instruction35c).registerC - addInstructions( - index + 1, - """ - invoke-static {v$thisRegister}, Lapp/revanced/tiktok/settingsmenu/SettingsMenu;->initializeSettings(Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;)V - return-void - """ - ) - break - } - } - return PatchResultSuccess() - } - - private fun findOptionsOnClickIndex(): IntArray { - val results = IntArray(2) - SettingsOnViewCreatedFingerprint.result?.apply { - for ((index, instruction) in mutableMethod.implementation!!.instructions.withIndex()) { - // Old UI settings option to replace to 'Revanced Settings' - if (instruction.opcode == Opcode.CONST_STRING) { - val string = ((instruction as ReferenceInstruction).reference as StringReference).string - if (string == "copyright_policy") { - results[0] = index - 2 - break - } - } - } - - // New UI settings option to replace to 'Revanced Settings' - results[1] = AboutViewFingerprint.result!!.scanResult.patternScanResult!!.startIndex - } ?: throw SettingsOnViewCreatedFingerprint.toErrorResult() - return results - } - - private fun patchOptionNameAndOnClickEvent(index: Int, context: BytecodeContext) { - with(SettingsOnViewCreatedFingerprint.result!!.mutableMethod) { - // Patch option name - val overrideRegister = (instruction(index - 4) as OneRegisterInstruction).registerA - replaceInstruction( - index - 4, - """ - const-string v$overrideRegister, "Revanced Settings" - """ - ) - - // Patch option OnClick Event - with(((instruction(index) as ReferenceInstruction).reference as TypeReference).type) { - context.findClass(this)!!.mutableClass.methods.first { it.name == "onClick" } - .addInstructions( - 0, - """ - invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsMenu;->startSettingsActivity()V - return-void - """ - ) - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/annotations/SpoofSimCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/annotations/SpoofSimCompatibility.kt deleted file mode 100644 index 97b091e61..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/annotations/SpoofSimCompatibility.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.tiktok.misc.spoof.sim.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package("com.ss.android.ugc.trill", arrayOf("27.8.3")), - Package("com.zhiliaoapp.musically", arrayOf("27.8.3")) - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class SpoofSimCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/patch/SpoofSimPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/patch/SpoofSimPatch.kt deleted file mode 100644 index 822a2e2fb..000000000 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/spoof/sim/patch/SpoofSimPatch.kt +++ /dev/null @@ -1,110 +0,0 @@ -package app.revanced.patches.tiktok.misc.spoof.sim.patch - -import app.revanced.extensions.findMutableMethodOf -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint -import app.revanced.patches.tiktok.misc.settings.patch.SettingsPatch -import app.revanced.patches.tiktok.misc.spoof.sim.annotations.SpoofSimCompatibility -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.formats.Instruction35c -import org.jf.dexlib2.iface.reference.MethodReference - -@Patch(false) -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("sim-spoof") -@Description("Spoofs the information which is retrieved from the sim-card.") -@SpoofSimCompatibility -@Version("0.0.1") -class SpoofSimPatch : BytecodePatch() { - private companion object { - val replacements = hashMapOf( - "getSimCountryIso" to "getCountryIso", - "getNetworkCountryIso" to "getCountryIso", - "getSimOperator" to "getOperator", - "getNetworkOperator" to "getOperator", - "getSimOperatorName" to "getOperatorName", - "getNetworkOperatorName" to "getOperatorName" - ) - } - - override fun execute(context: BytecodeContext): PatchResult { - // Find all api call to check sim information - buildMap { - context.classes.forEach { classDef -> - classDef.methods.let { methods -> - buildMap methodList@{ - methods.forEach methods@{ method -> - with(method.implementation?.instructions ?: return@methods) { - ArrayDeque>().also { patchIndices -> - this.forEachIndexed { index, instruction -> - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed - - val methodRef = - (instruction as Instruction35c).reference as MethodReference - if (methodRef.definingClass != "Landroid/telephony/TelephonyManager;") return@forEachIndexed - - replacements[methodRef.name]?.let { replacement -> - patchIndices.add(index to replacement) - } - } - }.also { if (it.isEmpty()) return@methods }.let { patches -> - put(method, patches) - } - } - } - } - }.also { if (it.isEmpty()) return@forEach }.let { methodPatches -> - put(classDef, methodPatches) - } - } - }.forEach { (classDef, methods) -> - with(context.proxy(classDef).mutableClass) { - methods.forEach { (method, patches) -> - with(findMutableMethodOf(method)) { - while (!patches.isEmpty()) { - val (index, replacement) = patches.removeLast() - replaceReference(index, replacement) - } - } - } - } - } - - // Enable patch in settings - with(SettingsStatusLoadFingerprint.result!!.mutableMethod) { - addInstruction( - 0, - "invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableSimSpoof()V" - ) - } - - return PatchResultSuccess() - } - - // Patch Android API and return fake sim information - private fun MutableMethod.replaceReference(index: Int, replacement: String) { - val resultReg = (instruction(index + 1) as OneRegisterInstruction).registerA - - addInstructions( - index + 2, - """ - invoke-static {v$resultReg}, Lapp/revanced/tiktok/spoof/sim/SpoofSimPatch;->$replacement(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$resultReg - """ - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/AgendaDaysWidgetUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/AgendaDaysWidgetUnlockFingerprint.kt deleted file mode 100644 index 33277fe7f..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/AgendaDaysWidgetUnlockFingerprint.kt +++ /dev/null @@ -1,5 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object AgendaDaysWidgetUnlockFingerprint : MethodUnlockFingerprint("AgendaDaysWidgetConfigureActivity") diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarBigWidgetUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarBigWidgetUnlockFingerprint.kt deleted file mode 100644 index 4245820d6..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarBigWidgetUnlockFingerprint.kt +++ /dev/null @@ -1,5 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CalendarBigWidgetUnlockFingerprint : MethodUnlockFingerprint("CalendarBigWidgetConfigureActivity") diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarWideDayEventsWidgetUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarWideDayEventsWidgetUnlockFingerprint.kt deleted file mode 100644 index adf3b82a8..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarWideDayEventsWidgetUnlockFingerprint.kt +++ /dev/null @@ -1,4 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.fingerprints - -object CalendarWideDayEventsWidgetUnlockFingerprint : - MethodUnlockFingerprint("CalendarWideDayEventsWidgetConfigureActivity") diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarWideTimelineWidgetUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarWideTimelineWidgetUnlockFingerprint.kt deleted file mode 100644 index 3b7bb2ed1..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/CalendarWideTimelineWidgetUnlockFingerprint.kt +++ /dev/null @@ -1,6 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CalendarWideTimelineWidgetUnlockFingerprint : - MethodUnlockFingerprint("CalendarWideTimelineWidgetConfigureActivity") diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/MethodUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/MethodUnlockFingerprint.kt deleted file mode 100644 index c85e6c92e..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/MethodUnlockFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -abstract class MethodUnlockFingerprint(private val className: String) : MethodFingerprint( - "L", - strings = listOf("binding.addButton"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/$className;") - } -) - diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/ScreentimeSmallWidgetUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/ScreentimeSmallWidgetUnlockFingerprint.kt deleted file mode 100644 index f2c0252de..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/ScreentimeSmallWidgetUnlockFingerprint.kt +++ /dev/null @@ -1,5 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object ScreentimeSmallWidgetUnlockFingerprint : MethodUnlockFingerprint("ScreentimeSmallWidgetConfigureActivity") diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/WeatherWidgetUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/WeatherWidgetUnlockFingerprint.kt deleted file mode 100644 index 17bd9e951..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/fingerprints/WeatherWidgetUnlockFingerprint.kt +++ /dev/null @@ -1,3 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.fingerprints - -object WeatherWidgetUnlockFingerprint : MethodUnlockFingerprint("WeatherWidgetConfigureActivity") diff --git a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/patch/UnlockPaidWidgetsPatch.kt b/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/patch/UnlockPaidWidgetsPatch.kt deleted file mode 100644 index 8a188600f..000000000 --- a/src/main/kotlin/app/revanced/patches/twelvewidgets/unlock/patch/UnlockPaidWidgetsPatch.kt +++ /dev/null @@ -1,54 +0,0 @@ -package app.revanced.patches.twelvewidgets.unlock.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.* -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.twelvewidgets.unlock.fingerprints.* - -@Patch -@Name("unlock-paid-widgets") -@Description("Unlocks paid widgets of the app") -@Compatibility([Package("com.dci.dev.androidtwelvewidgets")]) -@Version("0.0.1") -class UnlockPaidWidgetsPatch : BytecodePatch( - listOf( - AgendaDaysWidgetUnlockFingerprint, - CalendarBigWidgetUnlockFingerprint, - CalendarWideDayEventsWidgetUnlockFingerprint, - CalendarWideTimelineWidgetUnlockFingerprint, - ScreentimeSmallWidgetUnlockFingerprint, - WeatherWidgetUnlockFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - listOf( - AgendaDaysWidgetUnlockFingerprint, - CalendarBigWidgetUnlockFingerprint, - CalendarWideDayEventsWidgetUnlockFingerprint, - CalendarWideTimelineWidgetUnlockFingerprint, - ScreentimeSmallWidgetUnlockFingerprint, - WeatherWidgetUnlockFingerprint - ).map { fingerprint -> - fingerprint.result?.mutableMethod ?: return fingerprint.toErrorResult() - }.forEach { method -> - method.apply { - removeInstructions(4, 2) - addInstructions( - implementation?.instructions?.size!!, """ - const/4 v1, 0x0 - invoke-virtual {v0, v1}, Landroid/view/View;->setVisibility(I)V - return-object v0 - """ - ) - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/audio/annotations/AudioAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/audio/annotations/AudioAdsCompatibility.kt deleted file mode 100644 index 042c4c1d5..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/audio/annotations/AudioAdsCompatibility.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.twitch.ad.audio.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package( - "tv.twitch.android.app", arrayOf( - "14.3.3", - "14.4.0", - "14.5.0", - "14.5.2", - "14.6.0", - "14.6.1" - ) - ) - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class AudioAdsCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/audio/fingerprints/AudioAdsPresenterPlayFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/audio/fingerprints/AudioAdsPresenterPlayFingerprint.kt deleted file mode 100644 index 56bdf6286..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/audio/fingerprints/AudioAdsPresenterPlayFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.ad.audio.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object AudioAdsPresenterPlayFingerprint : MethodFingerprint( - customFingerprint = { method -> - method.definingClass.endsWith("AudioAdsPlayerPresenter;") && method.name == "playAd" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/audio/patch/AudioAdsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/audio/patch/AudioAdsPatch.kt deleted file mode 100644 index a5cccb1c7..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/audio/patch/AudioAdsPatch.kt +++ /dev/null @@ -1,67 +0,0 @@ -package app.revanced.patches.twitch.ad.audio.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.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.twitch.ad.audio.annotations.AudioAdsCompatibility -import app.revanced.patches.twitch.ad.audio.fingerprints.AudioAdsPresenterPlayFingerprint -import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("block-audio-ads") -@Description("Blocks audio ads in streams and VODs.") -@AudioAdsCompatibility -@Version("0.0.1") -class AudioAdsPatch : BytecodePatch( - listOf(AudioAdsPresenterPlayFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - // Block playAds call - with(AudioAdsPresenterPlayFingerprint.result!!) { - mutableMethod.addInstructions( - 0, - """ - invoke-static { }, Lapp/revanced/twitch/patches/AudioAdsPatch;->shouldBlockAudioAds()Z - move-result v0 - if-eqz v0, :show_audio_ads - return-void - """, - listOf(ExternalLabel("show_audio_ads", mutableMethod.instruction(0))) - ) - } - - SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences( - SwitchPreference( - "revanced_block_audio_ads", - StringResource( - "revanced_block_audio_ads", - "Block audio ads" - ), - true, - StringResource( - "revanced_block_audio_ads_on", - "Audio ads are blocked" - ), - StringResource( - "revanced_block_audio_ads_off", - "Audio ads are unblocked" - ), - ) - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/annotations/EmbeddedAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/annotations/EmbeddedAdsCompatibility.kt deleted file mode 100644 index 6f86e6411..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/annotations/EmbeddedAdsCompatibility.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.twitch.ad.embedded.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package( - "tv.twitch.android.app", arrayOf( - "14.3.3", - "14.4.0", - "14.5.0", - "14.5.2", - "14.6.0", - "14.6.1" - ) - ) - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class EmbeddedAdsCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/fingerprints/CreateUsherClientFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/fingerprints/CreateUsherClientFingerprint.kt deleted file mode 100644 index 348044040..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/fingerprints/CreateUsherClientFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.twitch.ad.embedded.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CreateUsherClientFingerprint : MethodFingerprint( - customFingerprint = { method -> - method.definingClass.endsWith("Ltv/twitch/android/network/OkHttpClientFactory;") && method.name == "buildOkHttpClient" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/patch/EmbeddedAdsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/patch/EmbeddedAdsPatch.kt deleted file mode 100644 index 5384546a4..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/patch/EmbeddedAdsPatch.kt +++ /dev/null @@ -1,78 +0,0 @@ -package app.revanced.patches.twitch.ad.embedded.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.ListPreference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.twitch.ad.embedded.annotations.EmbeddedAdsCompatibility -import app.revanced.patches.twitch.ad.embedded.fingerprints.CreateUsherClientFingerprint -import app.revanced.patches.twitch.ad.video.patch.VideoAdsPatch -import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([VideoAdsPatch::class, IntegrationsPatch::class, SettingsPatch::class]) -@Name("block-embedded-ads") -@Description("Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.") -@EmbeddedAdsCompatibility -@Version("0.0.1") -class EmbeddedAdsPatch : BytecodePatch( - listOf(CreateUsherClientFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = CreateUsherClientFingerprint.result ?: return PatchResultError("${CreateUsherClientFingerprint.name} not found") - - // Inject OkHttp3 application interceptor - result.mutableMethod.addInstructions( - 3, - """ - invoke-static {}, Lapp/revanced/twitch/patches/EmbeddedAdsPatch;->createRequestInterceptor()Lapp/revanced/twitch/api/RequestInterceptor; - move-result-object v2 - invoke-virtual {v0, v2}, Lokhttp3/OkHttpClient${"$"}Builder;->addInterceptor(Lokhttp3/Interceptor;)Lokhttp3/OkHttpClient${"$"}Builder; - """ - ) - - SettingsPatch.PreferenceScreen.ADS.SURESTREAM.addPreferences( - ListPreference( - "revanced_block_embedded_ads", - StringResource( - "revanced_block_embedded_ads", - "Block embedded video ads" - ), - ArrayResource( - "revanced_hls_proxies", - listOf( - StringResource("revanced_proxy_disabled", "Disabled"), - StringResource("revanced_proxy_ttv_lol", "TTV LOL proxy"), - StringResource("revanced_proxy_purpleadblock", "PurpleAdBlock proxy"), - ) - ), - ArrayResource( - "revanced_hls_proxies_values", - listOf( - StringResource("key_revanced_proxy_disabled", "disabled"), - StringResource("key_revanced_proxy_ttv_lol", "ttv-lol"), - StringResource("key_revanced_proxy_purpleadblock", "purpleadblock") - ) - ), - "ttv-lol" - ) - ) - - SettingsPatch.addString("revanced_embedded_ads_service_unavailable", "%s is unavailable. Ads may show. Try switching to another ad block service in settings.") - SettingsPatch.addString("revanced_embedded_ads_service_failed", "%s server returned an error. Ads may show. Try switching to another ad block service in settings.") - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AbstractAdPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AbstractAdPatch.kt deleted file mode 100644 index dca265bc7..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AbstractAdPatch.kt +++ /dev/null @@ -1,51 +0,0 @@ -package app.revanced.patches.twitch.ad.shared.util - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.util.smali.ExternalLabel - -abstract class AbstractAdPatch( - val conditionCall: String, - val skipLabelName: String, - internal val fingerprints: Iterable? = null, -) : BytecodePatch(fingerprints) { - - protected fun createConditionInstructions(register: String = "v0") = """ - invoke-static { }, $conditionCall - move-result $register - if-eqz $register, :$skipLabelName - """ - - protected data class ReturnMethod(val returnType: Char = 'V', val value: String = "") - - protected fun BytecodeContext.blockMethods(clazz: String, vararg methodNames: String, returnMethod: ReturnMethod = ReturnMethod()): Boolean { - - return with(findClass(clazz)?.mutableClass) { - this ?: return false - - this.methods.filter { methodNames.contains(it.name) }.forEach { - val retIntructions = when(returnMethod.returnType) { - 'V' -> "return-void" - 'Z' -> """ - const/4 v0, ${returnMethod.value} - return v0 - """ - else -> throw NotImplementedError() - } - it.addInstructions( - 0, - """ - ${createConditionInstructions("v0")} - $retIntructions - """, - listOf(ExternalLabel(skipLabelName, it.instruction(0))) - ) - } - true - } - } - -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/video/annotations/VideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/video/annotations/VideoAdsCompatibility.kt deleted file mode 100644 index 8bda487db..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/video/annotations/VideoAdsCompatibility.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.twitch.ad.video.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [ - Package( - "tv.twitch.android.app", arrayOf( - "14.3.3", - "14.4.0", - "14.5.0", - "14.5.2", - "14.6.0", - "14.6.1" - ) - ) - ] -) -@Target(AnnotationTarget.CLASS) -internal annotation class VideoAdsCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/CheckAdEligibilityLambdaFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/CheckAdEligibilityLambdaFingerprint.kt deleted file mode 100644 index 04c1c09b1..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/CheckAdEligibilityLambdaFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.twitch.ad.video.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object CheckAdEligibilityLambdaFingerprint : MethodFingerprint( - "L", - AccessFlags.PRIVATE or AccessFlags.FINAL or AccessFlags.STATIC, - listOf("L", "L", "L"), - customFingerprint = { method -> - method.definingClass.endsWith("AdEligibilityFetcher;") && - method.name.contains("shouldRequestAd") - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/ContentConfigShowAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/ContentConfigShowAdsFingerprint.kt deleted file mode 100644 index ed38035eb..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/ContentConfigShowAdsFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.ad.video.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object ContentConfigShowAdsFingerprint : MethodFingerprint( - customFingerprint = { method -> - method.definingClass.endsWith("ContentConfigData;") && method.name == "getShowAds" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/GetReadyToShowAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/GetReadyToShowAdFingerprint.kt deleted file mode 100644 index 3256ad024..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/video/fingerprints/GetReadyToShowAdFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.twitch.ad.video.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object GetReadyToShowAdFingerprint : MethodFingerprint( - customFingerprint = { method -> - method.definingClass.endsWith("/StreamDisplayAdsPresenter;") && method.name == "getReadyToShowAdOrAbort" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/ad/video/patch/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/ad/video/patch/VideoAdsPatch.kt deleted file mode 100644 index 9b1197e78..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/ad/video/patch/VideoAdsPatch.kt +++ /dev/null @@ -1,149 +0,0 @@ -package app.revanced.patches.twitch.ad.video.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.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.twitch.ad.shared.util.AbstractAdPatch -import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility -import app.revanced.patches.twitch.ad.video.fingerprints.CheckAdEligibilityLambdaFingerprint -import app.revanced.patches.twitch.ad.video.fingerprints.ContentConfigShowAdsFingerprint -import app.revanced.patches.twitch.ad.video.fingerprints.GetReadyToShowAdFingerprint -import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("block-video-ads") -@Description("Blocks video ads in streams and VODs.") -@VideoAdsCompatibility -@Version("0.0.1") -class VideoAdsPatch : AbstractAdPatch( - "Lapp/revanced/twitch/patches/VideoAdsPatch;->shouldBlockVideoAds()Z", - "show_video_ads", - listOf( - ContentConfigShowAdsFingerprint, - CheckAdEligibilityLambdaFingerprint, - GetReadyToShowAdFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - /* Amazon ads SDK */ - context.blockMethods( - "Lcom/amazon/ads/video/player/AdsManagerImpl;", - "playAds" - ) - - /* Twitch ads manager */ - context.blockMethods( - "Ltv/twitch/android/shared/ads/VideoAdManager;", - "checkAdEligibilityAndRequestAd", "requestAd", "requestAds" - ) - - /* Various ad presenters */ - context.blockMethods( - "Ltv/twitch/android/shared/ads/AdsPlayerPresenter;", - "requestAd", "requestFirstAd", "requestFirstAdIfEligible", "requestMidroll", "requestAdFromMultiAdFormatEvent" - ) - - context.blockMethods( - "Ltv/twitch/android/shared/ads/AdsVodPlayerPresenter;", - "requestAd", "requestFirstAd", - ) - - context.blockMethods( - "Ltv/twitch/android/feature/theatre/ads/AdEdgeAllocationPresenter;", - "parseAdAndCheckEligibility", "requestAdsAfterEligibilityCheck", "showAd", "bindMultiAdFormatAllocation" - ) - - /* A/B ad testing experiments */ - context.blockMethods( - "Ltv/twitch/android/provider/experiments/helpers/DisplayAdsExperimentHelper;", - "areDisplayAdsEnabled", - returnMethod = ReturnMethod('Z', "0") - ) - - context.blockMethods( - "Ltv/twitch/android/shared/ads/tracking/MultiFormatAdsTrackingExperiment;", - "shouldUseMultiAdFormatTracker", "shouldUseVideoAdTracker", - returnMethod = ReturnMethod('Z', "0") - ) - - context.blockMethods( - "Ltv/twitch/android/shared/ads/MultiformatAdsExperiment;", - "shouldDisableClientSideLivePreroll", "shouldDisableClientSideVodPreroll", - returnMethod = ReturnMethod('Z', "1") - ) - - // Pretend our player is ineligible for all ads - with(CheckAdEligibilityLambdaFingerprint.result!!) { - mutableMethod.addInstructions( - 0, - """ - ${createConditionInstructions()} - const/4 v0, 0 - invoke-static {v0}, Lio/reactivex/Single;->just(Ljava/lang/Object;)Lio/reactivex/Single; - move-result-object p0 - return-object p0 - """, - listOf(ExternalLabel(skipLabelName, mutableMethod.instruction(0))) - ) - } - - with(GetReadyToShowAdFingerprint.result!!) { - val adFormatDeclined = "Ltv/twitch/android/shared/display/ads/theatre/StreamDisplayAdsPresenter\$Action\$AdFormatDeclined;" - mutableMethod.addInstructions( - 0, - """ - ${createConditionInstructions()} - sget-object p2, $adFormatDeclined->INSTANCE:$adFormatDeclined - invoke-static {p1, p2}, Ltv/twitch/android/core/mvp/presenter/StateMachineKt;->plus(Ltv/twitch/android/core/mvp/presenter/PresenterState;Ltv/twitch/android/core/mvp/presenter/PresenterAction;)Ltv/twitch/android/core/mvp/presenter/StateAndAction; - move-result-object p1 - return-object p1 - """, - listOf(ExternalLabel(skipLabelName, mutableMethod.instruction(0))) - ) - } - - // Spoof showAds JSON field - with(ContentConfigShowAdsFingerprint.result!!) { - mutableMethod.addInstructions(0, """ - ${createConditionInstructions()} - const/4 v0, 0 - :$skipLabelName - return v0 - """ - ) - } - - SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences( - SwitchPreference( - "revanced_block_video_ads", - StringResource( - "revanced_block_video_ads", - "Block video ads" - ), - true, - StringResource( - "revanced_block_video_ads_on", - "Video ads are blocked" - ), - StringResource( - "revanced_block_video_ads_off", - "Video ads are unblocked" - ), - ) - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/annotations/ShowDeletedMessagesCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/annotations/ShowDeletedMessagesCompatibility.kt deleted file mode 100644 index 1a54cf917..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/annotations/ShowDeletedMessagesCompatibility.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.twitch.chat.antidelete.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("tv.twitch.android.app")]) -@Target(AnnotationTarget.CLASS) -internal annotation class ShowDeletedMessagesCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/ChatUtilCreateDeletedSpanFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/ChatUtilCreateDeletedSpanFingerprint.kt deleted file mode 100644 index 733710b2b..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/ChatUtilCreateDeletedSpanFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.twitch.chat.antidelete.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object ChatUtilCreateDeletedSpanFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/ChatUtil\$Companion;") && methodDef.name == "createDeletedSpanFromChatMessageSpan" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/DeletedMessageClickableSpanCtorFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/DeletedMessageClickableSpanCtorFingerprint.kt deleted file mode 100644 index 6ecb63cbd..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/DeletedMessageClickableSpanCtorFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.twitch.chat.antidelete.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object DeletedMessageClickableSpanCtorFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("DeletedMessageClickableSpan;") - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/SetHasModAccessFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/SetHasModAccessFingerprint.kt deleted file mode 100644 index 7e8ee66a3..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/SetHasModAccessFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.chat.antidelete.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SetHasModAccessFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("DeletedMessageClickableSpan;") && methodDef.name == "setHasModAccess" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/patch/ShowDeletedMessagesPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/patch/ShowDeletedMessagesPatch.kt deleted file mode 100644 index dba6e833e..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/patch/ShowDeletedMessagesPatch.kt +++ /dev/null @@ -1,103 +0,0 @@ -package app.revanced.patches.twitch.chat.antidelete.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.* -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.ListPreference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility -import app.revanced.patches.twitch.chat.antidelete.fingerprints.* -import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("show-deleted-messages") -@Description("Shows deleted chat messages behind a clickable spoiler.") -@ShowDeletedMessagesCompatibility -@Version("0.0.1") -class ShowDeletedMessagesPatch : BytecodePatch( - listOf( - SetHasModAccessFingerprint, - DeletedMessageClickableSpanCtorFingerprint, - ChatUtilCreateDeletedSpanFingerprint - ) -) { - private fun createSpoilerConditionInstructions(register: String = "v0") = """ - invoke-static {}, Lapp/revanced/twitch/patches/ShowDeletedMessagesPatch;->shouldUseSpoiler()Z - move-result $register - if-eqz $register, :no_spoiler - """ - - override fun execute(context: BytecodeContext): PatchResult { - // Spoiler mode: Force set hasModAccess member to true in constructor - with(DeletedMessageClickableSpanCtorFingerprint.result!!.mutableMethod) { - addInstructions( - implementation!!.instructions.lastIndex, /* place in front of return-void */ - """ - ${createSpoilerConditionInstructions()} - const/4 v0, 1 - iput-boolean v0, p0, $definingClass->hasModAccess:Z - """, - listOf(ExternalLabel("no_spoiler", instruction(implementation!!.instructions.lastIndex))) - ) - } - - // Spoiler mode: Disable setHasModAccess setter - with(SetHasModAccessFingerprint.result!!) { - mutableMethod.addInstruction(0, "return-void") - } - - // Cross-out mode: Reformat span of deleted message - with(ChatUtilCreateDeletedSpanFingerprint.result!!) { - mutableMethod.addInstructions( - 0, - """ - invoke-static {p2}, Lapp/revanced/twitch/patches/ShowDeletedMessagesPatch;->reformatDeletedMessage(Landroid/text/Spanned;)Landroid/text/Spanned; - move-result-object v0 - if-eqz v0, :no_reformat - return-object v0 - """, - listOf(ExternalLabel("no_reformat", mutableMethod.instruction(0))) - ) - } - - SettingsPatch.PreferenceScreen.CHAT.GENERAL.addPreferences( - ListPreference( - "revanced_show_deleted_messages", - StringResource( - "revanced_show_deleted_messages_title", - "Show deleted messages" - ), - ArrayResource( - "revanced_deleted_messages", - listOf( - StringResource("revanced_deleted_messages_hide", "Do not show deleted messages"), - StringResource("revanced_deleted_messages_spoiler", "Hide deleted messages behind a spoiler"), - StringResource("revanced_deleted_messages_cross_out", "Show deleted messages as crossed-out text") - ) - ), - ArrayResource( - "revanced_deleted_messages_values", - listOf( - StringResource("key_revanced_deleted_messages_hide", "hide"), - StringResource("key_revanced_deleted_messages_spoiler", "spoiler"), - StringResource("key_revanced_deleted_messages_cross_out", "cross-out") - ) - ), - "cross-out" - ) - ) - - SettingsPatch.addString("revanced_deleted_msg", "message deleted") - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitch/debug/annotations/DebugModeCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/debug/annotations/DebugModeCompatibility.kt deleted file mode 100644 index 078bae90d..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/debug/annotations/DebugModeCompatibility.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.twitch.debug.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("tv.twitch.android.app")]) -@Target(AnnotationTarget.CLASS) -internal annotation class DebugModeCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/IsDebugConfigEnabledFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/IsDebugConfigEnabledFingerprint.kt deleted file mode 100644 index e7a317849..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/IsDebugConfigEnabledFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.debug.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object IsDebugConfigEnabledFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "isDebugConfigEnabled" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/IsOmVerificationEnabledFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/IsOmVerificationEnabledFingerprint.kt deleted file mode 100644 index cf8f1f759..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/IsOmVerificationEnabledFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.debug.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object IsOmVerificationEnabledFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "isOmVerificationEnabled" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/ShouldShowDebugOptionsFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/ShouldShowDebugOptionsFingerprint.kt deleted file mode 100644 index 12c5de043..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/debug/fingerprints/ShouldShowDebugOptionsFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.debug.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object ShouldShowDebugOptionsFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "shouldShowDebugOptions" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/debug/patch/DebugModePatch.kt b/src/main/kotlin/app/revanced/patches/twitch/debug/patch/DebugModePatch.kt deleted file mode 100644 index 755efe696..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/debug/patch/DebugModePatch.kt +++ /dev/null @@ -1,76 +0,0 @@ -package app.revanced.patches.twitch.debug.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility -import app.revanced.patches.twitch.debug.fingerprints.IsDebugConfigEnabledFingerprint -import app.revanced.patches.twitch.debug.fingerprints.IsOmVerificationEnabledFingerprint -import app.revanced.patches.twitch.debug.fingerprints.ShouldShowDebugOptionsFingerprint -import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch - -@Patch(false) -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("debug-mode") -@Description("Enables Twitch's internal debugging mode.") -@DebugModeCompatibility -@Version("0.0.1") -class DebugModePatch : BytecodePatch( - listOf( - IsDebugConfigEnabledFingerprint, - IsOmVerificationEnabledFingerprint, - ShouldShowDebugOptionsFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - listOf( - IsDebugConfigEnabledFingerprint, - IsOmVerificationEnabledFingerprint, - ShouldShowDebugOptionsFingerprint - ).forEach { - with(it.result!!) { - with(mutableMethod) { - addInstructions( - 0, - """ - invoke-static {}, Lapp/revanced/twitch/patches/DebugModePatch;->isDebugModeEnabled()Z - move-result v0 - return v0 - """ - ) - } - } - } - - SettingsPatch.PreferenceScreen.MISC.OTHER.addPreferences( - SwitchPreference( - "revanced_debug_mode", - StringResource( - "revanced_debug_mode_enable", - "Enable debug mode" - ), - false, - StringResource( - "revanced_debug_mode_on", - "Debug mode is enabled (not recommended)" - ), - StringResource( - "revanced_debug_mode_off", - "Debug mode is disabled" - ), - ) - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/annotations/IntegrationsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/annotations/IntegrationsCompatibility.kt deleted file mode 100644 index 40778ece2..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/annotations/IntegrationsCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.twitch.misc.integrations.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("tv.twitch.android.app")]) -@Target(AnnotationTarget.CLASS) -internal annotation class IntegrationsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/fingerprints/InitFingerprint.kt deleted file mode 100644 index 7f55dd22f..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/fingerprints/InitFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.twitch.misc.integrations.fingerprints - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patches.twitch.misc.integrations.annotations.IntegrationsCompatibility -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint - -@Name("init-fingerprint") -@IntegrationsCompatibility -@Version("0.0.1") -object InitFingerprint : IntegrationsFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/TwitchApplication;") && - methodDef.name == "onCreate" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/patch/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/patch/IntegrationsPatch.kt deleted file mode 100644 index b9d0195fd..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/integrations/patch/IntegrationsPatch.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.twitch.misc.integrations.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.patch.annotations.RequiresIntegrations -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch -import app.revanced.patches.twitch.misc.integrations.annotations.IntegrationsCompatibility -import app.revanced.patches.twitch.misc.integrations.fingerprints.InitFingerprint - -@Name("integrations") -@IntegrationsCompatibility -@RequiresIntegrations -class IntegrationsPatch : AbstractIntegrationsPatch( - "Lapp/revanced/twitch/utils/ReVancedUtils;", - listOf(InitFingerprint) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/annotations/SettingsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/annotations/SettingsCompatibility.kt deleted file mode 100644 index 2b632f8ee..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/annotations/SettingsCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("tv.twitch.android.app")]) -@Target(AnnotationTarget.CLASS) -internal annotation class SettingsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/bytecode/patch/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/bytecode/patch/SettingsPatch.kt deleted file mode 100644 index d0f8b7214..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/bytecode/patch/SettingsPatch.kt +++ /dev/null @@ -1,196 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.* -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.shared.settings.preference.impl.PreferenceCategory -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.util.AbstractPreferenceScreen -import app.revanced.patches.twitch.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.twitch.misc.settings.annotations.SettingsCompatibility -import app.revanced.patches.twitch.misc.settings.components.CustomPreferenceCategory -import app.revanced.patches.twitch.misc.settings.fingerprints.* -import app.revanced.patches.twitch.misc.settings.resource.patch.SettingsResourcePatch -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.immutable.ImmutableField - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsResourcePatch::class]) -@Name("settings") -@Description("Adds settings menu to Twitch.") -@SettingsCompatibility -@Version("0.0.1") -class SettingsPatch : BytecodePatch( - listOf( - SettingsActivityOnCreateFingerprint, - SettingsMenuItemEnumFingerprint, - MenuGroupsUpdatedFingerprint, - MenuGroupsOnClickFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - // Hook onCreate to handle fragment creation - with(SettingsActivityOnCreateFingerprint.result!!) { - val insertIndex = mutableMethod.implementation!!.instructions.size - 2 - mutableMethod.addInstructions( - insertIndex, - """ - invoke-static {p0}, $SETTINGS_HOOKS_CLASS->handleSettingsCreation(Landroidx/appcompat/app/AppCompatActivity;)Z - move-result v0 - if-eqz v0, :no_rv_settings_init - return-void - """, - listOf(ExternalLabel("no_rv_settings_init", mutableMethod.instruction(insertIndex))) - ) - } - - // Create new menu item for settings menu - with(SettingsMenuItemEnumFingerprint.result!!) { - injectMenuItem( - REVANCED_SETTINGS_MENU_ITEM_NAME, - REVANCED_SETTINGS_MENU_ITEM_ID, - REVANCED_SETTINGS_MENU_ITEM_TITLE_RES, - REVANCED_SETTINGS_MENU_ITEM_ICON_RES - ) - } - - // Intercept settings menu creation and add new menu item - with(MenuGroupsUpdatedFingerprint.result!!) { - mutableMethod.addInstructions( - 0, - """ - sget-object v0, $MENU_ITEM_ENUM_CLASS->$REVANCED_SETTINGS_MENU_ITEM_NAME:$MENU_ITEM_ENUM_CLASS - invoke-static {p1, v0}, $SETTINGS_HOOKS_CLASS->handleSettingMenuCreation(Ljava/util/List;Ljava/lang/Object;)Ljava/util/List; - move-result-object p1 - """ - ) - } - - // Intercept onclick events for the settings menu - with(MenuGroupsOnClickFingerprint.result!!) { - val insertIndex = 0 - mutableMethod.addInstructions( - insertIndex, - """ - invoke-static {p1}, $SETTINGS_HOOKS_CLASS->handleSettingMenuOnClick(Ljava/lang/Enum;)Z - move-result p2 - if-eqz p2, :no_rv_settings_onclick - sget-object p1, $MENU_DISMISS_EVENT_CLASS->INSTANCE:$MENU_DISMISS_EVENT_CLASS - invoke-virtual {p0, p1}, Ltv/twitch/android/core/mvp/viewdelegate/RxViewDelegate;->pushEvent(Ltv/twitch/android/core/mvp/viewdelegate/ViewDelegateEvent;)V - return-void - """, - listOf(ExternalLabel("no_rv_settings_onclick", mutableMethod.instruction(insertIndex))) - ) - } - - addString("revanced_settings", "ReVanced Settings", false) - addString("revanced_reboot_message", "Twitch needs to restart to apply your changes. Restart now?", false) - addString("revanced_reboot", "Restart", false) - addString("revanced_cancel", "Cancel", false) - - return PatchResultSuccess() - } - - internal companion object { - fun addString(identifier: String, value: String, formatted: Boolean = true) = - SettingsResourcePatch.addString(identifier, value, formatted) - - fun addPreferenceScreen(preferenceScreen: app.revanced.patches.shared.settings.preference.impl.PreferenceScreen) = - SettingsResourcePatch.addPreferenceScreen(preferenceScreen) - - /* Private members */ - private const val REVANCED_SETTINGS_MENU_ITEM_NAME = "RevancedSettings" - private const val REVANCED_SETTINGS_MENU_ITEM_ID = 0x7 - private const val REVANCED_SETTINGS_MENU_ITEM_TITLE_RES = "revanced_settings" - private const val REVANCED_SETTINGS_MENU_ITEM_ICON_RES = "ic_settings" - - private const val MENU_ITEM_ENUM_CLASS = "Ltv/twitch/android/feature/settings/menu/SettingsMenuItem;" - private const val MENU_DISMISS_EVENT_CLASS = "Ltv/twitch/android/feature/settings/menu/SettingsMenuViewDelegate\$Event\$OnDismissClicked;" - - private const val INTEGRATIONS_PACKAGE = "app/revanced/twitch" - private const val SETTINGS_HOOKS_CLASS = "L$INTEGRATIONS_PACKAGE/settingsmenu/SettingsHooks;" - private const val REVANCED_UTILS_CLASS = "L$INTEGRATIONS_PACKAGE/utils/ReVancedUtils;" - - private fun MethodFingerprintResult.injectMenuItem( - name: String, - value: Int, - titleResourceName: String, - iconResourceName: String - ) { - // Add new static enum member field - mutableClass.staticFields.add( - ImmutableField( - mutableMethod.definingClass, - name, - MENU_ITEM_ENUM_CLASS, - AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.ENUM or AccessFlags.STATIC, - null, - null, - null - ).toMutable() - ) - - // Add initializer for the new enum member - mutableMethod.addInstructions( - mutableMethod.implementation!!.instructions.size - 4, - """ - new-instance v0, $MENU_ITEM_ENUM_CLASS - const-string v1, "$titleResourceName" - invoke-static {v1}, $REVANCED_UTILS_CLASS->getStringId(Ljava/lang/String;)I - move-result v1 - const-string v3, "$iconResourceName" - invoke-static {v3}, $REVANCED_UTILS_CLASS->getDrawableId(Ljava/lang/String;)I - move-result v3 - const-string v4, "$name" - const/4 v5, $value - invoke-direct {v0, v4, v5, v1, v3}, $MENU_ITEM_ENUM_CLASS->(Ljava/lang/String;III)V - sput-object v0, $MENU_ITEM_ENUM_CLASS->$name:$MENU_ITEM_ENUM_CLASS - """ - ) - } - } - - /** - * Preference screens patches should add their settings to. - */ - internal object PreferenceScreen : AbstractPreferenceScreen() { - val ADS = CustomScreen("ads", "Ads", "Ad blocking settings") - val CHAT = CustomScreen("chat", "Chat", "Chat settings") - val MISC = CustomScreen("misc", "Misc", "Miscellaneous patches") - - internal class CustomScreen(key: String, title: String, summary: String) : Screen(key, title, summary) { - /* Categories */ - val GENERAL = CustomCategory("general", "General settings") - val OTHER = CustomCategory("other", "Other settings") - val CLIENT_SIDE = CustomCategory("client_ads", "Client-side ads") - val SURESTREAM = CustomCategory("surestream_ads", "Server-side surestream ads") - - internal inner class CustomCategory(key: String, title: String) : Screen.Category(key, title) { - /* For Twitch, we need to load our CustomPreferenceCategory class instead of the default one. */ - override fun transform(): PreferenceCategory { - return CustomPreferenceCategory( - key, - StringResource("${key}_title", title), - preferences.sortedBy { it.title.value } - ) - } - } - } - - override fun commit(screen: app.revanced.patches.shared.settings.preference.impl.PreferenceScreen) { - addPreferenceScreen(screen) - } - } - - override fun close() = PreferenceScreen.close() -} diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/components/CustomPreferenceCategory.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/components/CustomPreferenceCategory.kt deleted file mode 100644 index 20c7bdb80..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/components/CustomPreferenceCategory.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.components - -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.StringResource - -/** - * Customized preference category for Twitch. - * - * @param key The key of the preference. - * @param title The title of the preference. - * @param preferences Child preferences of this category. - */ -internal open class CustomPreferenceCategory( - key: String, - title: StringResource, - preferences: List -) : PreferenceCategory(key, title, preferences) { - override val tag: String = "app.revanced.twitch.settingsmenu.preference.CustomPreferenceCategory" -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/MenuGroupsOnClickFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/MenuGroupsOnClickFingerprint.kt deleted file mode 100644 index 1a6375986..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/MenuGroupsOnClickFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object MenuGroupsOnClickFingerprint : MethodFingerprint( - "V", - AccessFlags.PRIVATE or AccessFlags.STATIC or AccessFlags.FINAL, - listOf("L", "L", "L"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/SettingsMenuViewDelegate;") - && methodDef.name.contains("render") - } -) diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/MenuGroupsUpdatedFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/MenuGroupsUpdatedFingerprint.kt deleted file mode 100644 index 913f31d14..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/MenuGroupsUpdatedFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object MenuGroupsUpdatedFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/SettingsMenuPresenter\$Event\$MenuGroupsUpdated;") - && methodDef.name == "" - } -) diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/SettingsActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/SettingsActivityOnCreateFingerprint.kt deleted file mode 100644 index f976f0210..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/SettingsActivityOnCreateFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SettingsActivityOnCreateFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/SettingsActivity;") && - methodDef.name == "onCreate" - } -) diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/SettingsMenuItemEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/SettingsMenuItemEnumFingerprint.kt deleted file mode 100644 index cdb2dd177..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/fingerprints/SettingsMenuItemEnumFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SettingsMenuItemEnumFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("/SettingsMenuItem;") && methodDef.name == "" - } -) diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/resource/patch/SettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/resource/patch/SettingsResourcePatch.kt deleted file mode 100644 index 07420cea9..000000000 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/resource/patch/SettingsResourcePatch.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.twitch.misc.settings.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen -import app.revanced.patches.shared.settings.resource.patch.AbstractSettingsResourcePatch -import app.revanced.patches.twitch.misc.settings.annotations.SettingsCompatibility - -@Name("settings-resource-patch") -@SettingsCompatibility -@Version("0.0.1") -class SettingsResourcePatch : AbstractSettingsResourcePatch( -"revanced_prefs", -"twitch/settings" -) { - internal companion object { - /* Companion delegates */ - - /** - * Add a new string to the resources. - * - * @param identifier The key of the string. - * @param value The value of the string. - * @throws IllegalArgumentException if the string already exists. - */ - fun addString(identifier: String, value: String, formatted: Boolean) = - AbstractSettingsResourcePatch.addString(identifier, value, formatted) - - /** - * Add an array to the resources. - * - * @param arrayResource The array resource to add. - */ - fun addArray(arrayResource: ArrayResource) = AbstractSettingsResourcePatch.addArray(arrayResource) - - /** - * Add a preference to the settings. - * - * @param preferenceScreen The name of the preference screen. - */ - fun addPreferenceScreen(preferenceScreen: PreferenceScreen) = AbstractSettingsResourcePatch.addPreference(preferenceScreen) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/annotations/HideViewsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/annotations/HideViewsCompatibility.kt deleted file mode 100644 index 3a4116ab9..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/annotations/HideViewsCompatibility.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.twitter.layout.hideviews.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.twitter.android", arrayOf("9.69.1-release.0", "9.71.0-release.0") - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideViewsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/InlineActionTypesFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/InlineActionTypesFingerprint.kt deleted file mode 100644 index eb4f86a25..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/InlineActionTypesFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.twitter.layout.hideviews.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object InlineActionTypesFingerprint : MethodFingerprint( - returnType = "Ljava/util/List", - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - strings = listOf( - "getCurrentMemoizing()", - "android_animated_reply_icon_enabled", - "reply_voting_android_position_before_favorite_enabled" - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsContainerConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsContainerConstructorFingerprint.kt deleted file mode 100644 index dda7c74cc..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsContainerConstructorFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.twitter.layout.hideviews.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object TweetStatsContainerConstructorFingerprint : MethodFingerprint( - access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - parameters = listOf("L"), - opcodes = listOf( - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsContainerWrapperConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsContainerWrapperConstructorFingerprint.kt deleted file mode 100644 index 791e15162..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsContainerWrapperConstructorFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.twitter.layout.hideviews.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object TweetStatsContainerWrapperConstructorFingerprint : MethodFingerprint( - access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - parameters = listOf("L"), - opcodes = listOf( - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsViewDelegateBinderFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsViewDelegateBinderFingerprint.kt deleted file mode 100644 index 3d3f845b4..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/fingerprints/TweetStatsViewDelegateBinderFingerprint.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.twitter.layout.hideviews.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object TweetStatsViewDelegateBinderFingerprint : MethodFingerprint( - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.NEW_INSTANCE, - Opcode.CONST_16, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST_16, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_OBJECT - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/patch/HideViewsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/patch/HideViewsBytecodePatch.kt deleted file mode 100644 index 3752d0798..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/patch/HideViewsBytecodePatch.kt +++ /dev/null @@ -1,114 +0,0 @@ -package app.revanced.patches.twitter.layout.hideviews.patch - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.extensions.removeInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.twitter.layout.hideviews.fingerprints.InlineActionTypesFingerprint -import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsContainerConstructorFingerprint -import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsContainerWrapperConstructorFingerprint -import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsViewDelegateBinderFingerprint -import org.jf.dexlib2.Opcode - -class HideViewsBytecodePatch : BytecodePatch( - listOf( - InlineActionTypesFingerprint, - TweetStatsContainerWrapperConstructorFingerprint, - TweetStatsContainerConstructorFingerprint, - TweetStatsViewDelegateBinderFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - removeViewsFromTimeline(context) - removeTweetStatViewInitializer(context) - removeTweetStatViewWrapperInitializer(context) - removeViewDelegateBinderSubscription() - return PatchResultSuccess() - } - - private fun removeViewsFromTimeline(context: BytecodeContext) { - val addViewsToActionBarMethodFingerprint = object : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IF_EQZ, - ) - ) {} - transformMethodAtPattern( - context, - InlineActionTypesFingerprint, - addViewsToActionBarMethodFingerprint - ) { patternScanResult, method -> - method.removeInstruction(patternScanResult.endIndex - 1) - } - } - - private fun removeTweetStatViewInitializer(context: BytecodeContext) { - val returnFingerprint = object : MethodFingerprint( - opcodes = listOf(Opcode.RETURN_VOID) - ) {} - transformMethodAtPattern( - context, - TweetStatsContainerConstructorFingerprint, - returnFingerprint - ) { patternScanResult, method -> - method.removeInstructions(patternScanResult.endIndex - 3, 2) - } - } - - private fun removeTweetStatViewWrapperInitializer(context: BytecodeContext) { - val wrapperReturnFingerprint = object : MethodFingerprint( - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.RETURN_VOID, - ) - ) {} - transformMethodAtPattern( - context, - TweetStatsContainerWrapperConstructorFingerprint, - wrapperReturnFingerprint - ) { patternScanResult, method -> - method.removeInstructions(patternScanResult.startIndex - 4, 3) - } - } - - private fun removeViewDelegateBinderSubscription() { - transformMethod(TweetStatsViewDelegateBinderFingerprint) { result, method -> - method.removeInstructions(result.scanResult.patternScanResult!!.startIndex - 4, 9) - } - } - - private fun transformMethodAtPattern( - context: BytecodeContext, methodFingerprint: MethodFingerprint, - patternFingerprint: MethodFingerprint, transformer: TransformerAtPattern - ) { - transformMethod(methodFingerprint) { result, method -> - val patternResult = patternFingerprint.also { - it.resolve(context, method, result.classDef) - }.result!! - transformer(patternResult.scanResult.patternScanResult!!, method) - } - } - - private fun transformMethod(methodFingerprint: MethodFingerprint, transformer: Transformer) { - val result = methodFingerprint.result!! - val method = result.mutableMethod - transformer(result, method) - } -} - -private typealias Transformer = (MethodFingerprintResult, MutableMethod) -> Unit - -private typealias TransformerAtPattern = (MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult, MutableMethod) -> Unit \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/patch/HideViewsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/patch/HideViewsResourcePatch.kt deleted file mode 100644 index 734326668..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/layout/hideviews/patch/HideViewsResourcePatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.twitter.layout.hideviews.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.twitter.layout.hideviews.annotations.HideViewsCompatibility -import org.w3c.dom.Element - -@Patch -@DependsOn([HideViewsBytecodePatch::class]) -@Name("hide-views-stats") -@Description("Hides the view stats under tweets.") -@HideViewsCompatibility -@Version("0.0.1") -class HideViewsResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - arrayOf( - "res/layout/condensed_tweet_stats.xml", - "res/layout/focal_tweet_stats.xml" - ).forEach { file -> - context.xmlEditor[file].use { editor -> - val tags = editor.file.getElementsByTagName("com.twitter.ui.tweet.TweetStatView") - List(tags.length) { tags.item(it) as Element } - .filter { it.getAttribute("android:id").contains("views_stat") } - .forEach { it.parentNode.removeChild(it) } - } - } - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/annotations/DynamicColorCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/annotations/DynamicColorCompatibility.kt deleted file mode 100644 index 3015f29f0..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/annotations/DynamicColorCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.twitter.misc.dynamiccolor.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.twitter.android")]) -@Target(AnnotationTarget.CLASS) -internal annotation class DynamicColorCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/patch/DynamicColorPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/patch/DynamicColorPatch.kt deleted file mode 100644 index 3ba3b564c..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/dynamiccolor/patch/DynamicColorPatch.kt +++ /dev/null @@ -1,87 +0,0 @@ -package app.revanced.patches.twitter.misc.dynamiccolor.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.twitter.misc.dynamiccolor.annotations.DynamicColorCompatibility -import java.io.FileWriter -import java.nio.file.Files - -@Patch -@Name("dynamic-color") -@Description("Replaces the default Twitter Blue with the users Material You palette.") -@DynamicColorCompatibility -@Version("0.0.1") -class DynamicColorPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - val resDirectory = context["res"] - if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.") - - val valuesV31Directory = resDirectory.resolve("values-v31") - if (!valuesV31Directory.isDirectory) Files.createDirectories(valuesV31Directory.toPath()) - - val valuesNightV31Directory = resDirectory.resolve("values-night-v31") - if (!valuesNightV31Directory.isDirectory) Files.createDirectories(valuesNightV31Directory.toPath()) - - listOf(valuesV31Directory, valuesNightV31Directory).forEach { it -> - val colorsXml = it.resolve("colors.xml") - - if(!colorsXml.exists()) { - FileWriter(colorsXml).use { - it.write("") - } - } - } - - context.xmlEditor["res/values-v31/colors.xml"].use { editor -> - val document = editor.file - - mapOf( - "ps__twitter_blue" to "@color/twitter_blue", - "ps__twitter_blue_pressed" to "@color/twitter_blue_fill_pressed", - "twitter_blue" to "@android:color/system_accent1_400", - "twitter_blue_fill_pressed" to "@android:color/system_accent1_300", - "twitter_blue_opacity_30" to "@android:color/system_accent1_100", - "twitter_blue_opacity_50" to "@android:color/system_accent1_200", - "twitter_blue_opacity_58" to "@android:color/system_accent1_300", - "deep_transparent_twitter_blue" to "@android:color/system_accent1_200", - "ic_launcher_background" to "#1DA1F2" - ).forEach { (k, v) -> - val colorElement = document.createElement("color") - - colorElement.setAttribute("name", k) - colorElement.textContent = v - - document.getElementsByTagName("resources").item(0).appendChild(colorElement) - } - } - - context.xmlEditor["res/values-night-v31/colors.xml"].use { editor -> - val document = editor.file - - mapOf( - "twitter_blue" to "@android:color/system_accent1_200", - "twitter_blue_fill_pressed" to "@android:color/system_accent1_300", - "twitter_blue_opacity_30" to "@android:color/system_accent1_50", - "twitter_blue_opacity_50" to "@android:color/system_accent1_100", - "twitter_blue_opacity_58" to "@android:color/system_accent1_200", - "deep_transparent_twitter_blue" to "@android:color/system_accent1_200" - ).forEach { (k, v) -> - val colorElement = document.createElement("color") - - colorElement.setAttribute("name", k) - colorElement.textContent = v - - document.getElementsByTagName("resources").item(0).appendChild(colorElement) - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/JsonHookPatchFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/JsonHookPatchFingerprint.kt deleted file mode 100644 index cc533162d..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/JsonHookPatchFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.json.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object JsonHookPatchFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> methodDef.name == "" }, - opcodes = listOf(Opcode.IGET_OBJECT) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/JsonInputStreamFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/JsonInputStreamFingerprint.kt deleted file mode 100644 index 7c80f5bde..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/JsonInputStreamFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.json.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object JsonInputStreamFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - if (methodDef.parameterTypes.size == 0) false - else methodDef.parameterTypes.first() == "Ljava/io/InputStream;" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/LoganSquareFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/LoganSquareFingerprint.kt deleted file mode 100644 index 98f0a82f6..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/fingerprints/LoganSquareFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.json.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object LoganSquareFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> methodDef.definingClass.endsWith("LoganSquare;") } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/patch/JsonHookPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/patch/JsonHookPatch.kt deleted file mode 100644 index c604c6810..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/json/patch/JsonHookPatch.kt +++ /dev/null @@ -1,116 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.json.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.RequiresIntegrations -import app.revanced.patches.twitter.misc.hook.json.fingerprints.JsonHookPatchFingerprint -import app.revanced.patches.twitter.misc.hook.json.fingerprints.JsonInputStreamFingerprint -import app.revanced.patches.twitter.misc.hook.json.fingerprints.LoganSquareFingerprint -import java.io.InvalidClassException - -@Name("json-hook") -@Description("Hooks the stream which reads JSON responses.") -@Version("0.0.1") -@RequiresIntegrations -class JsonHookPatch : BytecodePatch( - listOf(LoganSquareFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - // Make sure the integrations are present. - val jsonHookPatch = context.findClass { it.type == JSON_HOOK_PATCH_CLASS_DESCRIPTOR } - ?: return PatchResultError("Could not find integrations.") - - // Allow patch to inject hooks into the patches integrations. - jsonHookPatchFingerprintResult = JsonHookPatchFingerprint.also { - it.resolve(context, jsonHookPatch.immutableClass) - }.result ?: return PatchResultError("Unexpected integrations.") - - // Conveniently find the type to hook a method in, via a named field. - val jsonFactory = LoganSquareFingerprint.result - ?.classDef - ?.fields - ?.firstOrNull { it.name == "JSON_FACTORY" } - ?.type - .let { type -> - context.findClass { it.type == type }?.mutableClass - } ?: return PatchResultError("Could not find required class.") - - // Hook the methods first parameter. - JsonInputStreamFingerprint - .also { it.resolve(context, jsonFactory) } - .result - ?.mutableMethod - ?.addInstructions( - 0, - """ - invoke-static { p1 }, $JSON_HOOK_PATCH_CLASS_DESCRIPTOR->parseJsonHook(Ljava/io/InputStream;)Ljava/io/InputStream; - move-result-object p1 - """ - ) ?: return PatchResultError("Could not find method to hook.") - - return PatchResultSuccess() - } - - /** - * Create a hook class. - * The class has to extend on **JsonHook**. - * The class has to be a Kotlin object class, or at least have an INSTANCE field of itself. - * - * @param context The [BytecodeContext] of the current patch. - * @param descriptor The class descriptor of the hook. - */ - internal class Hook(context: BytecodeContext, private val descriptor: String) { - private var added = false - - /** - * Add the hook. - */ - internal fun add() { - if (added) return - - jsonHookPatchFingerprintResult.apply { - mutableMethod.apply { - addInstructions( - scanResult.patternScanResult!!.startIndex, - """ - sget-object v1, $descriptor->INSTANCE:$descriptor - invoke-virtual {v0, v1}, Lkotlin/collections/builders/ListBuilder;->add(Ljava/lang/Object;)Z - """ - ) - } - } - - added = true - } - - init { - context.findClass { it.type == descriptor }?.let { - it.mutableClass.also { classDef -> - if ( - classDef.superclass != JSON_HOOK_CLASS_DESCRIPTOR || - !classDef.fields.any { field -> field.name == "INSTANCE" } - ) throw InvalidClassException(classDef.type, "Not a hook class") - - } - } ?: throw ClassNotFoundException("Failed to find hook class") - } - } - - private companion object { - const val JSON_HOOK_CLASS_NAMESPACE = "app/revanced/twitter/patches/hook/json" - - const val JSON_HOOK_PATCH_CLASS_DESCRIPTOR = "L$JSON_HOOK_CLASS_NAMESPACE/JsonHookPatch;" - - const val BASE_PATCH_CLASS_NAME = "BaseJsonHook" - - const val JSON_HOOK_CLASS_DESCRIPTOR = "L$JSON_HOOK_CLASS_NAMESPACE/$BASE_PATCH_CLASS_NAME;" - - private lateinit var jsonHookPatchFingerprintResult: MethodFingerprintResult - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/BaseHookPatchPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/BaseHookPatchPatch.kt deleted file mode 100644 index f2dec2a20..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/BaseHookPatchPatch.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.patch - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.twitter.misc.hook.json.patch.JsonHookPatch - -@DependsOn([JsonHookPatch::class]) -abstract class BaseHookPatchPatch(private val hookClassDescriptor: String) : BytecodePatch() { - override fun execute(context: BytecodeContext) = try { - PatchResultSuccess().also { JsonHookPatch.Hook(context, hookClassDescriptor).add() } - } catch (ex: Exception) { - PatchResultError(ex) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/ads/annotations/HideAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/ads/annotations/HideAdsCompatibility.kt deleted file mode 100644 index cdfab469e..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/ads/annotations/HideAdsCompatibility.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.patch.ads.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.twitter.android" - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideAdsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/ads/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/ads/patch/HideAdsPatch.kt deleted file mode 100644 index 6273a26d8..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/ads/patch/HideAdsPatch.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.patch.ads.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.twitter.misc.hook.json.patch.JsonHookPatch -import app.revanced.patches.twitter.misc.hook.patch.BaseHookPatchPatch -import app.revanced.patches.twitter.misc.hook.patch.ads.annotations.HideAdsCompatibility - -@Patch -@Name("hide-ads") -@DependsOn([JsonHookPatch::class]) -@Description("Hides ads.") -@HideAdsCompatibility -@Version("0.0.1") -class HideAdsPatch : BaseHookPatchPatch(HOOK_CLASS_DESCRIPTOR) { - private companion object { - const val HOOK_CLASS_DESCRIPTOR = "Lapp/revanced/twitter/patches/hook/patch/ads/AdsHook;" - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/recommendation/annotations/HideRecommendedUsersCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/recommendation/annotations/HideRecommendedUsersCompatibility.kt deleted file mode 100644 index cac83ff82..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/recommendation/annotations/HideRecommendedUsersCompatibility.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.patch.recommendation.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.twitter.android" - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideRecommendedUsersCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/recommendation/patch/HideRecommendedUsersPatch.kt b/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/recommendation/patch/HideRecommendedUsersPatch.kt deleted file mode 100644 index a6ea294fb..000000000 --- a/src/main/kotlin/app/revanced/patches/twitter/misc/hook/patch/recommendation/patch/HideRecommendedUsersPatch.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.twitter.misc.hook.patch.recommendation.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.twitter.misc.hook.json.patch.JsonHookPatch -import app.revanced.patches.twitter.misc.hook.patch.BaseHookPatchPatch -import app.revanced.patches.twitter.misc.hook.patch.recommendation.annotations.HideRecommendedUsersCompatibility - -@Patch -@Name("hide-recommended-users") -@DependsOn([JsonHookPatch::class]) -@Description("Hides recommended users.") -@HideRecommendedUsersCompatibility -@Version("0.0.1") -class HideRecommendedUsersPatch : BaseHookPatchPatch(HOOK_CLASS_DESCRIPTOR) { - private companion object { - const val HOOK_CLASS_DESCRIPTOR = - "Lapp/revanced/twitter/patches/hook/patch/recommendation/RecommendedUsersHook;" - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/annotations/FirebaseGetCertPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/annotations/FirebaseGetCertPatchCompatibility.kt deleted file mode 100644 index 2a8f63791..000000000 --- a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/annotations/FirebaseGetCertPatchCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.warnwetter.misc.firebasegetcert.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("de.dwd.warnapp")]) -@Target(AnnotationTarget.CLASS) -internal annotation class FirebaseGetCertPatchCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/fingerprints/GetCertMessagingFingerprint.kt b/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/fingerprints/GetCertMessagingFingerprint.kt deleted file mode 100644 index 196f649cf..000000000 --- a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/fingerprints/GetCertMessagingFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object GetMessagingCertFingerprint : MethodFingerprint( - "Ljava/lang/String;", - strings = listOf( - "ContentValues", - "Could not get fingerprint hash for package: ", - "No such package: " - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/fingerprints/GetCertRegistrationFingerprint.kt b/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/fingerprints/GetCertRegistrationFingerprint.kt deleted file mode 100644 index 8c1fb8c55..000000000 --- a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/fingerprints/GetCertRegistrationFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object GetReqistrationCertFingerprint : MethodFingerprint( - "Ljava/lang/String;", - strings = listOf( - "FirebaseRemoteConfig", - "Could not get fingerprint hash for package: ", - "No such package: " - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/patch/FirebaseGetCertPatch.kt b/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/patch/FirebaseGetCertPatch.kt deleted file mode 100644 index c7dd384d4..000000000 --- a/src/main/kotlin/app/revanced/patches/warnwetter/misc/firebasegetcert/patch/FirebaseGetCertPatch.kt +++ /dev/null @@ -1,46 +0,0 @@ -package app.revanced.patches.warnwetter.misc.firebasegetcert.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.warnwetter.misc.firebasegetcert.annotations.FirebaseGetCertPatchCompatibility -import app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints.GetMessagingCertFingerprint -import app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints.GetReqistrationCertFingerprint - -@Name("spoof-cert-patch") -@Description("Spoofs the X-Android-Cert header.") -@FirebaseGetCertPatchCompatibility -@Version("0.0.1") -class FirebaseGetCertPatch : BytecodePatch( - listOf( - GetReqistrationCertFingerprint, - GetMessagingCertFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val spoofedInstruction = - """ - const-string v0, "0799DDF0414D3B3475E88743C91C0676793ED450" - return-object v0 - """ - - val registrationCertMethod = GetReqistrationCertFingerprint.result!!.mutableMethod - val messagingCertMethod = GetMessagingCertFingerprint.result!!.mutableMethod - - registrationCertMethod.addInstructions( - 0, - spoofedInstruction - ) - messagingCertMethod.addInstructions( - 0, - spoofedInstruction - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/annotations/PromoCodeUnlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/annotations/PromoCodeUnlockCompatibility.kt deleted file mode 100644 index c82c22c02..000000000 --- a/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/annotations/PromoCodeUnlockCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.warnwetter.misc.promocode.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("de.dwd.warnapp")]) -@Target(AnnotationTarget.CLASS) -internal annotation class PromoCodeUnlockCompatibility diff --git a/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/fingerprints/PromoCodeUnlockFingerprint.kt b/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/fingerprints/PromoCodeUnlockFingerprint.kt deleted file mode 100644 index a0eb98d7e..000000000 --- a/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/fingerprints/PromoCodeUnlockFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.warnwetter.misc.promocode.fingerprints -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PromoCodeUnlockFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("PromoTokenVerification;") && methodDef.name == "isValid" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/patch/PromoCodeUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/patch/PromoCodeUnlockPatch.kt deleted file mode 100644 index 68ee1de05..000000000 --- a/src/main/kotlin/app/revanced/patches/warnwetter/misc/promocode/patch/PromoCodeUnlockPatch.kt +++ /dev/null @@ -1,47 +0,0 @@ -package app.revanced.patches.warnwetter.misc.promocode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.warnwetter.misc.firebasegetcert.patch.FirebaseGetCertPatch -import app.revanced.patches.warnwetter.misc.promocode.annotations.PromoCodeUnlockCompatibility -import app.revanced.patches.warnwetter.misc.promocode.fingerprints.PromoCodeUnlockFingerprint - -@DependsOn( - [ - FirebaseGetCertPatch::class - ] -) -@Patch -@Name("promo-code-unlock") -@Description("Disables the validation of promo code. Any code will work to unlock all features.") -@PromoCodeUnlockCompatibility -@Version("0.0.1") -class PromoCodeUnlockPatch : BytecodePatch( - listOf( - PromoCodeUnlockFingerprint - ) -) { - - override fun execute(context: BytecodeContext): PatchResult { - val method = PromoCodeUnlockFingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - - return PatchResultSuccess() - } - - -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/annotations/UnlockProCompatibility.kt b/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/annotations/UnlockProCompatibility.kt deleted file mode 100644 index 4e6747399..000000000 --- a/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/annotations/UnlockProCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.windyapp.misc.pro.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("co.windyapp.android")]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockProCompatibility diff --git a/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/fingerprints/CheckProFingerprint.kt b/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/fingerprints/CheckProFingerprint.kt deleted file mode 100644 index 230f83a1e..000000000 --- a/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/fingerprints/CheckProFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.windyapp.misc.pro.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CheckProFingerprint : MethodFingerprint( - "I", - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("RawUserData;") && methodDef.name == "isPro" - } -) diff --git a/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/patch/UnlockProPatch.kt b/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/patch/UnlockProPatch.kt deleted file mode 100644 index fac915b59..000000000 --- a/src/main/kotlin/app/revanced/patches/windyapp/misc/unlockpro/patch/UnlockProPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.windyapp.misc.pro.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.windyapp.misc.pro.annotations.UnlockProCompatibility -import app.revanced.patches.windyapp.misc.pro.fingerprints.CheckProFingerprint - -@Patch -@Name("unlock-pro") -@Description("Unlocks all pro features.") -@UnlockProCompatibility -@Version("0.0.1") -class UnlockProPatch : BytecodePatch( - listOf( - CheckProFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val method = CheckProFingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/16 v0, 0x1 - return v0 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/GeneralAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/GeneralAdsCompatibility.kt deleted file mode 100644 index 7562a7977..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/GeneralAdsCompatibility.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.ad.general.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class GeneralAdsCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/fingerprints/ReelConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/fingerprints/ReelConstructorFingerprint.kt deleted file mode 100644 index b6140dcc3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/fingerprints/ReelConstructorFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.ad.general.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.ad.general.resource.patch.GeneralAdsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object ReelConstructorFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL - ), - customFingerprint = { method -> - method.implementation?.instructions?.any { - it.opcode == Opcode.CONST && (it as WideLiteralInstruction).wideLiteral == GeneralAdsResourcePatch.reelMultipleItemShelfId - } ?: false - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/patch/GeneralAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/patch/GeneralAdsPatch.kt deleted file mode 100644 index 9bcc728a4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/patch/GeneralAdsPatch.kt +++ /dev/null @@ -1,92 +0,0 @@ -package app.revanced.patches.youtube.ad.general.bytecode.patch - -import app.revanced.extensions.findMutableMethodOf -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility -import app.revanced.patches.youtube.ad.general.bytecode.fingerprints.ReelConstructorFingerprint -import app.revanced.patches.youtube.ad.general.resource.patch.GeneralAdsResourcePatch -import app.revanced.patches.youtube.misc.fix.backtoexitgesture.patch.FixBackToExitGesturePatch -import app.revanced.patches.shared.misc.fix.verticalscroll.patch.VerticalScrollPatch -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction -import org.jf.dexlib2.iface.instruction.formats.Instruction31i -import org.jf.dexlib2.iface.instruction.formats.Instruction35c - - -@Patch -@DependsOn([GeneralAdsResourcePatch::class, VerticalScrollPatch::class, FixBackToExitGesturePatch::class]) -@Name("general-ads") -@Description("Removes general ads.") -@GeneralAdsCompatibility -@Version("0.0.1") -class GeneralAdsPatch : BytecodePatch( - listOf(ReelConstructorFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - fun String.buildHideCall(viewRegister: Int) = "invoke-static { v$viewRegister }, " + - "Lapp/revanced/integrations/patches/GeneralAdsPatch;" + - "->" + - "$this(Landroid/view/View;)V" - - fun MutableMethod.injectHideCall(insertIndex: Int, viewRegister: Int, method: String) = - this.addInstruction(insertIndex, method.buildHideCall(viewRegister)) - - context.classes.forEach { classDef -> - classDef.methods.forEach { method -> - with(method.implementation) { - this?.instructions?.forEachIndexed { index, instruction -> - if (instruction.opcode != org.jf.dexlib2.Opcode.CONST) - return@forEachIndexed - // Instruction to store the id adAttribution into a register - if ((instruction as Instruction31i).wideLiteral != GeneralAdsResourcePatch.adAttributionId) - return@forEachIndexed - - val insertIndex = index + 1 - - // Call to get the view with the id adAttribution - with(instructions.elementAt(insertIndex)) { - if (opcode != org.jf.dexlib2.Opcode.INVOKE_VIRTUAL) - return@forEachIndexed - - // Hide the view - val viewRegister = (this as Instruction35c).registerC - context.proxy(classDef) - .mutableClass - .findMutableMethodOf(method) - .injectHideCall(insertIndex, viewRegister, "hideAdAttributionView") - } - } - } - } - } - - with( - ReelConstructorFingerprint.result - ?: return PatchResultError("Could not resolve fingerprint") - ) { - // iput-object v$viewRegister, ... - val insertIndex = this.scanResult.patternScanResult!!.startIndex + 2 - - with(this.mutableMethod) { - val viewRegister = (instruction(insertIndex) as TwoRegisterInstruction).registerA - - injectHideCall(insertIndex, viewRegister, "hideReelView") - } - - } - - return PatchResultSuccess() - } - -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/GeneralAdsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/GeneralAdsResourcePatch.kt deleted file mode 100644 index 4bcaecc3d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/GeneralAdsResourcePatch.kt +++ /dev/null @@ -1,303 +0,0 @@ -package app.revanced.patches.youtube.ad.general.resource.patch - -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.* -import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility -import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen - -@DependsOn( - dependencies = [ - LithoFilterPatch::class, - SettingsPatch::class, - ResourceMappingPatch::class - ] -) -@GeneralAdsCompatibility -@Version("0.0.1") -class GeneralAdsResourcePatch : ResourcePatch { - internal companion object { - var adAttributionId: Long = -1 - var reelMultipleItemShelfId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_adremover_separator", - StringResource("revanced_adremover_separator_title", "Hide gray separator"), - true, - StringResource("revanced_adremover_separator_summary_on", "Gray separators are hidden"), - StringResource("revanced_adremover_separator_summary_off", "Gray separators are shown") - ), - SwitchPreference( - "revanced_adremover_hide_channel_guidelines", - StringResource("revanced_adremover_hide_channel_guidelines_enabled_title", "Hide channel guidelines"), - true, - StringResource( - "revanced_adremover_hide_channel_guidelines_enabled_summary_on", - "Channel guidelines are hidden" - ), - StringResource( - "revanced_adremover_hide_channel_guidelines_enabled_summary_off", - "Channel guidelines are shown" - ) - ), - SwitchPreference( - "revanced_adremover_chapter_teaser", - StringResource( - "revanced_adremover_chapter_teaser_enabled_title", - "Hide chapter teaser under videos" - ), - true, - StringResource( - "revanced_adremover_chapter_teaser_enabled_summary_on", - "Chapter teasers are hidden" - ), - StringResource( - "revanced_adremover_chapter_teaser_enabled_summary_off", - "Chapter teasers are shown" - ) - ), - SwitchPreference( - "revanced_adremover_merchandise", - StringResource("revanced_adremover_merchandise_enabled_title", "Hide merchandise banners"), - true, - StringResource("revanced_adremover_merchandise_enabled_summary_on", "Merchandise banners are hidden"), - StringResource("revanced_adremover_merchandise_enabled_summary_off", "Merchandise banners are shown") - ), - SwitchPreference( - "revanced_adremover_community_posts_removal", - StringResource("revanced_adremover_community_posts_enabled_title", "Hide community posts"), - false, - StringResource("revanced_adremover_community_posts_enabled_summary_on", "Community posts are hidden"), - StringResource("revanced_adremover_community_posts_enabled_summary_off", "Community posts are shown") - ), - SwitchPreference( - "revanced_adremover_compact_banner_removal", - StringResource("revanced_adremover_compact_banner_enabled_title", "Hide compact banners"), - true, - StringResource("revanced_adremover_compact_banner_enabled_summary_on", "Compact banners are hidden"), - StringResource("revanced_adremover_compact_banner_enabled_summary_off", "Compact banners are shown") - ), - SwitchPreference( - "revanced_adremover_view_products", - StringResource("revanced_adremover_view_products_title", "Hide banner to view products"), - true, - StringResource("revanced_adremover_view_products_summary_on", "Banner is hidden"), - StringResource("revanced_adremover_view_products_summary_off", "Banner is shown") - ), - SwitchPreference( - "revanced_adremover_web_search_result", - StringResource("revanced_adremover_web_search_result_panel_title", "Hide web search results"), - true, - StringResource("revanced_adremover_web_search_result_summary_on", "Web search results are hidden"), - StringResource("revanced_adremover_web_search_result_summary_off", "Web search results are shown") - ), - SwitchPreference( - "revanced_adremover_movie", - StringResource("revanced_adremover_movie_enabled_title", "Hide movies section"), - true, - StringResource("revanced_adremover_movie_enabled_summary_on", "Movies section is hidden"), - StringResource("revanced_adremover_movie_enabled_summary_off", "Movies section is shown") - ), - SwitchPreference( - "revanced_adremover_feed_survey", - StringResource("revanced_adremover_feed_survey_enabled_title", "Hide feed surveys"), - true, - StringResource("revanced_adremover_feed_survey_enabled_summary_on", "Feed surveys are hidden"), - StringResource("revanced_adremover_feed_survey_enabled_summary_off", "Feed surveys are shown") - ), - SwitchPreference( - "revanced_adremover_shorts", - StringResource("revanced_adremover_shorts_enabled_title", "Hide shorts"), - true, - StringResource("revanced_adremover_shorts_enabled_summary_on", "Shorts are hidden"), - StringResource("revanced_adremover_shorts_enabled_summary_off", "Shorts are shown") - ), - SwitchPreference( - "revanced_adremover_community_guidelines", - StringResource("revanced_adremover_community_guidelines_enabled_title", "Hide community guidelines"), - true, - StringResource( - "revanced_adremover_community_guidelines_enabled_summary_on", - "Community guidelines are hidden" - ), - StringResource( - "revanced_adremover_community_guidelines_enabled_summary_off", - "Community guidelines are shown" - ) - ), - SwitchPreference( - "revanced_adremover_subscribers_community_guidelines_removal", - StringResource( - "revanced_adremover_subscribers_community_guidelines_enabled_title", - "Hide subscribers community guidelines" - ), - true, - StringResource( - "revanced_adremover_subscribers_community_guidelines_enabled_summary_on", - "Subscribers community guidelines are hidden" - ), - StringResource( - "revanced_adremover_subscribers_community_guidelines_enabled_summary_off", - "Subscribers community guidelines are shown" - ) - ), - SwitchPreference( - "revanced_adremover_channel_member_shelf_removal", - StringResource("revanced_adremover_channel_member_shelf_enabled_title", "Hide channel member shelf"), - true, - StringResource( - "revanced_adremover_channel_member_shelf_enabled_summary_on", - "Channel member shelf is hidden" - ), - StringResource( - "revanced_adremover_channel_member_shelf_enabled_summary_off", - "Channel member shelf is shown" - ) - ), - SwitchPreference( - "revanced_adremover_emergency_box_removal", - StringResource("revanced_adremover_emergency_box_enabled_title", "Hide emergency boxes"), - true, - StringResource("revanced_adremover_emergency_box_enabled_summary_on", "Emergency boxes are hidden"), - StringResource("revanced_adremover_emergency_box_enabled_summary_off", "Emergency boxes are shown") - ), - SwitchPreference( - "revanced_adremover_info_panel", - StringResource("revanced_adremover_info_panel_enabled_title", "Hide info panels"), - true, - StringResource("revanced_adremover_info_panel_enabled_summary_on", "Info panels are hidden"), - StringResource("revanced_adremover_info_panel_enabled_summary_off", "Info panels are shown") - ), - SwitchPreference( - "revanced_adremover_medical_panel", - StringResource("revanced_adremover_medical_panel_enabled_title", "Hide medical panels"), - true, - StringResource("revanced_adremover_medical_panel_enabled_summary_on", "Medical panels are hidden"), - StringResource("revanced_adremover_medical_panel_enabled_summary_off", "Medical panels are shown") - ), - SwitchPreference( - "revanced_hide_channel_bar", - StringResource("revanced_hide_channel_bar_title", "Hide channel bar"), - false, - StringResource("revanced_hide_channel_bar_summary_on", "Channel bar is hidden"), - StringResource("revanced_hide_channel_bar_summary_off", "Channel bar is shown") - ), - SwitchPreference( - "revanced_hide_quick_actions", - StringResource("revanced_hide_quick_actions_title", "Hide quick actions in fullscreen"), - false, - StringResource("revanced_hide_quick_actions_summary_on", "Quick actions are hidden"), - StringResource("revanced_hide_quick_actions_summary_off", "Quick actions are shown") - ), - SwitchPreference( - "revanced_hide_related_videos", - StringResource("revanced_hide_related_videos_title", "Hide related videos in quick actions"), - false, - StringResource("revanced_hide_related_videos_summary_on", "Related videos are hidden"), - StringResource("revanced_hide_related_videos_summary_off", "Related videos are shown") - ), - SwitchPreference( - "revanced_hide_image_shelf", - StringResource("revanced_hide_image_shelf", "Hide image shelf in search results"), - true, - StringResource("revanced_hide_image_shelf_summary_on", "Image shelf is hidden"), - StringResource("revanced_hide_image_shelf_summary_off", "Image shelf is shown") - ), - SwitchPreference( - "revanced_hide_audio_track_button", - StringResource("revanced_hide_audio_track_button_title", "Hide audio track button"), - false, - StringResource("revanced_hide_audio_track_button_on", "Audio track button is hidden"), - StringResource("revanced_hide_audio_track_button_off", "Audio track button is shown") - ) - ) - - PreferenceScreen.ADS.addPreferences( - SwitchPreference( - "revanced_adremover_ad_removal", - StringResource("revanced_adremover_ad_removal_enabled_title", "Hide general ads"), - true, - StringResource("revanced_adremover_ad_removal_enabled_summary_on", "General ads are hidden"), - StringResource("revanced_adremover_ad_removal_enabled_summary_off", "General ads are shown") - ), - SwitchPreference( - "revanced_adremover_buttoned", - StringResource("revanced_adremover_buttoned_enabled_title", "Hide buttoned ad"), - true, - StringResource("revanced_adremover_buttoned_enabled_summary_on", "Buttoned ads are hidden"), - StringResource("revanced_adremover_buttoned_enabled_summary_off", "Buttoned ads are shown") - ), - SwitchPreference( - "revanced_adremover_paid_content", - StringResource("revanced_adremover_paid_content_enabled_title", "Hide paid content"), - true, - StringResource("revanced_adremover_paid_content_enabled_summary_on", "Paid content is hidden"), - StringResource("revanced_adremover_paid_content_enabled_summary_off", "Paid content is shown") - ), - SwitchPreference( - "revanced_adremover_hide_latest_posts", - StringResource("revanced_adremover_hide_latest_posts_enabled_title", "Hide latest posts"), - true, - StringResource("revanced_adremover_hide_latest_posts_enabled_summary_on", "Latest posts are hidden"), - StringResource("revanced_adremover_hide_latest_posts_enabled_summary_off", "Latest posts are shown") - ), - SwitchPreference( - "revanced_adremover_self_sponsor", - StringResource("revanced_adremover_self_sponsor_enabled_title", "Hide self sponsored cards"), - true, - StringResource("revanced_adremover_self_sponsor_enabled_summary_on", "Self sponsored cards are hidden"), - StringResource("revanced_adremover_self_sponsor_enabled_summary_off", "Self sponsored cards are shown") - ), - PreferenceScreen( - "revanced_adremover_custom", - StringResource("revanced_adremover_custom_title", "Custom filter"), - listOf( - SwitchPreference( - "revanced_adremover_custom_enabled", - StringResource( - "revanced_adremover_custom_enabled_title", - "Enable custom filter" - ), - false, - StringResource( - "revanced_adremover_custom_enabled_summary_on", - "Custom filter is enabled" - ), - StringResource( - "revanced_adremover_custom_enabled_summary_off", - "Custom filter is disabled" - ) - ), - // TODO: This should be a dynamic ListPreference, which does not exist yet - TextPreference( - "revanced_adremover_custom_strings", - StringResource("revanced_adremover_custom_strings_title", "Custom filter"), - InputType.STRING, - "", - StringResource( - "revanced_adremover_custom_strings_summary", - "Filter components by their name separated by a comma" - ) - ) - ) - ) - ) - - fun String.getId() = ResourceMappingPatch.resourceMappings.single { it.name == this }.id - - adAttributionId = "ad_attribution".getId() - reelMultipleItemShelfId = "reel_multiple_items_shelf".getId() - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt deleted file mode 100644 index 2bc4ce2df..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.ad.video.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class VideoAdsCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/fingerprints/LoadVideoAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/fingerprints/LoadVideoAdsFingerprint.kt deleted file mode 100644 index b5a4c70e9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/fingerprints/LoadVideoAdsFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.ad.video.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object LoadVideoAdsFingerprint : MethodFingerprint( - strings = listOf( - "TriggerBundle doesn't have the required metadata specified by the trigger ", - "Tried to enter slot with no assigned slotAdapter", - "Trying to enter a slot when a slot of same type and physical position is already active. Its status: ", - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/patch/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/patch/VideoAdsPatch.kt deleted file mode 100644 index 10e14d39d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/patch/VideoAdsPatch.kt +++ /dev/null @@ -1,57 +0,0 @@ -package app.revanced.patches.youtube.ad.video.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.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.ad.video.annotations.VideoAdsCompatibility -import app.revanced.patches.youtube.ad.video.fingerprints.LoadVideoAdsFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("video-ads") -@Description("Removes ads in the video player.") -@VideoAdsCompatibility -@Version("0.0.1") -class VideoAdsPatch : BytecodePatch( - listOf( - LoadVideoAdsFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.ADS.addPreferences( - SwitchPreference( - "revanced_video_ads_removal", - StringResource("revanced_video_ads_removal_title", "Hide video ads"), - true, - StringResource("revanced_video_ads_removal_summary_on", "Video ads are hidden"), - StringResource("revanced_video_ads_removal_summary_off", "Video ads are shown") - ) - ) - - val loadVideoAdsFingerprintMethod = LoadVideoAdsFingerprint.result!!.mutableMethod - - loadVideoAdsFingerprintMethod.addInstructions( - 0, """ - invoke-static { }, Lapp/revanced/integrations/patches/VideoAdsPatch;->shouldShowAds()Z - move-result v0 - if-nez v0, :show_video_ads - return-void - """, listOf(ExternalLabel("show_video_ads", loadVideoAdsFingerprintMethod.instruction(0))) - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt deleted file mode 100644 index 4f4e524b0..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.interaction.copyvideourl.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class CopyVideoUrlCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/bytecode/patch/CopyVideoUrlBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/bytecode/patch/CopyVideoUrlBytecodePatch.kt deleted file mode 100644 index c015612a4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/bytecode/patch/CopyVideoUrlBytecodePatch.kt +++ /dev/null @@ -1,49 +0,0 @@ -package app.revanced.patches.youtube.interaction.copyvideourl.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.interaction.copyvideourl.annotation.CopyVideoUrlCompatibility -import app.revanced.patches.youtube.interaction.copyvideourl.resource.patch.CopyVideoUrlResourcePatch -import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch -import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch - -@Patch -@Name("copy-video-url") -@Description("Adds buttons in player to copy video links.") -@DependsOn([ - CopyVideoUrlResourcePatch::class, - PlayerControlsBytecodePatch::class, - VideoInformationPatch::class -]) -@CopyVideoUrlCompatibility -@Version("0.0.1") -class CopyVideoUrlBytecodePatch : BytecodePatch() { - private companion object { - const val INTEGRATIONS_PACKAGE = "Lapp/revanced/integrations" - const val INTEGRATIONS_PLAYER_PACKAGE = "$INTEGRATIONS_PACKAGE/videoplayer" - val BUTTONS_DESCRIPTORS = listOf( - "$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlButton;", - "$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlTimestampButton;" - ) - } - - override fun execute(context: BytecodeContext): PatchResult { - - // Initialize buttons and inject visibility control - BUTTONS_DESCRIPTORS.forEach { descriptor -> - val initializeButtonDescriptor = "$descriptor->initializeButton(Ljava/lang/Object;)V" - val visibilityDescriptor = "$descriptor->changeVisibility(Z)V" - PlayerControlsBytecodePatch.initializeControl(initializeButtonDescriptor) - PlayerControlsBytecodePatch.injectVisibilityCheckCall(visibilityDescriptor) - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt deleted file mode 100644 index 6e60282cd..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.revanced.patches.youtube.interaction.copyvideourl.resource.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -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.impl.SwitchPreference -import app.revanced.patches.youtube.interaction.copyvideourl.annotation.CopyVideoUrlCompatibility -import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources - -@Name("copy-video-url-resource") -@Description("Makes necessary changes to resources for copy video link buttons.") -@DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class]) -@CopyVideoUrlCompatibility -@Version("0.0.1") -class CopyVideoUrlResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( - PreferenceScreen( - "revanced_copy_video_url", - StringResource("revanced_copy_video_url_title", "Copy video URL settings"), - listOf( - SwitchPreference( - "revanced_copy_video_url_enabled", - StringResource("revanced_copy_video_url_enabled_title", "Show copy video URL button"), - true, - StringResource("revanced_copy_video_url_enabled_summary_on", "Button is shown, click to copy video URL without timestamp"), - StringResource("revanced_copy_video_url_enabled_summary_off", "Button is not shown") - ), - SwitchPreference( - "revanced_copy_video_url_timestamp_enabled", - StringResource("revanced_copy_video_url_timestamp_enabled_title", "Show copy timestamp URL button"), - true, - StringResource("revanced_copy_video_url_timestamp_enabled_summary_on", "Button is shown, click to copy video URL with timestamp"), - StringResource("revanced_copy_video_url_timestamp_enabled_summary_off", "Button is not shown") - ) - ), - StringResource("revanced_copy_video_url_summary", "Settings related to copy URL buttons in video player") - ) - ) - - context.copyResources("copyvideourl", ResourceUtils.ResourceGroup( - resourceDirectoryName = "drawable", - "revanced_yt_copy.xml", - "revanced_yt_copy_timestamp.xml" - )) - - BottomControlsResourcePatch.addControls("copyvideourl/host/layout/${BottomControlsResourcePatch.TARGET_RESOURCE_NAME}") - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/DownloadsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/DownloadsCompatibility.kt deleted file mode 100644 index 7d0d31281..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/DownloadsCompatibility.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.interaction.downloads.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class DownloadsCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/bytecode/patch/DownloadsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/bytecode/patch/DownloadsBytecodePatch.kt deleted file mode 100644 index 244dbeadf..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/bytecode/patch/DownloadsBytecodePatch.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.youtube.interaction.downloads.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.interaction.downloads.annotation.DownloadsCompatibility -import app.revanced.patches.youtube.interaction.downloads.resource.patch.DownloadsResourcePatch -import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch -import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch - -@Patch -@Name("downloads") -@DependsOn([DownloadsResourcePatch::class, PlayerControlsBytecodePatch::class, VideoInformationPatch::class]) -@Description("Enables downloading music and videos from YouTube.") -@DownloadsCompatibility -@Version("0.0.1") -class DownloadsBytecodePatch : BytecodePatch() { - override fun execute(context: BytecodeContext): PatchResult { - val integrationsPackage = "app/revanced/integrations" - val classDescriptor = "L$integrationsPackage/videoplayer/DownloadButton;" - - /* - initialize the control - */ - - val initializeDownloadsDescriptor = "$classDescriptor->initializeButton(Ljava/lang/Object;)V" - PlayerControlsBytecodePatch.initializeControl(initializeDownloadsDescriptor) - - /* - add code to change the visibility of the control - */ - - val changeVisibilityDescriptor = "$classDescriptor->changeVisibility(Z)V" - PlayerControlsBytecodePatch.injectVisibilityCheckCall(changeVisibilityDescriptor) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/resource/patch/DownloadsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/resource/patch/DownloadsResourcePatch.kt deleted file mode 100644 index f628f4d0c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/resource/patch/DownloadsResourcePatch.kt +++ /dev/null @@ -1,71 +0,0 @@ -package app.revanced.patches.youtube.interaction.downloads.resource.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.settings.preference.impl.* -import app.revanced.patches.youtube.interaction.downloads.annotation.DownloadsCompatibility -import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources -import app.revanced.util.resources.ResourceUtils.mergeStrings - -@Name("downloads-resource-patch") -@DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class]) -@Description("Makes necessary changes to resources for the download button.") -@DownloadsCompatibility -@Version("0.0.1") -class DownloadsResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( - PreferenceScreen( - "revanced_downloads", - StringResource("revanced_downloads_title", "Download settings"), - listOf( - SwitchPreference( - "revanced_downloads_enabled", - StringResource("revanced_downloads_enabled_title", "Show download button"), - true, - StringResource("revanced_downloads_enabled_summary_on", "Download button is shown"), - StringResource("revanced_downloads_enabled_summary_off", "Download button is not shown") - ), - TextPreference( - "revanced_downloads_package_name", - StringResource("revanced_downloads_package_name_title", "Downloader package name"), - InputType.STRING, - "org.schabi.newpipe" /* NewPipe */, - StringResource("revanced_downloads_package_name_summary", "Package name of the downloader app such as NewPipe\\'s or PowerTube\\'s") - ) - ), - StringResource("revanced_downloads_summary", "Settings related to downloads") - ) - ) - - - /* - * Copy strings - */ - - context.mergeStrings("downloads/host/values/strings.xml") - - /* - * Copy resources - */ - - context.copyResources("downloads", ResourceUtils.ResourceGroup("drawable", "revanced_yt_download_button.xml")) - - /* - * Add download button node - */ - - BottomControlsResourcePatch.addControls("downloads/host/layout/${BottomControlsResourcePatch.TARGET_RESOURCE_NAME}") - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt deleted file mode 100644 index c85c1bf7a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.interaction.seekbar.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class SeekbarTappingCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingFingerprint.kt deleted file mode 100644 index 94d6b2cef..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingFingerprint.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.youtube.interaction.seekbar.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object SeekbarTappingFingerprint : MethodFingerprint( - "Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_WIDE, - Opcode.IGET, - Opcode.IGET_OBJECT, - Opcode.IGET, - Opcode.DIV_INT_2ADDR, - Opcode.ADD_INT, - Opcode.SUB_INT_2ADDR, - Opcode.INT_TO_FLOAT, - Opcode.CMPG_FLOAT, - Opcode.IF_GTZ, - Opcode.INT_TO_FLOAT, - Opcode.CMPG_FLOAT, - Opcode.IF_GTZ, - Opcode.CONST_4, - Opcode.INVOKE_INTERFACE, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.INVOKE_VIRTUAL - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingParentFingerprint.kt deleted file mode 100644 index 20f83effb..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/fingerprints/SeekbarTappingParentFingerprint.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.youtube.interaction.seekbar.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object SeekbarTappingParentFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_4, - Opcode.NEW_ARRAY, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_WIDE, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_4, - Opcode.APUT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_WIDE, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_4, - Opcode.APUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.RETURN_OBJECT - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt deleted file mode 100644 index fed792408..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt +++ /dev/null @@ -1,110 +0,0 @@ -package app.revanced.patches.youtube.interaction.seekbar.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility -import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingFingerprint -import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingParentFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction21t -import org.jf.dexlib2.iface.Method -import org.jf.dexlib2.iface.instruction.formats.Instruction11n -import org.jf.dexlib2.iface.instruction.formats.Instruction35c - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("seekbar-tapping") -@Description("Enables tap-to-seek on the seekbar of the video player.") -@SeekbarTappingCompatibility -@Version("0.0.1") -class EnableSeekbarTappingPatch : BytecodePatch( - listOf( - SeekbarTappingParentFingerprint, SeekbarTappingFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( - SwitchPreference( - "revanced_enable_tap_seeking", - StringResource("revanced_seekbar_tapping_enabled_title", "Enable seekbar tapping"), - true, - StringResource("revanced_seekbar_tapping_summary_on", "Seekbar tapping is enabled"), - StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled") - ) - ) - - var result = SeekbarTappingParentFingerprint.result!! - - val tapSeekMethods = mutableMapOf() - - // find the methods which tap the seekbar - for (it in result.classDef.methods) { - if (it.implementation == null) continue - - val instructions = it.implementation!!.instructions - // here we make sure we actually find the method because it has more than 7 instructions - if (instructions.count() < 7) continue - - // we know that the 7th instruction has the opcode CONST_4 - val instruction = instructions.elementAt(6) - if (instruction.opcode != Opcode.CONST_4) continue - - // the literal for this instruction has to be either 1 or 2 - val literal = (instruction as Instruction11n).narrowLiteral - - // method founds - if (literal == 1) tapSeekMethods["P"] = it - if (literal == 2) tapSeekMethods["O"] = it - } - - // replace map because we don't need the upper one anymore - result = SeekbarTappingFingerprint.result!! - - val implementation = result.mutableMethod.implementation!! - - // if tap-seeking is enabled, do not invoke the two methods below - val pMethod = tapSeekMethods["P"]!! - val oMethod = tapSeekMethods["O"]!! - - val insertIndex = result.scanResult.patternScanResult!!.endIndex + 1 - - // get the required register - val instruction = implementation.instructions[insertIndex - 1] - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) return PatchResultError("Could not find the correct register") - val register = (instruction as Instruction35c).registerC - - val elseLabel = implementation.newLabelForIndex(insertIndex) - // the instructions are written in reverse order. - result.mutableMethod.addInstructions( - insertIndex, """ - invoke-virtual { v$register, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V - invoke-virtual { v$register, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V - """ - ) - - // if tap-seeking is disabled, do not invoke the two methods above by jumping to the else label - implementation.addInstruction( - insertIndex, BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel) - ) - result.mutableMethod.addInstructions( - insertIndex, """ - invoke-static { }, Lapp/revanced/integrations/patches/SeekbarTappingPatch;->isTapSeekingEnabled()Z - move-result v0 - """ - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt deleted file mode 100644 index 5def19efa..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.interaction.swipecontrols.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class SwipeControlsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/fingerprints/SwipeControlsHostActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/fingerprints/SwipeControlsHostActivityFingerprint.kt deleted file mode 100644 index 25e3ada23..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/fingerprints/SwipeControlsHostActivityFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.interaction.swipecontrols.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SwipeControlsHostActivityFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;" && methodDef.name == "" - } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/patch/bytecode/SwipeControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/patch/bytecode/SwipeControlsBytecodePatch.kt deleted file mode 100644 index 22f94b83f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/patch/bytecode/SwipeControlsBytecodePatch.kt +++ /dev/null @@ -1,68 +0,0 @@ -package app.revanced.patches.youtube.interaction.swipecontrols.patch.bytecode - -import app.revanced.extensions.transformMethods -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.TypeUtil.traverseClassHierarchy -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patches.shared.fingerprints.WatchWhileActivityFingerprint -import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility -import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.SwipeControlsHostActivityFingerprint -import app.revanced.patches.youtube.interaction.swipecontrols.patch.resource.SwipeControlsResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.immutable.ImmutableMethod - -@Patch -@Name("swipe-controls") -@Description("Adds volume and brightness swipe controls.") -@SwipeControlsCompatibility -@Version("0.0.3") -@DependsOn( - [ - IntegrationsPatch::class, - PlayerTypeHookPatch::class, - SwipeControlsResourcePatch::class - ] -) -class SwipeControlsBytecodePatch : BytecodePatch( - listOf( - WatchWhileActivityFingerprint, - SwipeControlsHostActivityFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass - val targetClass = WatchWhileActivityFingerprint.result!!.mutableClass - - // inject the wrapper class from integrations into the class hierarchy of WatchWhileActivity - wrapperClass.setSuperClass(targetClass.superclass) - targetClass.setSuperClass(wrapperClass.type) - - // ensure all classes and methods in the hierarchy are non-final, so we can override them in integrations - context.traverseClassHierarchy(targetClass) { - accessFlags = accessFlags and AccessFlags.FINAL.value.inv() - transformMethods { - ImmutableMethod( - definingClass, - name, - parameters, - returnType, - accessFlags and AccessFlags.FINAL.value.inv(), - annotations, - hiddenApiRestrictions, - implementation - ).toMutable() - } - } - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/patch/resource/SwipeControlsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/patch/resource/SwipeControlsResourcePatch.kt deleted file mode 100644 index 01cfffd5d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/patch/resource/SwipeControlsResourcePatch.kt +++ /dev/null @@ -1,111 +0,0 @@ -package app.revanced.patches.youtube.interaction.swipecontrols.patch.resource - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -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.impl.SwitchPreference -import app.revanced.patches.shared.settings.preference.impl.TextPreference -import app.revanced.patches.shared.settings.preference.impl.InputType -import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources - -@Name("swipe-controls-resource-patch") -@DependsOn([SettingsPatch::class]) -@SwipeControlsCompatibility -@Version("0.0.1") -class SwipeControlsResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( - PreferenceScreen( - "revanced_swipe_controls", StringResource("revanced_swipe_controls_title", "Swipe controls"), listOf( - SwitchPreference( - "revanced_enable_swipe_brightness", - StringResource("revanced_swipe_brightness_enabled_title", "Enable brightness gesture"), - true, - StringResource("revanced_swipe_brightness_summary_on", "Brightness swipe is enabled"), - StringResource("revanced_swipe_brightness_summary_off", "Brightness swipe is disabled") - ), - SwitchPreference( - "revanced_enable_swipe_volume", - StringResource("revanced_swipe_volume_enabled_title", "Enable volume gesture"), - true, - StringResource("revanced_swipe_volume_summary_on", "Volume swipe is enabled"), - StringResource("revanced_swipe_volume_summary_off", "Volume swipe is disabled") - ), - SwitchPreference( - "revanced_enable_press_to_swipe", - StringResource("revanced_press_to_swipe_enabled_title", "Enable press-to-swipe gesture"), - false, - StringResource("revanced_press_to_swipe_summary_on", "Press-to-swipe is enabled"), - StringResource("revanced_press_to_swipe_summary_off", "Press-to-swipe is disabled") - ), - SwitchPreference( - "revanced_enable_swipe_haptic_feedback", - StringResource("revanced_swipe_haptic_feedback_enabled_title", "Enable haptic feedback"), - true, - StringResource("revanced_swipe_haptic_feedback_summary_on", "Haptic feedback is enabled"), - StringResource("revanced_swipe_haptic_feedback_summary_off", "Haptic feedback is disabled") - ), - TextPreference( - "revanced_swipe_overlay_timeout", - StringResource("revanced_swipe_overlay_timeout_title", "Swipe overlay timeout"), - InputType.NUMBER, - "500", - StringResource( - "revanced_swipe_overlay_timeout_summary", - "The amount of milliseconds the overlay is visible" - ) - ), - TextPreference( - "revanced_swipe_overlay_text_size", - StringResource("revanced_swipe_overlay_text_size_title", "Swipe overlay text size"), - InputType.NUMBER, - "22", - StringResource("revanced_swipe_overlay_text_size_summary", "The text size for swipe overlay") - ), - TextPreference( - "revanced_swipe_overlay_background_alpha", - StringResource("revanced_swipe_overlay_background_alpha_title", "Swipe background visibility"), - InputType.NUMBER, - "127", - StringResource( - "revanced_swipe_overlay_background_alpha_summary", - "The visibility of swipe overlay background" - ) - ), - TextPreference( - "revanced_swipe_magnitude_threshold", - StringResource("revanced_swipe_magnitude_threshold_title", "Swipe magnitude threshold"), - InputType.NUMBER, - "30", - StringResource( - "revanced_swipe_magnitude_threshold_summary", - "The amount of threshold for swipe to occur" - ) - ) - ), - StringResource("revanced_swipe_controls_summary","Control volume and brightness") - ) - ) - - context.copyResources( - "swipecontrols", - ResourceUtils.ResourceGroup( - "drawable", - "ic_sc_brightness_auto.xml", - "ic_sc_brightness_manual.xml", - "ic_sc_volume_mute.xml", - "ic_sc_volume_normal.xml" - ) - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt deleted file mode 100644 index ac4e86824..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.autocaptions.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class AutoCaptionsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt deleted file mode 100644 index e65c2b74f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.revanced.patches.youtube.layout.autocaptions.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(3) -object StartVideoInformerFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L", "L", "L"), listOf( - Opcode.INVOKE_STATIC, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_INTERFACE, - Opcode.IF_EQZ, - Opcode.CONST_STRING, - Opcode.INVOKE_INTERFACE, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.CONST_4, - Opcode.IF_EQ, - Opcode.GOTO, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt deleted file mode 100644 index d42965f73..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.youtube.layout.autocaptions.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object SubtitleButtonControllerFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.RETURN_VOID, - Opcode.IGET_BOOLEAN, - Opcode.CONST_4, - Opcode.IF_NEZ, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt deleted file mode 100644 index a011e60c2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.youtube.layout.autocaptions.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object SubtitleTrackFingerprint : MethodFingerprint( - "Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.CONST_STRING, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.RETURN, - ), - strings = listOf("DISABLE_CAPTIONS_OPTION") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/patch/AutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/patch/AutoCaptionsPatch.kt deleted file mode 100644 index 25e3e8521..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/patch/AutoCaptionsPatch.kt +++ /dev/null @@ -1,80 +0,0 @@ -package app.revanced.patches.youtube.layout.autocaptions.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.autocaptions.fingerprints.StartVideoInformerFingerprint -import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleButtonControllerFingerprint -import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleTrackFingerprint -import app.revanced.patches.youtube.layout.buttons.captions.annotations.HideCaptionsButtonCompatibility -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("disable-auto-captions") -@Description("Disable forced captions from being automatically enabled.") -@HideCaptionsButtonCompatibility -@Version("0.0.1") -class AutoCaptionsPatch : BytecodePatch( - listOf( - StartVideoInformerFingerprint, SubtitleButtonControllerFingerprint, SubtitleTrackFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_autocaptions_enabled", - StringResource("revanced_autocaptions_enabled_title", "Disable auto captions"), - false, - StringResource("revanced_autocaptions_summary_on", "Auto captions are disabled"), - StringResource("revanced_autocaptions_summary_off", "Auto captions are enabled") - ) - ) - - val startVideoInformerMethod = StartVideoInformerFingerprint.result!!.mutableMethod - - startVideoInformerMethod.addInstructions( - 0, """ - const/4 v0, 0x0 - sput-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z - """ - ) - - val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod - - subtitleButtonControllerMethod.addInstructions( - 0, """ - const/4 v0, 0x1 - sput-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z - """ - ) - - val subtitleTrackMethod = SubtitleTrackFingerprint.result!!.mutableMethod - - subtitleTrackMethod.addInstructions( - 0, """ - invoke-static {}, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->autoCaptionsEnabled()Z - move-result v0 - if-eqz v0, :auto_captions_enabled - sget-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z - if-nez v0, :auto_captions_enabled - const/4 v0, 0x1 - return v0 - :auto_captions_enabled - nop - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/annotations/PremiumHeadingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/annotations/PremiumHeadingCompatibility.kt deleted file mode 100644 index c021de553..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/annotations/PremiumHeadingCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.branding.header.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class PremiumHeadingCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/patch/PremiumHeadingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/patch/PremiumHeadingPatch.kt deleted file mode 100644 index 2d358f79c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/patch/PremiumHeadingPatch.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.youtube.layout.branding.header.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility -import java.nio.file.Files -import java.nio.file.StandardCopyOption -import kotlin.io.path.exists - -@Patch -@Name("premium-heading") -@Description("Shows premium branding on the home screen.") -@PremiumHeadingCompatibility -@Version("0.0.1") -class PremiumHeadingPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - val resDirectory = context["res"] - if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.") - - val (original, replacement) = "yt_premium_wordmark_header" to "yt_wordmark_header" - val modes = arrayOf("light", "dark") - - arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi").forEach { size -> - val headingDirectory = resDirectory.resolve("drawable-$size") - modes.forEach { mode -> - val fromPath = headingDirectory.resolve("${original}_$mode.png").toPath() - val toPath = headingDirectory.resolve("${replacement}_$mode.png").toPath() - - if (!fromPath.exists()) - return PatchResultError("The file $fromPath does not exist in the resources. Therefore, this patch can not succeed.") - Files.copy( - fromPath, - toPath, - StandardCopyOption.REPLACE_EXISTING - ) - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/annotations/CustomBrandingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/annotations/CustomBrandingCompatibility.kt deleted file mode 100644 index ec6b73b27..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/annotations/CustomBrandingCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.branding.icon.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class CustomBrandingCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/patch/CustomBrandingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/patch/CustomBrandingPatch.kt deleted file mode 100644 index f9d93d4cd..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/patch/CustomBrandingPatch.kt +++ /dev/null @@ -1,91 +0,0 @@ -package app.revanced.patches.youtube.layout.branding.icon.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources -import java.io.File -import java.nio.file.Files - -@Patch -@Name("custom-branding") -@Description("Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).") -@CustomBrandingCompatibility -@Version("0.0.1") -class CustomBrandingPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - fun copyResources(resourceGroups: List) { - iconPath?.let { iconPathString -> - val iconPath = File(iconPathString) - val resourceDirectory = context["res"] - - resourceGroups.forEach { group -> - val fromDirectory = iconPath.resolve(group.resourceDirectoryName) - val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName) - - group.resources.forEach { iconFileName -> - Files.write( - toDirectory.resolve(iconFileName).toPath(), - fromDirectory.resolve(iconFileName).readBytes() - ) - } - } - } ?: resourceGroups.forEach { context.copyResources("branding", it) } - } - - val iconResourceFileNames = arrayOf( - "adaptiveproduct_youtube_background_color_108", - "adaptiveproduct_youtube_foreground_color_108", - "ic_launcher", - "ic_launcher_round" - ).map { "$it.png" }.toTypedArray() - - fun createGroup(directory: String) = ResourceUtils.ResourceGroup( - directory, *iconResourceFileNames - ) - - // change the app icon - arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi") - .map { "mipmap-$it" } - .map(::createGroup) - .let(::copyResources) - - // change the name of the app - val manifest = context["AndroidManifest.xml"] - manifest.writeText( - manifest.readText() - .replace( - "android:label=\"@string/application_name", - "android:label=\"$appName" - ) - ) - - return PatchResultSuccess() - } - - companion object : OptionsContainer() { - private var appName: String? by option( - PatchOption.StringOption( - key = "appName", - default = "YouTube ReVanced", - title = "Application Name", - description = "The name of the application it will show on your home screen.", - required = true - ) - ) - - private var iconPath: String? by option( - PatchOption.StringOption( - key = "iconPath", - default = null, - title = "App Icon Path", - description = "A path containing mipmap resource folders with icons." - ) - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt deleted file mode 100644 index 78c8fdd91..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.action.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideButtonsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt deleted file mode 100644 index cb2c94c04..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt +++ /dev/null @@ -1,76 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.action.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -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.impl.SwitchPreference -import app.revanced.patches.youtube.layout.buttons.action.annotations.HideButtonsCompatibility -import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([ResourceMappingPatch::class, LithoFilterPatch::class]) -@Name("hide-video-action-buttons") -@Description("Adds the options to hide action buttons under a video.") -@HideButtonsCompatibility -@Version("0.0.1") -class HideButtonsPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - PreferenceScreen( - "revanced_hide_buttons", - StringResource("revanced_hide_buttons_title", "Hide action buttons"), - listOf( - SwitchPreference( - "revanced_hide_like_dislike_button", - StringResource("revanced_hide_like_dislike_button_title", "Hide like and dislike buttons"), - false, - StringResource("revanced_hide_like_dislike_button_summary_on", "Like and dislike buttons are hidden"), - StringResource("revanced_hide_like_dislike_button_summary_off", "Like and dislike buttons are shown") - ), - SwitchPreference( - "revanced_hide_download_button", - StringResource("revanced_hide_download_button_title", "Hide download button"), - false, - StringResource("revanced_hide_download_button_summary_on", "Download button is hidden"), - StringResource("revanced_hide_download_button_summary_off", "Download button is shown") - ), - SwitchPreference( - "revanced_hide_playlist_button", - StringResource("revanced_hide_playlist_button_title", "Hide playlist button"), - false, - StringResource("revanced_hide_playlist_button_summary_on", "Playlist button is hidden"), - StringResource("revanced_hide_playlist_button_summary_off", "Playlist button is shown") - ), - SwitchPreference( - "revanced_hide_clip_button", - StringResource("revanced_hide_clip_button_title", "Hide clip button"), - false, - StringResource("revanced_hide_clip_button_summary_on", "Clip button is hidden"), - StringResource("revanced_hide_clip_button_summary_off", "Clip button is shown"), - StringResource("revanced_hide_clip_button_user_dialog_message", - "Hiding the clip button might not work reliably. In the case it does not work, it can only be hidden by enabling \\'Hide all other action buttons\\'") - ), - SwitchPreference( - "revanced_hide_action_buttons", - StringResource("revanced_hide_action_buttons_title", "Hide all other action buttons"), - false, - StringResource("revanced_hide_action_buttons_summary_on", "Share, remix, thanks, shop, live chat buttons are hidden"), - StringResource("revanced_hide_action_buttons_summary_off", "Share, remix, thanks, shop, live chat buttons are shown") - ) - ), - StringResource("revanced_hide_buttons_summary", "Hide or show buttons under videos") - ) - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt deleted file mode 100644 index 9f32c59f3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.autoplay.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class AutoplayButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/fingerprints/LayoutConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/fingerprints/LayoutConstructorFingerprint.kt deleted file mode 100644 index cc9c20ccc..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/fingerprints/LayoutConstructorFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object LayoutConstructorFingerprint : MethodFingerprint( - strings = listOf("1.0x"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("YouTubeControlsOverlay;") - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt deleted file mode 100644 index 2700bbad9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt +++ /dev/null @@ -1,86 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.autoplay.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.buttons.autoplay.annotations.AutoplayButtonCompatibility -import app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints.LayoutConstructorFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.iface.instruction.Instruction -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction -import org.jf.dexlib2.iface.reference.MethodReference - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class, ResourceMappingPatch::class]) -@Name("hide-autoplay-button") -@Description("Hides the autoplay button in the video player.") -@AutoplayButtonCompatibility -@Version("0.0.1") -class HideAutoplayButtonPatch : BytecodePatch( - listOf(LayoutConstructorFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_autoplay_button", - StringResource("revanced_hide_autoplay_button_title", "Hide autoplay button"), - true, - StringResource("revanced_hide_autoplay_button_summary_on", "Autoplay button is hidden"), - StringResource("revanced_hide_autoplay_button_summary_off", "Autoplay button is shown") - ), - ) - - LayoutConstructorFingerprint.result?.mutableMethod?.apply { - val layoutGenMethodInstructions = implementation!!.instructions - - // resolve the offsets such as ... - val autoNavPreviewStubId = ResourceMappingPatch.resourceMappings.single { - it.name == "autonav_preview_stub" - }.id - - // where to insert the branch instructions and ... - val insertIndex = layoutGenMethodInstructions.indexOfFirst { - (it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId - } - - // where to branch away - val branchIndex = - layoutGenMethodInstructions.subList(insertIndex + 1, layoutGenMethodInstructions.size - 1) - .indexOfFirst { - ((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "addOnLayoutChangeListener" - } + 2 - - val jumpInstruction = layoutGenMethodInstructions[insertIndex + branchIndex] as Instruction - - // can be clobbered because this register is overwritten after the injected code - val clobberRegister = (instruction(insertIndex) as OneRegisterInstruction).registerA - - addInstructions( - insertIndex, - """ - invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z - move-result v$clobberRegister - if-eqz v$clobberRegister, :hidden - """, listOf(ExternalLabel("hidden", jumpInstruction)) - ) - } ?: return LayoutConstructorFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt deleted file mode 100644 index 8069cab27..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.captions.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideCaptionsButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/patch/HideCaptionsButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/patch/HideCaptionsButtonPatch.kt deleted file mode 100644 index fcd7773be..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/patch/HideCaptionsButtonPatch.kt +++ /dev/null @@ -1,56 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.captions.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleButtonControllerFingerprint -import app.revanced.patches.youtube.layout.buttons.captions.annotations.HideCaptionsButtonCompatibility -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.Opcode - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-captions-button") -@Description("Hides the captions button on video player.") -@HideCaptionsButtonCompatibility -@Version("0.0.1") -class HideCaptionsButtonPatch : BytecodePatch(listOf( - SubtitleButtonControllerFingerprint, -)) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_captions_button", - StringResource("revanced_hide_captions_button_title", "Hide captions button"), - false, - StringResource("revanced_hide_captions_button_summary_on", "Captions button is hidden"), - StringResource("revanced_hide_captions_button_summary_off", "Captions button is shown") - ) - ) - - val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod - - // Due to previously applied patches, scanResult index cannot be used in this context - val igetBooleanIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst { - it.opcode == Opcode.IGET_BOOLEAN - } - - subtitleButtonControllerMethod.addInstructions( - igetBooleanIndex + 1, """ - invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/annotations/CastPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/annotations/CastPatchCompatibility.kt deleted file mode 100644 index 8aace1028..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/annotations/CastPatchCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.cast.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class CastButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/patch/HideCastButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/patch/HideCastButtonPatch.kt deleted file mode 100644 index 884e3adbc..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/cast/patch/HideCastButtonPatch.kt +++ /dev/null @@ -1,57 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.cast.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.buttons.cast.annotations.CastButtonCompatibility -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-cast-button") -@Description("Hides the cast button in the video player.") -@CastButtonCompatibility -@Version("0.0.1") -class HideCastButtonPatch : BytecodePatch() { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_cast_button", - StringResource("revanced_hide_cast_button_title", "Hide cast button"), - true, - StringResource("revanced_hide_cast_button_summary_on", "Cast button is hidden"), - StringResource("revanced_hide_cast_button_summary_off", "Cast button is shown") - ) - ) - - with( - context.findClass("MediaRouteButton") - ?: return PatchResultError("MediaRouteButton class not found.") - ) { - with( - mutableClass.methods.find { it.name == "setVisibility" } - ?: return PatchResultError("setVisibility method not found.") - ) { - addInstructions( - 0, """ - invoke-static {p1}, Lapp/revanced/integrations/patches/HideCastButtonPatch;->getCastButtonOverrideV2(I)I - move-result p1 - """ - ) - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/create/fingerprints/PivotBarCreateButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/create/fingerprints/PivotBarCreateButtonViewFingerprint.kt deleted file mode 100644 index 5e7e6d0e8..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/create/fingerprints/PivotBarCreateButtonViewFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.create.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object PivotBarCreateButtonViewFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.MOVE_OBJECT, - Opcode.INVOKE_DIRECT_RANGE, // unique instruction anchor - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/create/patch/CreateButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/create/patch/CreateButtonRemoverPatch.kt deleted file mode 100644 index ae37a4665..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/create/patch/CreateButtonRemoverPatch.kt +++ /dev/null @@ -1,79 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.create.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.buttons.pivotbar.create.fingerprints.PivotBarCreateButtonViewFingerprint -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.annotations.PivotBarCompatibility -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.fingerprints.InitializeButtonsFingerprint -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.patch.ResolvePivotBarFingerprintsPatch -import app.revanced.patches.youtube.layout.buttons.pivotbar.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT -import app.revanced.patches.youtube.layout.buttons.pivotbar.utils.InjectionUtils.injectHook -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.Opcode - -@Patch -@DependsOn([IntegrationsPatch::class, ResourceMappingPatch::class, SettingsPatch::class, ResolvePivotBarFingerprintsPatch::class]) -@Name("hide-create-button") -@Description("Hides the create button in the navigation bar.") -@PivotBarCompatibility -@Version("0.0.1") -class CreateButtonRemoverPatch : BytecodePatch() { - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/HideCreateButtonPatch;" - } - - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_create_button", - StringResource("revanced_hide_create_button_title", "Hide create button"), - true, - StringResource("revanced_hide_create_button_summary_on", "Create button is hidden"), - StringResource("revanced_hide_create_button_summary_off", "Create button is shown") - ) - ) - - /* - * Resolve fingerprints - */ - - InitializeButtonsFingerprint.result!!.let { - if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)) - return PivotBarCreateButtonViewFingerprint.toErrorResult() - } - - PivotBarCreateButtonViewFingerprint.result!!.apply { - val insertIndex = mutableMethod.implementation!!.instructions.let { - val scanStart = scanResult.patternScanResult!!.endIndex - - scanStart + it.subList(scanStart, it.size - 1).indexOfFirst { instruction -> - instruction.opcode == Opcode.INVOKE_STATIC - } - } - - /* - * Inject hooks - */ - val hook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " + - "$INTEGRATIONS_CLASS_DESCRIPTOR->hideCreateButton(Landroid/view/View;)V" - - mutableMethod.injectHook(hook, insertIndex) - } - - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/annotations/PivotBarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/annotations/PivotBarCompatibility.kt deleted file mode 100644 index 087005bb3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/annotations/PivotBarCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.shared.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class PivotBarCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/fingerprints/InitializeButtonsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/fingerprints/InitializeButtonsFingerprint.kt deleted file mode 100644 index 5c2d10162..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/fingerprints/InitializeButtonsFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.shared.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.patch.ResolvePivotBarFingerprintsPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object InitializeButtonsFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { - it.opcode == Opcode.CONST && (it as WideLiteralInstruction).wideLiteral == - ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/fingerprints/PivotBarConstructorFingerprint.kt deleted file mode 100644 index ad700d095..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/fingerprints/PivotBarConstructorFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.shared.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object PivotBarConstructorFingerprint : MethodFingerprint( - access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - strings = listOf("com.google.android.apps.youtube.app.endpoint.flags") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/patch/ResolvePivotBarFingerprintsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/patch/ResolvePivotBarFingerprintsPatch.kt deleted file mode 100644 index 1451f7a3e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/patch/ResolvePivotBarFingerprintsPatch.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.shared.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.annotations.PivotBarCompatibility -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.fingerprints.InitializeButtonsFingerprint -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.fingerprints.PivotBarConstructorFingerprint - -@DependsOn([ResourceMappingPatch::class]) -@PivotBarCompatibility -@Description("Resolves necessary fingerprints.") -@Version("0.0.1") -class ResolvePivotBarFingerprintsPatch : BytecodePatch( - listOf(PivotBarConstructorFingerprint) -) { - internal companion object { - var imageOnlyTabResourceId: Long = -1 - } - - override fun execute(context: BytecodeContext): PatchResult { - // imageOnlyTabResourceId is used in InitializeButtonsFingerprint fingerprint - ResourceMappingPatch.resourceMappings.find { it.type == "layout" && it.name == "image_only_tab" } - ?.let { imageOnlyTabResourceId = it.id } ?: return PatchResultError("Failed to find resource") - - PivotBarConstructorFingerprint.result?.let { - // Resolve InitializeButtonsFingerprint on the class of the method - // which PivotBarConstructorFingerprint resolved to - if (!InitializeButtonsFingerprint.resolve( - context, - it.classDef - ) - ) return InitializeButtonsFingerprint.toErrorResult() - } ?: return PivotBarConstructorFingerprint.toErrorResult() - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/fingerprints/PivotBarEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/fingerprints/PivotBarEnumFingerprint.kt deleted file mode 100644 index cee53db0a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/fingerprints/PivotBarEnumFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.shorts.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object PivotBarEnumFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_NEZ, // target reference - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/fingerprints/PivotBarShortsButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/fingerprints/PivotBarShortsButtonViewFingerprint.kt deleted file mode 100644 index e4309ad90..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/fingerprints/PivotBarShortsButtonViewFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.shorts.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object PivotBarShortsButtonViewFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL_RANGE, - Opcode.MOVE_RESULT_OBJECT, // target reference - Opcode.GOTO, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/patch/ShortsButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/patch/ShortsButtonRemoverPatch.kt deleted file mode 100644 index 47a34dcda..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shorts/patch/ShortsButtonRemoverPatch.kt +++ /dev/null @@ -1,93 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.shorts.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.annotations.PivotBarCompatibility -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.fingerprints.InitializeButtonsFingerprint -import app.revanced.patches.youtube.layout.buttons.pivotbar.shared.patch.ResolvePivotBarFingerprintsPatch -import app.revanced.patches.youtube.layout.buttons.pivotbar.shorts.fingerprints.PivotBarEnumFingerprint -import app.revanced.patches.youtube.layout.buttons.pivotbar.shorts.fingerprints.PivotBarShortsButtonViewFingerprint -import app.revanced.patches.youtube.layout.buttons.pivotbar.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT -import app.revanced.patches.youtube.layout.buttons.pivotbar.utils.InjectionUtils.injectHook -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class, ResolvePivotBarFingerprintsPatch::class]) -@Name("hide-shorts-button") -@Description("Hides the shorts button on the navigation bar.") -@PivotBarCompatibility -@Version("0.0.1") -class ShortsButtonRemoverPatch : BytecodePatch() { - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/HideShortsButtonPatch;" - } - - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_shorts_button", - StringResource("revanced_hide_shorts_button_title", "Hide shorts button"), - true, - StringResource("revanced_hide_shorts_button_summary_on", "Shorts button is hidden"), - StringResource("revanced_hide_shorts_button_summary_off", "Shorts button is shown") - ) - ) - - /* - * Resolve fingerprints - */ - - val initializeButtonsResult = InitializeButtonsFingerprint.result!! - - val fingerprintResults = - arrayOf(PivotBarEnumFingerprint, PivotBarShortsButtonViewFingerprint) - .onEach { - if (!it.resolve( - context, - initializeButtonsResult.mutableMethod, - initializeButtonsResult.mutableClass - ) - ) - return it.toErrorResult() - } - .map { it.result!!.scanResult.patternScanResult!! } - - - val enumScanResult = fingerprintResults[0] - val buttonViewResult = fingerprintResults[1] - - val enumHookInsertIndex = enumScanResult.startIndex + 2 - val buttonHookInsertIndex = buttonViewResult.endIndex - - /* - * Inject hooks - */ - - val enumHook = "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, " + - "$INTEGRATIONS_CLASS_DESCRIPTOR->lastPivotTab:Ljava/lang/Enum;" - val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " + - "$INTEGRATIONS_CLASS_DESCRIPTOR->hideShortsButton(Landroid/view/View;)V" - - // Inject bottom to top to not mess up the indices - mapOf( - buttonHook to buttonHookInsertIndex, - enumHook to enumHookInsertIndex - ).forEach { (hook, insertIndex) -> - initializeButtonsResult.mutableMethod.injectHook(hook, insertIndex) - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/utils/InjectionUtils.kt deleted file mode 100644 index b39f92aa2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/utils/InjectionUtils.kt +++ /dev/null @@ -1,30 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.pivotbar.utils - -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import org.jf.dexlib2.Opcode.MOVE_RESULT_OBJECT -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -internal object InjectionUtils { - const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX" - - /** - * Injects an instruction into insertIndex of the hook. - * @param hook The hook to insert. - * @param insertIndex The index to insert the instruction at. - * [MOVE_RESULT_OBJECT] has to be the previous instruction before [insertIndex]. - */ - fun MutableMethod.injectHook(hook: String, insertIndex: Int) { - val injectTarget = this - - // Register to pass to the hook - val registerIndex = insertIndex - 1 // MOVE_RESULT_OBJECT is always the previous instruction - val register = (injectTarget.instruction(registerIndex) as OneRegisterInstruction).registerA - - injectTarget.addInstruction( - insertIndex, - hook.replace("REGISTER_INDEX", register.toString()), - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/annotations/PlayerButtonBackgroundCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/annotations/PlayerButtonBackgroundCompatibility.kt deleted file mode 100644 index 92d2f756e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/annotations/PlayerButtonBackgroundCompatibility.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.player.background.annotations -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class PlayerButtonBackgroundCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/patch/PlayerButtonBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/patch/PlayerButtonBackgroundPatch.kt deleted file mode 100644 index b9951abd4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/patch/PlayerButtonBackgroundPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.player.background.patch - -import app.revanced.extensions.doRecursively -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.buttons.player.background.annotations.PlayerButtonBackgroundCompatibility -import org.w3c.dom.Element - -@Patch -@Name("remove-player-button-background") -@Description("Removes the background from the video player buttons.") -@PlayerButtonBackgroundCompatibility -@Version("0.0.1") -class PlayerButtonBackgroundPatch : ResourcePatch { - private companion object { - const val RESOURCE_FILE_PATH = "res/drawable/player_button_circle_background.xml" - } - - override fun execute(context: ResourceContext): PatchResult { - context.xmlEditor[RESOURCE_FILE_PATH].use { editor -> - editor.file.doRecursively node@{ node -> - if (node !is Element) return@node - - node.getAttributeNode("android:color")?.let { attribute -> - attribute.textContent = "@android:color/transparent" - } - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/annotations/HidePlayerButtonsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/annotations/HidePlayerButtonsCompatibility.kt deleted file mode 100644 index d2137b01c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/annotations/HidePlayerButtonsCompatibility.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.player.hide.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf() - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HidePlayerButtonsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/fingerprints/PlayerControlsVisibilityModelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/fingerprints/PlayerControlsVisibilityModelFingerprint.kt deleted file mode 100644 index 37f90e60c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/fingerprints/PlayerControlsVisibilityModelFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.player.hide.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object PlayerControlsVisibilityModelFingerprint : MethodFingerprint( - opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE), - strings = listOf("hasNext", "hasPrevious", "Missing required properties:") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/patch/HidePlayerButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/patch/HidePlayerButtonsPatch.kt deleted file mode 100644 index 1ea9cfbad..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/patch/HidePlayerButtonsPatch.kt +++ /dev/null @@ -1,74 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.player.hide.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.buttons.player.hide.annotations.HidePlayerButtonsCompatibility -import app.revanced.patches.youtube.layout.buttons.player.hide.fingerprints.PlayerControlsVisibilityModelFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.iface.instruction.formats.Instruction3rc - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-player-buttons") -@Description("Adds the option to hide video player previous and next buttons.") -@HidePlayerButtonsCompatibility -@Version("0.0.1") -class HidePlayerButtonsPatch : BytecodePatch( - listOf(PlayerControlsVisibilityModelFingerprint) -) { - private object ParameterOffsets { - const val HAS_NEXT = 5 - } - - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_player_buttons", - StringResource( - "revanced_hide_player_buttons_title", - "Hide previous & next video buttons" - ), - false, - StringResource( - "revanced_hide_player_buttons_summary_on", - "Buttons are hidden" - ), - StringResource( - "revanced_hide_player_buttons_summary_off", - "Buttons are shown" - ) - ) - ) - - PlayerControlsVisibilityModelFingerprint.result?.apply { - val callIndex = scanResult.patternScanResult!!.endIndex - val callInstruction = mutableMethod.instruction(callIndex) as Instruction3rc - - // overriding this parameter register hides the previous and next buttons - val hasNextParameterRegister = callInstruction.startRegister + ParameterOffsets.HAS_NEXT - - mutableMethod.addInstructions( - callIndex, - """ - invoke-static { }, Lapp/revanced/integrations/patches/HidePlayerButtonsPatch;->hideButtons()Z - move-result v$hasNextParameterRegister - xor-int/lit8 v$hasNextParameterRegister, v$hasNextParameterRegister, 1 - """ - ) - } ?: return PlayerControlsVisibilityModelFingerprint.toErrorResult() - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt deleted file mode 100644 index b89120ae4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.albumcards.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class AlbumCardsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/fingerprints/AlbumCardsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/fingerprints/AlbumCardsFingerprint.kt deleted file mode 100644 index 79874b37a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/fingerprints/AlbumCardsFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.albumcards.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.albumcards.resource.patch.AlbumCardsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object AlbumCardsFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == AlbumCardsResourcePatch.albumCardId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/patch/AlbumCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/patch/AlbumCardsPatch.kt deleted file mode 100644 index f9ae2950e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/bytecode/patch/AlbumCardsPatch.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.albumcards.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.albumcards.annotations.AlbumCardsCompatibility -import app.revanced.patches.youtube.layout.hide.albumcards.bytecode.fingerprints.AlbumCardsFingerprint -import app.revanced.patches.youtube.layout.hide.albumcards.resource.patch.AlbumCardsResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, AlbumCardsResourcePatch::class]) -@Name("hide-album-cards") -@Description("Hides the album cards below the artist description.") -@AlbumCardsCompatibility -@Version("0.0.1") -class AlbumCardsPatch : BytecodePatch( - listOf( - AlbumCardsFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val albumCardsResult = AlbumCardsFingerprint.result!! - val albumCardsMethod = albumCardsResult.mutableMethod - - val checkCastAnchorIndex = albumCardsResult.scanResult.patternScanResult!!.endIndex - - albumCardsMethod.addInstruction( - checkCastAnchorIndex + 1, """ - invoke-static {v${(albumCardsMethod.instruction(checkCastAnchorIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideAlbumCardsPatch;->hideAlbumCards(Landroid/view/View;)V - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/resource/patch/AlbumCardsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/resource/patch/AlbumCardsResourcePatch.kt deleted file mode 100644 index 50621ee06..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/resource/patch/AlbumCardsResourcePatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.albumcards.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.albumcards.annotations.AlbumCardsCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Name("hide-album-cards-resource-patch") -@AlbumCardsCompatibility -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class AlbumCardsResourcePatch : ResourcePatch { - companion object { - internal var albumCardId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_album_cards", - StringResource("revanced_hide_album_cards_title", "Hide album cards"), - false, - StringResource("revanced_hide_album_cards_summary_on", "Album cards are hidden"), - StringResource("revanced_hide_album_cards_summary_off", "Album cards are shown") - ) - ) - - albumCardId = ResourceMappingPatch.resourceMappings.single { - it.type == "layout" && it.name == "album_card" - }.id - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/annotations/HideArtistCardCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/annotations/HideArtistCardCompatibility.kt deleted file mode 100644 index 637728f6f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/annotations/HideArtistCardCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.artistcards.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideArtistCardCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/patch/HideArtistCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/patch/HideArtistCardsPatch.kt deleted file mode 100644 index c6153f34e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/patch/HideArtistCardsPatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.artistcards.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.artistcards.annotations.HideArtistCardCompatibility -import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([ResourceMappingPatch::class, LithoFilterPatch::class]) -@Name("hide-artist-card") -@Description("Hides the artist card below the searchbar.") -@HideArtistCardCompatibility -@Version("0.0.1") -class HideArtistCardsPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_artist_cards", - StringResource("revanced_hide_artist_cards_title", "Hide artist cards"), - false, - StringResource("revanced_hide_artist_cards_on", "Artist cards is hidden"), - StringResource("revanced_hide_artist_cards_off", "Artist cards is shown") - ), - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt deleted file mode 100644 index ee2cd1a76..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.breakingnews.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class BreakingNewsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt deleted file mode 100644 index b4c3d8363..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/fingerprints/BreakingNewsFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.breakingnews.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch.BreakingNewsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object BreakingNewsFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == BreakingNewsResourcePatch.horizontalCardListId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/patch/BreakingNewsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/patch/BreakingNewsPatch.kt deleted file mode 100644 index 0b5cf1182..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/bytecode/patch/BreakingNewsPatch.kt +++ /dev/null @@ -1,46 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.breakingnews.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.breakingnews.annotations.BreakingNewsCompatibility -import app.revanced.patches.youtube.layout.hide.breakingnews.bytecode.fingerprints.BreakingNewsFingerprint -import app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch.BreakingNewsResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, BreakingNewsResourcePatch::class]) -@Name("hide-breaking-news-shelf") -@Description("Hides the breaking news shelf on the homepage tab.") -@BreakingNewsCompatibility -@Version("0.0.1") -class BreakingNewsPatch : BytecodePatch( - listOf( - BreakingNewsFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val breakingNewsResult = BreakingNewsFingerprint.result!! - val breakingNewsMethod = breakingNewsResult.mutableMethod - - val moveResultObjectIndex = - breakingNewsResult.scanResult.patternScanResult!!.endIndex - 2 - - breakingNewsMethod.addInstruction( - moveResultObjectIndex + 1, """ - invoke-static {v${(breakingNewsMethod.instruction(moveResultObjectIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideBreakingNewsPatch;->hideBreakingNews(Landroid/view/View;)V - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/resource/patch/BreakingNewsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/resource/patch/BreakingNewsResourcePatch.kt deleted file mode 100644 index ffb32092e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/resource/patch/BreakingNewsResourcePatch.kt +++ /dev/null @@ -1,40 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Name("breaking-news-shelf-resource-patch") -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class BreakingNewsResourcePatch : ResourcePatch { - companion object { - internal var horizontalCardListId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_breaking_news", - StringResource("revanced_hide_breaking_news_title", "Hide breaking news"), - true, - StringResource("revanced_hide_breaking_news_summary_on", "Breaking news are hidden"), - StringResource("revanced_hide_breaking_news_summary_off", "Breaking news are shown") - ) - ) - - horizontalCardListId = ResourceMappingPatch.resourceMappings.single { - it.type == "layout" && it.name == "horizontal_card_list" - }.id - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt deleted file mode 100644 index a110c894c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.comments.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class CommentsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/fingerprints/ShortsCommentsButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/fingerprints/ShortsCommentsButtonFingerprint.kt deleted file mode 100644 index 1bfb297f3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/fingerprints/ShortsCommentsButtonFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.comments.bytecode.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.comments.resource.patch.CommentsResourcePatch -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object ShortsCommentsButtonFingerprint : MethodFingerprint( - "V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("Z", "Z", "L"), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { - it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == CommentsResourcePatch.shortsCommentsButtonId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/patch/CommentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/patch/CommentsPatch.kt deleted file mode 100644 index 7e6708278..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/patch/CommentsPatch.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.comments.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.comments.annotations.CommentsCompatibility -import app.revanced.patches.youtube.layout.hide.comments.bytecode.fingerprints.ShortsCommentsButtonFingerprint -import app.revanced.patches.youtube.layout.hide.comments.resource.patch.CommentsResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, CommentsResourcePatch::class]) -@Name("comments") -@Description("Hides components related to comments.") -@CommentsCompatibility -@Version("0.0.1") -class CommentsPatch : BytecodePatch( - listOf( - ShortsCommentsButtonFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val shortsCommentsButtonResult = ShortsCommentsButtonFingerprint.result!! - val shortsCommentsButtonMethod = shortsCommentsButtonResult.mutableMethod - - val checkCastAnchorFingerprint = object : MethodFingerprint( - opcodes = listOf( - Opcode.CONST, - Opcode.CONST_HIGH16, - Opcode.IF_EQZ, - Opcode.CONST, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ) - ) {} - - val checkCastAnchorIndex = checkCastAnchorFingerprint.also { - it.resolve(context, shortsCommentsButtonMethod, shortsCommentsButtonResult.classDef) - }.result!!.scanResult.patternScanResult!!.endIndex - - shortsCommentsButtonMethod.addInstructions( - checkCastAnchorIndex + 1, """ - invoke-static {v${(shortsCommentsButtonMethod.instruction(checkCastAnchorIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideShortsCommentsButtonPatch;->hideShortsCommentsButton(Landroid/view/View;)V - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/resource/patch/CommentsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/resource/patch/CommentsResourcePatch.kt deleted file mode 100644 index c16d6f82e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/resource/patch/CommentsResourcePatch.kt +++ /dev/null @@ -1,64 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.comments.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -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.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.comments.annotations.CommentsCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Name("comments-resource-patch") -@CommentsCompatibility -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class CommentsResourcePatch : ResourcePatch { - companion object { - internal var shortsCommentsButtonId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - PreferenceScreen( - "revanced_comments", - StringResource("revanced_comments_title", "Comments"), - listOf( - SwitchPreference( - "revanced_hide_comments_section", - StringResource("revanced_hide_comments_section_title", "Hide comments section"), - false, - StringResource("revanced_hide_comments_section_summary_on", "Comment section is hidden"), - StringResource("revanced_hide_comments_section_summary_off", "Comment section is shown") - ), - SwitchPreference( - "revanced_hide_preview_comment", - StringResource("revanced_hide_preview_comment_title", "Hide preview comment"), - false, - StringResource("revanced_hide_preview_comment_on", "Preview comment is hidden"), - StringResource("revanced_hide_preview_comment_off", "Preview comment is shown") - ), - SwitchPreference( - "revanced_hide_shorts_comments_button", - StringResource("revanced_hide_shorts_comments_button_title", "Hide shorts comments button"), - false, - StringResource("revanced_hide_shorts_comments_button_on", "Shorts comments button is hidden"), - StringResource("revanced_hide_shorts_comments_button_off", "Shorts comments button is shown") - ), - ), - StringResource("revanced_comments_summary", "Manage the visibility of comments section components") - ) - ) - - shortsCommentsButtonId = ResourceMappingPatch.resourceMappings.single { - it.type == "drawable" && it.name == "ic_right_comment_32c" - }.id - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt deleted file mode 100644 index df20612b5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class CrowdfundingBoxCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt deleted file mode 100644 index 0ad96367d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object CrowdfundingBoxFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == CrowdfundingBoxResourcePatch.crowdfundingBoxId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/patch/CrowdfundingBoxPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/patch/CrowdfundingBoxPatch.kt deleted file mode 100644 index 94d3b103f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/patch/CrowdfundingBoxPatch.kt +++ /dev/null @@ -1,49 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations.CrowdfundingBoxCompatibility -import app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.fingerprints.CrowdfundingBoxFingerprint -import app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, CrowdfundingBoxResourcePatch::class]) -@Name("hide-crowdfunding-box") -@Description("Hides the crowdfunding box between the player and video description.") -@CrowdfundingBoxCompatibility -@Version("0.0.1") -class CrowdfundingBoxPatch : BytecodePatch( - listOf( - CrowdfundingBoxFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - CrowdfundingBoxFingerprint.result?.let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val objectRegister = (instruction(insertIndex) as TwoRegisterInstruction).registerA - - addInstruction(insertIndex, "invoke-static {v$objectRegister}, $INTEGRATIONS_METHOD_DESCRIPTOR") - } - } ?: return CrowdfundingBoxFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_METHOD_DESCRIPTOR = - "Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/resource/patch/CrowdfundingBoxResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/resource/patch/CrowdfundingBoxResourcePatch.kt deleted file mode 100644 index dc639f438..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/resource/patch/CrowdfundingBoxResourcePatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations.CrowdfundingBoxCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Name("crowdfunding-box-resource-patch") -@CrowdfundingBoxCompatibility -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class CrowdfundingBoxResourcePatch : ResourcePatch { - companion object { - internal var crowdfundingBoxId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_crowdfunding_box", - StringResource("revanced_hide_crowdfunding_box_title", "Hide crowdfunding box"), - false, - StringResource("revanced_hide_crowdfunding_box_summary_on", "Crowdfunding box is hidden"), - StringResource("revanced_hide_crowdfunding_box_summary_off", "Crowdfunding box is shown") - ) - ) - - crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single { - it.type == "layout" && it.name == "donation_companion" - }.id - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndscreenCardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndscreenCardsCompatibility.kt deleted file mode 100644 index f756c99fe..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndscreenCardsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.endscreencards.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideEndscreenCardsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutCircleFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutCircleFingerprint.kt deleted file mode 100644 index 0931de5f1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutCircleFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object LayoutCircleFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutCircle - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutIconFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutIconFingerprint.kt deleted file mode 100644 index 9fcd0dc43..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutIconFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object LayoutIconFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.CONST_4, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutIcon - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutVideoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutVideoFingerprint.kt deleted file mode 100644 index bec34caf5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/fingerprints/LayoutVideoFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object LayoutVideoFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutVideo - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/patch/HideEndscreenCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/patch/HideEndscreenCardsPatch.kt deleted file mode 100644 index 69adc82c6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/bytecode/patch/HideEndscreenCardsPatch.kt +++ /dev/null @@ -1,54 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.endscreencards.annotations.HideEndscreenCardsCompatibility -import app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints.LayoutCircleFingerprint -import app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints.LayoutIconFingerprint -import app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints.LayoutVideoFingerprint -import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.iface.instruction.formats.Instruction21c - -@Patch -@DependsOn([IntegrationsPatch::class, HideEndscreenCardsResourcePatch::class]) -@Name("hide-endscreen-cards") -@Description("Hides the suggested video cards at the end of a video in fullscreen.") -@HideEndscreenCardsCompatibility -@Version("0.0.1") -class HideEndscreenCardsPatch : BytecodePatch( - listOf( - LayoutCircleFingerprint, - LayoutIconFingerprint, - LayoutVideoFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - fun MethodFingerprint.injectHideCall() { - val layoutResult = result!! - val layoutMethod = layoutResult.mutableMethod - - val checkCastIndex = layoutResult.scanResult.patternScanResult!!.endIndex - val viewRegister = (layoutMethod.instruction(checkCastIndex) as Instruction21c).registerA - - layoutMethod.addInstruction( - checkCastIndex + 1, - "invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideEndscreenCardsPatch;->hideEndscreen(Landroid/view/View;)V" - ) - } - - listOf(LayoutCircleFingerprint, LayoutIconFingerprint, LayoutVideoFingerprint).forEach(MethodFingerprint::injectHideCall) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/resource/patch/HideEndscreenCardsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/resource/patch/HideEndscreenCardsResourcePatch.kt deleted file mode 100644 index 6dc3d74c5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/resource/patch/HideEndscreenCardsResourcePatch.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.endscreencards.annotations.HideEndscreenCardsCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Name("hide-endscreen-cards-resource-patch") -@HideEndscreenCardsCompatibility -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class HideEndscreenCardsResourcePatch : ResourcePatch { - internal companion object { - var layoutCircle: Long = -1 - var layoutIcon: Long = -1 - var layoutVideo: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_endscreen_cards", - StringResource("revanced_hide_endscreen_cards_title", "Hide end screen cards"), - true, - StringResource("revanced_hide_endscreen_cards_summary_on", "End screen cards are hidden"), - StringResource("revanced_hide_endscreen_cards_summary_off", "End screen cards are shown") - ), - ) - - fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single { - it.type == "layout" && it.name == "endscreen_element_layout_$name" - }.id - - layoutCircle = findEndscreenResourceId("circle") - layoutIcon = findEndscreenResourceId("icon") - layoutVideo = findEndscreenResourceId("video") - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt deleted file mode 100644 index fdada61ab..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.floatingmicrophone.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideFloatingMicrophoneButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/fingerprints/ShowFloatingMicrophoneButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/fingerprints/ShowFloatingMicrophoneButtonFingerprint.kt deleted file mode 100644 index ed72bd968..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/fingerprints/ShowFloatingMicrophoneButtonFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.floatingmicrophone.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.floatingmicrophone.patch.HideFloatingMicrophoneButtonResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object ShowFloatingMicrophoneButtonFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.IGET_BOOLEAN, - Opcode.IF_EQZ, - Opcode.RETURN_VOID - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { - (it as? WideLiteralInstruction)?.wideLiteral == HideFloatingMicrophoneButtonResourcePatch.fabButtonId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/patch/HideFloatingMicrophoneButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/patch/HideFloatingMicrophoneButtonPatch.kt deleted file mode 100644 index 30f02c143..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/patch/HideFloatingMicrophoneButtonPatch.kt +++ /dev/null @@ -1,51 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.floatingmicrophone.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.floatingmicrophone.annotations.HideFloatingMicrophoneButtonCompatibility -import app.revanced.patches.youtube.layout.hide.floatingmicrophone.fingerprints.ShowFloatingMicrophoneButtonFingerprint -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction - -@Patch -@Name("hide-floating-microphone-button") -@Description("Hides the floating microphone button which appears in search.") -@DependsOn([HideFloatingMicrophoneButtonResourcePatch::class]) -@HideFloatingMicrophoneButtonCompatibility -@Version("0.0.1") -class HideFloatingMicrophoneButtonPatch : BytecodePatch( - listOf(ShowFloatingMicrophoneButtonFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - ShowFloatingMicrophoneButtonFingerprint.result?.let { result -> - with(result.mutableMethod) { - val insertIndex = result.scanResult.patternScanResult!!.startIndex + 1 - val showButtonRegister = (instruction(insertIndex - 1) as TwoRegisterInstruction).registerA - - addInstructions( - insertIndex, - """ - invoke-static {v$showButtonRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideFloatingMicrophoneButton(Z)Z - move-result v$showButtonRegister - """ - ) - } - } ?: return ShowFloatingMicrophoneButtonFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/patches/HideFloatingMicrophoneButtonPatch;" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/patch/HideFloatingMicrophoneButtonResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/patch/HideFloatingMicrophoneButtonResourcePatch.kt deleted file mode 100644 index 5bc6cc043..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/patch/HideFloatingMicrophoneButtonResourcePatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.floatingmicrophone.patch - -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.floatingmicrophone.annotations.HideFloatingMicrophoneButtonCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@HideFloatingMicrophoneButtonCompatibility -@Version("0.0.1") -class HideFloatingMicrophoneButtonResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_floating_microphone_button", - StringResource( - "revanced_hide_floating_microphone_button_enabled_title", - "Hide floating microphone button" - ), - true, - StringResource("revanced_hide_floating_microphone_button_summary_on", "Microphone button hidden"), - StringResource("revanced_hide_floating_microphone_button_summary_off", "Microphone button shown") - ) - ) - - fabButtonId = ResourceMappingPatch.resourceMappings.find { it.type == "id" && it.name == "fab" }?.id - ?: return PatchResultError("Can not find required fab button resource id") - return PatchResultSuccess() - } - - internal companion object { - var fabButtonId: Long = -1 - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/annotations/HideGetPremiumCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/annotations/HideGetPremiumCompatibility.kt deleted file mode 100644 index 6f373efd5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/annotations/HideGetPremiumCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.getpremium.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube", arrayOf("18.15.40"))]) -@Target(AnnotationTarget.CLASS) -internal annotation class HideGetPremiumCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt deleted file mode 100644 index 29cca3d03..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/fingerprints/GetPremiumViewFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.getpremium.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object GetPremiumViewFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.ADD_INT_2ADDR, - Opcode.ADD_INT_2ADDR, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ), - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/google/android/apps/youtube/app/red/presenter/CompactYpcOfferModuleView;" - && methodDef.name == "onMeasure" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/patch/HideGetPremiumVideoAdvertisementPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/patch/HideGetPremiumVideoAdvertisementPatch.kt deleted file mode 100644 index 7e3e7b036..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/getpremium/bytecode/patch/HideGetPremiumVideoAdvertisementPatch.kt +++ /dev/null @@ -1,77 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.getpremium.bytecode.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.getpremium.annotations.HideGetPremiumCompatibility -import app.revanced.patches.youtube.layout.hide.getpremium.bytecode.fingerprints.GetPremiumViewFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-get-premium") -@Description("Hides advertisement for YouTube Premium under the video player.") -@HideGetPremiumCompatibility -@Version("0.0.1") -class HideGetPremiumPatch : BytecodePatch( - listOf( - GetPremiumViewFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_get_premium", - StringResource("revanced_hide_get_premium_title", "Hide YouTube Premium advertisement"), - true, - StringResource("revanced_hide_get_premium_summary_on", "YouTube Premium advertisement are hidden"), - StringResource("revanced_hide_get_premium_summary_off", "YouTube Premium advertisement are shown") - ) - ) - - GetPremiumViewFingerprint.result?.let { - it.mutableMethod.apply { - val startIndex = it.scanResult.patternScanResult!!.startIndex - val measuredWidthRegister = (instruction(startIndex) as TwoRegisterInstruction).registerA - val measuredHeightInstruction = instruction(startIndex + 1) as TwoRegisterInstruction - val measuredHeightRegister = measuredHeightInstruction.registerA - val tempRegister = measuredHeightInstruction.registerB - - addInstructions( - startIndex + 2, - """ - # Override the internal measurement of the layout with zero values. - invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideGetPremiumView()Z - move-result v$tempRegister - if-eqz v$tempRegister, :allow - const/4 v$measuredWidthRegister, 0x0 - const/4 v$measuredHeightRegister, 0x0 - :allow - nop - # Layout width/height is then passed to a protected class method. - """ - ) - } - } ?: return GetPremiumViewFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/patches/HideGetPremiumPatch;" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt deleted file mode 100644 index a3d68e940..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.infocards.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideInfocardsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoFingerprint.kt deleted file mode 100644 index 1c5d3d54c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.infocards.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object InfocardsIncognitoFingerprint : MethodFingerprint( - "Ljava/lang/Boolean;", - AccessFlags.PUBLIC or AccessFlags.FINAL, - strings = listOf("vibrator") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoParentFingerprint.kt deleted file mode 100644 index 815b37d80..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsIncognitoParentFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.infocards.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object InfocardsIncognitoParentFingerprint : MethodFingerprint( - "Ljava/lang/String;", - AccessFlags.PUBLIC or AccessFlags.FINAL, - strings = listOf("player_overlay_info_card_teaser"), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsMethodCallFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsMethodCallFingerprint.kt deleted file mode 100644 index 0f258ca1b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/fingerprints/InfocardsMethodCallFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.infocards.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.infocards.resource.patch.HideInfocardsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object InfocardsMethodCallFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - (instruction as? WideLiteralInstruction)?.wideLiteral == HideInfocardsResourcePatch.drawerResourceId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/patch/HideInfoCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/patch/HideInfoCardsPatch.kt deleted file mode 100644 index 577a4da0d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/patch/HideInfoCardsPatch.kt +++ /dev/null @@ -1,76 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.infocards.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.layout.hide.infocards.annotations.HideInfocardsCompatibility -import app.revanced.patches.youtube.layout.hide.infocards.fingerprints.InfocardsIncognitoFingerprint -import app.revanced.patches.youtube.layout.hide.infocards.fingerprints.InfocardsIncognitoParentFingerprint -import app.revanced.patches.youtube.layout.hide.infocards.fingerprints.InfocardsMethodCallFingerprint -import app.revanced.patches.youtube.layout.hide.infocards.resource.patch.HideInfocardsResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction35c - -@Patch -@DependsOn([IntegrationsPatch::class, HideInfocardsResourcePatch::class]) -@Name("hide-info-cards") -@Description("Hides info cards in videos.") -@HideInfocardsCompatibility -@Version("0.0.1") -class HideInfoCardsPatch : BytecodePatch( - listOf( - InfocardsIncognitoParentFingerprint, - InfocardsMethodCallFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - with(InfocardsIncognitoFingerprint.also { - it.resolve(context, InfocardsIncognitoParentFingerprint.result!!.classDef) - }.result!!.mutableMethod) { - val invokeInstructionIndex = implementation!!.instructions.indexOfFirst { - it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal && - ((it as? BuilderInstruction35c)?.reference.toString() == - "Landroid/view/View;->setVisibility(I)V") - } - - addInstructions( - invokeInstructionIndex, - "invoke-static {v${(instruction(invokeInstructionIndex) as? BuilderInstruction35c)?.registerC}}," + - " Lapp/revanced/integrations/patches/HideInfoCardsPatch;->hideInfoCardsIncognito(Landroid/view/View;)V" - ) - } - - with(InfocardsMethodCallFingerprint.result!!) { - val hideInfocardsCallMethod = mutableMethod - - val invokeInterfaceIndex = scanResult.patternScanResult!!.endIndex - val toggleRegister = hideInfocardsCallMethod.implementation!!.registerCount - 1 - - hideInfocardsCallMethod.addInstructions( - invokeInterfaceIndex, """ - invoke-static {}, Lapp/revanced/integrations/patches/HideInfoCardsPatch;->hideInfoCardsMethodCall()Z - move-result v$toggleRegister - if-nez v$toggleRegister, :hide_info_cards - """, - listOf( - ExternalLabel( - "hide_info_cards", hideInfocardsCallMethod.instruction(invokeInterfaceIndex + 1) - ) - ) - ) - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/resource/patch/HideInfocardsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/resource/patch/HideInfocardsResourcePatch.kt deleted file mode 100644 index 47388939a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/resource/patch/HideInfocardsResourcePatch.kt +++ /dev/null @@ -1,40 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.infocards.resource.patch - -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.infocards.annotations.HideInfocardsCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@HideInfocardsCompatibility -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class HideInfocardsResourcePatch : ResourcePatch { - internal companion object { - var drawerResourceId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_infocards", - StringResource("revanced_hide_infocards_title", "Hide info cards"), - true, - StringResource("revanced_hide_infocards_summary_on", "Info cards are hidden"), - StringResource("revanced_hide_infocards_summary_off", "Info cards are shown") - ) - ) - - drawerResourceId = ResourceMappingPatch.resourceMappings.single { - it.type == "id" && it.name == "info_cards_drawer_header" - }.id - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt deleted file mode 100644 index 237a27691..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.personalinformation.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideEmailAddressCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt deleted file mode 100644 index 5e5d9fb23..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.personalinformation.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch.HideEmailAddressResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object AccountSwitcherAccessibilityLabelFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.NEW_ARRAY, - Opcode.CONST_4, - Opcode.APUT_OBJECT, - Opcode.CONST, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == HideEmailAddressResourcePatch.accountSwitcherAccessibilityLabelId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/patch/HideEmailAddressPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/patch/HideEmailAddressPatch.kt deleted file mode 100644 index a6f443d7d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/bytecode/patch/HideEmailAddressPatch.kt +++ /dev/null @@ -1,52 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.personalinformation.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.personalinformation.annotations.HideEmailAddressCompatibility -import app.revanced.patches.youtube.layout.hide.personalinformation.bytecode.fingerprints.AccountSwitcherAccessibilityLabelFingerprint -import app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch.HideEmailAddressResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, HideEmailAddressResourcePatch::class]) -@Name("hide-email-address") -@Description("Hides the email address in the account switcher.") -@HideEmailAddressCompatibility -@Version("0.0.1") -class HideEmailAddressPatch : BytecodePatch( - listOf( - AccountSwitcherAccessibilityLabelFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val accountSwitcherAccessibilityLabelResult = AccountSwitcherAccessibilityLabelFingerprint.result!! - val accountSwitcherAccessibilityLabelMethod = accountSwitcherAccessibilityLabelResult.mutableMethod - - val setVisibilityConstIndex = - accountSwitcherAccessibilityLabelResult.scanResult.patternScanResult!!.endIndex - - val setVisibilityConstRegister = ( - accountSwitcherAccessibilityLabelMethod.instruction - (setVisibilityConstIndex - 2) as OneRegisterInstruction - ).registerA - - accountSwitcherAccessibilityLabelMethod.addInstructions( - setVisibilityConstIndex, """ - invoke-static {v$setVisibilityConstRegister}, Lapp/revanced/integrations/patches/HideEmailAddressPatch;->hideEmailAddress(I)I - move-result v$setVisibilityConstRegister - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/resource/patch/HideEmailAddressResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/resource/patch/HideEmailAddressResourcePatch.kt deleted file mode 100644 index 044c3475f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/resource/patch/HideEmailAddressResourcePatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.personalinformation.annotations.HideEmailAddressCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Name("hide-email-address-resource-patch") -@HideEmailAddressCompatibility -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class HideEmailAddressResourcePatch : ResourcePatch { - companion object { - internal var accountSwitcherAccessibilityLabelId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_email_address", - StringResource("revanced_hide_email_address_title", "Hide email in account switcher"), - false, - StringResource("revanced_hide_email_address_summary_on", "Email address is hidden"), - StringResource("revanced_hide_email_address_summary_off", "Email address is shown") - ) - ) - - accountSwitcherAccessibilityLabelId = ResourceMappingPatch.resourceMappings.single { - it.type == "string" && it.name == "account_switcher_accessibility_label" - }.id - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/annotations/HidePlayerOverlayPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/annotations/HidePlayerOverlayPatchCompatibility.kt deleted file mode 100644 index 9ca55f523..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/annotations/HidePlayerOverlayPatchCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.player.overlay.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class HidePlayerOverlayPatchCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/patch/HidePlayerOverlayPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/patch/HidePlayerOverlayPatch.kt deleted file mode 100644 index 060073e40..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/overlay/patch/HidePlayerOverlayPatch.kt +++ /dev/null @@ -1,46 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.player.overlay.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HidePlayerOverlayPatchCompatibility - -@Patch(false) -@Name("hide-player-overlay") -@Description("Hides the dark player overlay when player controls are visible.") -@HidePlayerOverlayPatchCompatibility -@Version("0.0.1") -class HidePlayerOverlayPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - val attributes = arrayOf("height", "width") - - context.xmlEditor[RESOURCE_FILE_PATH].use { editor -> - editor.file.getElementsByTagName("FrameLayout").item(0).childNodes.apply { - for (i in 1 until length) { - val view = item(i) - if ( - view.attributes.getNamedItem("android:id") - ?.nodeValue - ?.endsWith("scrim_overlay") == true - ) { - attributes.forEach { - view.attributes.getNamedItem("android:layout_$it").nodeValue = "0.0dip" - } - break - } - } - } - } - - return PatchResultSuccess() - } - - private companion object { - const val RESOURCE_FILE_PATH = "res/layout/youtube_controls_overlay.xml" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt deleted file mode 100644 index 893b4c4e8..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.seekbar.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideSeekbarCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/patch/HideSeekbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/patch/HideSeekbarPatch.kt deleted file mode 100644 index 6fdfa4b84..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/patch/HideSeekbarPatch.kt +++ /dev/null @@ -1,58 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.seekbar.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.fingerprints.SeekbarFingerprint -import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.seekbar.annotations.HideSeekbarCompatibility -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-seekbar") -@Description("Hides the seekbar.") -@HideSeekbarCompatibility -@Version("0.0.1") -class HideSeekbarPatch : BytecodePatch( - listOf(SeekbarFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_seekbar", - StringResource("revanced_hide_seekbar_title", "Hide seekbar"), - false, - StringResource("revanced_hide_seekbar_summary_on", "Seekbar is hidden"), - StringResource("revanced_hide_seekbar_summary_off", "Seekbar is shown") - ) - ) - - SeekbarFingerprint.result!!.let { - SeekbarOnDrawFingerprint.apply { resolve(context, it.mutableClass) } - }.result!!.mutableMethod.addInstructions( - 0, """ - const/4 v0, 0x0 - invoke-static { }, Lapp/revanced/integrations/patches/HideSeekbarPatch;->hideSeekbar()Z - move-result v0 - if-eqz v0, :hide_seekbar - return-void - :hide_seekbar - nop - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt deleted file mode 100644 index c1d67cd02..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.time.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideTimeCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/fingerprints/TimeCounterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/fingerprints/TimeCounterFingerprint.kt deleted file mode 100644 index d230e5420..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/fingerprints/TimeCounterFingerprint.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.time.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(3) -object TimeCounterFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.IGET_OBJECT, - Opcode.IGET_WIDE, - Opcode.CONST_WIDE_16, - Opcode.CMP_LONG, - Opcode.IF_LEZ, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.GOTO, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/patch/HideTimestampPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/patch/HideTimestampPatch.kt deleted file mode 100644 index e30f8cb5a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/patch/HideTimestampPatch.kt +++ /dev/null @@ -1,55 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.time.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.time.annotations.HideTimeCompatibility -import app.revanced.patches.youtube.layout.hide.time.fingerprints.TimeCounterFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-timestamp") -@Description("Hides timestamp in video player.") -@HideTimeCompatibility -@Version("0.0.1") -class HideTimestampPatch : BytecodePatch( - listOf( - TimeCounterFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_timestamp", - StringResource("revanced_hide_timestamp_title", "Hide video timestamp"), - false, - StringResource("revanced_hide_timestamp_summary_on", "Timestamp is hidden"), - StringResource("revanced_hide_timestamp_summary_off", "Timestamp is shown") - ) - ) - - TimeCounterFingerprint.result!!.mutableMethod.addInstructions( - 0, """ - invoke-static { }, Lapp/revanced/integrations/patches/HideTimestampPatch;->hideTimestamp()Z - move-result v0 - if-eqz v0, :hide_time - return-void - :hide_time - nop - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchinVRCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchinVRCompatibility.kt deleted file mode 100644 index 94f11946a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchinVRCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.watchinvr.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class WatchinVRCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/fingerprints/WatchInVRFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/fingerprints/WatchInVRFingerprint.kt deleted file mode 100644 index daf6190e3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/fingerprints/WatchInVRFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.watchinvr.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object WatchInVRFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), - strings = listOf("menu_item_cardboard_vr") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/patch/WatchInVRPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/patch/WatchInVRPatch.kt deleted file mode 100644 index 84e8d8d94..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/patch/WatchInVRPatch.kt +++ /dev/null @@ -1,55 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.watchinvr.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.watchinvr.annotations.WatchinVRCompatibility -import app.revanced.patches.youtube.layout.hide.watchinvr.fingerprints.WatchInVRFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-watch-in-vr") -@Description("Hides the option to watch in VR from the player settings flyout panel.") -@WatchinVRCompatibility -@Version("0.0.1") -class WatchInVRPatch : BytecodePatch( - listOf( - WatchInVRFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_watch_in_vr", - StringResource("revanced_hide_watch_in_vr_title", "Hide VR setting"), - false, - StringResource("revanced_hide_watch_in_vr_summary_on", "VR setting is hidden"), - StringResource("revanced_hide_watch_in_vr_summary_off", "VR setting is shown") - ) - ) - - WatchInVRFingerprint.result!!.mutableMethod.addInstructions( - 0, """ - invoke-static {}, Lapp/revanced/integrations/patches/HideWatchInVRPatch;->hideWatchInVR()Z - move-result v0 - if-eqz v0, :shown - return-void - :shown - nop - """ - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWaterwarkCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWaterwarkCompatibility.kt deleted file mode 100644 index 922cf1eb4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWaterwarkCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.watermark.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HideWatermarkCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/fingerprints/HideWatermarkFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/fingerprints/HideWatermarkFingerprint.kt deleted file mode 100644 index b34c9a99a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/fingerprints/HideWatermarkFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.watermark.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object HideWatermarkFingerprint : MethodFingerprint ( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/fingerprints/HideWatermarkParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/fingerprints/HideWatermarkParentFingerprint.kt deleted file mode 100644 index 444fadd52..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/fingerprints/HideWatermarkParentFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.watermark.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object HideWatermarkParentFingerprint : MethodFingerprint ( - "L", AccessFlags.PUBLIC or AccessFlags.FINAL, strings = listOf("player_overlay_in_video_programming") -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/patch/HideWatermarkPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/patch/HideWatermarkPatch.kt deleted file mode 100644 index f149f3cf6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/patch/HideWatermarkPatch.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.watermark.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.watermark.annotations.HideWatermarkCompatibility -import app.revanced.patches.youtube.layout.hide.watermark.fingerprints.HideWatermarkFingerprint -import app.revanced.patches.youtube.layout.hide.watermark.fingerprints.HideWatermarkParentFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("hide-watermark") -@Description("Hides creator's watermarks on videos.") -@HideWatermarkCompatibility -@Version("0.0.1") -class HideWatermarkPatch : BytecodePatch( - listOf( - HideWatermarkParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_video_watermark", - StringResource("revanced_hide_video_watermark_title", "Hide creator watermark on videos"), - true, - StringResource("revanced_hide_video_watermark_summary_on", "Watermark is hidden"), - StringResource("revanced_hide_video_watermark_summary_off", "Watermark is shown") - ) - ) - - HideWatermarkFingerprint.resolve(context, HideWatermarkParentFingerprint.result!!.classDef) - val result = HideWatermarkFingerprint.result - ?: return PatchResultError("Required parent method could not be found.") - - val method = result.mutableMethod - val line = method.implementation!!.instructions.size - 5 - - method.removeInstruction(line) - method.addInstructions( - line, """ - invoke-static {}, Lapp/revanced/integrations/patches/BrandingWaterMarkPatch;->isBrandingWatermarkShown()Z - move-result p2 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt deleted file mode 100644 index c6dbfa470..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.oldqualitylayout.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class OldQualityLayoutCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt deleted file mode 100644 index 4abb688e9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/fingerprints/QualityMenuViewInflateFingerprint.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object QualityMenuViewInflateFingerprint : MethodFingerprint( - "L", AccessFlags.FINAL or AccessFlags.PUBLIC, listOf("L", "L", "L"), listOf( - Opcode.INVOKE_SUPER, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_16, - Opcode.INVOKE_VIRTUAL, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST_STRING, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt deleted file mode 100644 index dd4597b01..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.revanced.patches.youtube.layout.oldqualitylayout.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility -import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.QualityMenuViewInflateFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("old-quality-layout") -@Description("Enables the original video quality flyout in the video player settings") -@OldQualityLayoutCompatibility -@Version("0.0.1") -// new ReVanced users have no idea what it means to use the "old quality layout menu" -// maybe rename this patch to better describe what it provides (ie: user-selectable-video-resolution ) -class OldQualityLayoutPatch : BytecodePatch( - listOf(QualityMenuViewInflateFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_use_old_style_quality_settings", - StringResource("revanced_old_style_quality_settings_enabled_title", "Use old video quality player menu"), - true, - StringResource("revanced_old_style_quality_settings_summary_on", "Old video quality menu is used"), - StringResource("revanced_old_style_quality_settings_summary_off", "Old video quality menu is not used") - ) - ) - - val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!! - val method = inflateFingerprintResult.mutableMethod - val instructions = method.implementation!!.instructions - - // at this index the listener is added to the list view - val listenerInvokeRegister = instructions.size - 1 - 1 - - // get the register which stores the quality menu list view - val onItemClickViewRegister = (instructions[listenerInvokeRegister] as FiveRegisterInstruction).registerC - - // insert the integrations method - method.addInstruction( - listenerInvokeRegister, // insert the integrations instructions right before the listener - "invoke-static { v$onItemClickViewRegister }, Lapp/revanced/integrations/patches/playback/quality/OldQualityLayoutPatch;->showOldQualityMenu(Landroid/widget/ListView;)V" - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt deleted file mode 100644 index bbfa21ded..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class FullscreenPanelsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderFingerprint.kt deleted file mode 100644 index 7d7429ca1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object FullscreenViewAdderFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.IGET_BOOLEAN - ) -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderParentFingerprint.kt deleted file mode 100644 index 6184eb0c2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/fingerprints/FullscreenViewAdderParentFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object FullscreenViewAdderParentFingerprint : MethodFingerprint( - parameters = listOf("L", "L"), - opcodes = listOf( - Opcode.GOTO, - Opcode.IGET_BOOLEAN, - Opcode.IF_EQ, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - ), - customFingerprint = { it.definingClass.endsWith("FullscreenEngagementPanelOverlay;") } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/patch/FullscreenPanelsRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/patch/FullscreenPanelsRemoverPatch.kt deleted file mode 100644 index 3939bdcac..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/patch/FullscreenPanelsRemoverPatch.kt +++ /dev/null @@ -1,65 +0,0 @@ -package app.revanced.patches.youtube.layout.panels.fullscreen.remove.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations.FullscreenPanelsCompatibility -import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderFingerprint -import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderParentFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@Name("disable-fullscreen-panels") -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Description("Disables video description and comments panel in fullscreen view.") -@FullscreenPanelsCompatibility -@Version("0.0.1") -class FullscreenPanelsRemoverPatch : BytecodePatch( - listOf( - FullscreenViewAdderParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_hide_fullscreen_panels", - StringResource("revanced_hide_fullscreen_panels_title", "Hide fullscreen panels"), - true, - StringResource("revanced_hide_fullscreen_panels_summary_on", "Fullscreen panels are hidden"), - StringResource("revanced_hide_fullscreen_panels_summary_off", "Fullscreen panels are shown") - ) - ) - - val parentResult = FullscreenViewAdderParentFingerprint.result!! - FullscreenViewAdderFingerprint.resolve(context, parentResult.method, parentResult.classDef) - val result = FullscreenViewAdderParentFingerprint.result - ?: return PatchResultError("Fingerprint not resolved!") - - val method = result.mutableMethod - - val ifIndex = result.scanResult.patternScanResult!!.startIndex + 2 - - method.removeInstruction(ifIndex) - method.addInstructions( - ifIndex, """ - invoke-static {}, Lapp/revanced/integrations/patches/FullscreenPanelsRemoverPatch;->getFullscreenPanelsVisibility()I - move-result p1 - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt deleted file mode 100644 index ac678e6ea..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.panels.popup.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class PlayerPopupPanelsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/fingerprints/EngagementPanelControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/fingerprints/EngagementPanelControllerFingerprint.kt deleted file mode 100644 index c09853574..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/fingerprints/EngagementPanelControllerFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.layout.panels.popup.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - - -@FuzzyPatternScanMethod(3) -object EngagementPanelControllerFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PRIVATE or AccessFlags.FINAL, - strings = listOf( - "EngagementPanelController: cannot show EngagementPanel before EngagementPanelController.init() has been called.", - "[EngagementPanel] Cannot show EngagementPanel before EngagementPanelController.init() has been called." - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/patch/PlayerPopupPanelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/patch/PlayerPopupPanelsPatch.kt deleted file mode 100644 index a8dabc9ca..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/patch/PlayerPopupPanelsPatch.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.revanced.patches.youtube.layout.panels.popup.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.panels.popup.annotations.PlayerPopupPanelsCompatibility -import app.revanced.patches.youtube.layout.panels.popup.fingerprints.EngagementPanelControllerFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("disable-player-popup-panels") -@Description("Disables panels from appearing automatically when going into fullscreen (playlist or live chat).") -@PlayerPopupPanelsCompatibility -@Version("0.0.1") -class PlayerPopupPanelsPatch : BytecodePatch( - listOf( - EngagementPanelControllerFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_player_popup_panels_enabled", - StringResource("revanced_player_popup_panels_title", "Disable player popup panels"), - false, - StringResource("revanced_player_popup_panels_summary_on", "Player popup panels are disabled"), - StringResource("revanced_player_popup_panels_summary_off", "Player popup panels are enabled") - ) - ) - - val engagementPanelControllerMethod = EngagementPanelControllerFingerprint - .result?.mutableMethod ?: return EngagementPanelControllerFingerprint.toErrorResult() - - engagementPanelControllerMethod.addInstructions( - 0, """ - invoke-static { }, Lapp/revanced/integrations/patches/DisablePlayerPopupPanelsPatch;->disablePlayerPopupPanels()Z - move-result v0 - if-eqz v0, :player_popup_panels - if-eqz p4, :player_popup_panels - const/4 v0, 0x0 - return-object v0 - :player_popup_panels - nop - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt deleted file mode 100644 index 19d4d4cbe..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube", arrayOf("18.15.40"))]) -@Target(AnnotationTarget.CLASS) -internal annotation class ReturnYouTubeDislikeCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikeFingerprint.kt deleted file mode 100644 index 63609aff7..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikeFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object DislikeFingerprint : MethodFingerprint( - "V", - strings = listOf("like/dislike") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt deleted file mode 100644 index 29ab1564d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt +++ /dev/null @@ -1,28 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch.ReturnYouTubeDislikeResourcePatch -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object DislikesOldLayoutTextViewFingerprint : MethodFingerprint( - returnType = "V", - parameters = listOf("L"), - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.CONST, // resource identifier register - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, // textview register - Opcode.GOTO, - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == ReturnYouTubeDislikeResourcePatch.oldUIDislikeId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt deleted file mode 100644 index 53a9c0e89..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object LikeFingerprint : MethodFingerprint( - "V", - strings = listOf("like/like") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt deleted file mode 100644 index 9c226ccf8..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object RemoveLikeFingerprint : MethodFingerprint( - "V", - strings = listOf("like/removelike") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextComponentParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextComponentParentFingerprint.kt deleted file mode 100644 index f4e6f7801..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextComponentParentFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object ShortsTextComponentParentFingerprint : MethodFingerprint( - returnType = "V", - parameters = listOf("L", "L"), - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.GOTO, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET_BOOLEAN, - Opcode.IF_EQZ, - Opcode.INVOKE_STATIC - ) -) \ 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 deleted file mode 100644 index 2385aa904..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt +++ /dev/null @@ -1,35 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -/** - * Resolves against the same method that [TextComponentContextFingerprint] resolves to. - */ -object TextComponentAtomicReferenceFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PROTECTED or AccessFlags.FINAL, - parameters = listOf("L"), - opcodes = listOf( - Opcode.MOVE_OBJECT, // available unused register - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.MOVE_OBJECT, // CharSequence reference, and control flow label. Insert code here. - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL_RANGE, - Opcode.MOVE_RESULT_OBJECT, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt deleted file mode 100644 index ca29b8eee..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object TextComponentConstructorFingerprint : MethodFingerprint( - access = AccessFlags.CONSTRUCTOR or AccessFlags.PRIVATE, - strings = listOf("TextComponent") -) \ No newline at end of file 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 deleted file mode 100644 index 1a23e7046..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -/** - * Resolves against the same method that [TextComponentContextFingerprint] resolves to. - */ -object TextComponentContextFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PROTECTED or AccessFlags.FINAL, - parameters = listOf("L"), - opcodes = listOf( - 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/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt deleted file mode 100644 index 1686c7996..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt +++ /dev/null @@ -1,208 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility -import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.* -import app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch.ReturnYouTubeDislikeResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch -import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch -import org.jf.dexlib2.builder.instruction.BuilderInstruction35c -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction - -@Patch -@DependsOn( - [ - IntegrationsPatch::class, - VideoIdPatch::class, - ReturnYouTubeDislikeResourcePatch::class, - PlayerTypeHookPatch::class, - ] -) -@Name("return-youtube-dislike") -@Description("Shows the dislike count of videos using the Return YouTube Dislike API.") -@ReturnYouTubeDislikeCompatibility -@Version("0.0.1") -class ReturnYouTubeDislikePatch : BytecodePatch( - listOf( - TextComponentConstructorFingerprint, - ShortsTextComponentParentFingerprint, - DislikesOldLayoutTextViewFingerprint, - LikeFingerprint, - DislikeFingerprint, - RemoveLikeFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - // region Inject newVideoLoaded event handler to update dislikes when a new video is loaded. - - VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") - - // endregion - - // region Hook like/dislike/remove like button clicks to send votes to the API. - - listOf( - LikeFingerprint.toPatch(Vote.LIKE), - DislikeFingerprint.toPatch(Vote.DISLIKE), - RemoveLikeFingerprint.toPatch(Vote.REMOVE_LIKE) - ).forEach { (fingerprint, vote) -> - fingerprint.result?.mutableMethod?.apply { - addInstructions( - 0, - """ - const/4 v0, ${vote.value} - invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->sendVote(I)V - """ - ) - } ?: return PatchResultError("Failed to find ${fingerprint.name} method.") - } - - // endregion - - // region Hook creation of Spans and the cached lookup of them. - - // Alternatively the hook can be made at the creation of Spans in TextComponentSpec, - // And it works in all situations except it fails to update the Span when the user dislikes, - // since the underlying (likes only) text did not change. - // This hook handles all situations, as it's where the created Spans are stored and later reused. - TextComponentContextFingerprint.also { - it.resolve( - context, - TextComponentConstructorFingerprint.result!!.classDef - ) - }.result?.also { result -> - if (!TextComponentAtomicReferenceFingerprint.resolve(context, result.method, result.classDef)) - throw TextComponentAtomicReferenceFingerprint.toErrorResult() - }?.let { textComponentContextFingerprintResult -> - val conversionContextIndex = textComponentContextFingerprintResult - .scanResult.patternScanResult!!.startIndex - val atomicReferenceStartIndex = TextComponentAtomicReferenceFingerprint.result!! - .scanResult.patternScanResult!!.startIndex - - textComponentContextFingerprintResult.mutableMethod.apply { - // Get the conversion context obfuscated field name, and the registers for the AtomicReference and CharSequence - val conversionContextFieldReference = - (instruction(conversionContextIndex) as ReferenceInstruction).reference - // any free register - val contextRegister = - (instruction(atomicReferenceStartIndex) as TwoRegisterInstruction).registerB - val atomicReferenceRegister = - (instruction(atomicReferenceStartIndex + 5) as FiveRegisterInstruction).registerC - - val insertIndex = atomicReferenceStartIndex + 8 - val moveCharSequenceInstruction = instruction(insertIndex) as TwoRegisterInstruction - val charSequenceRegister = moveCharSequenceInstruction.registerB - - // Insert as first instructions at the control flow label. - // Must replace the existing instruction to preserve the label, and then insert the remaining instructions. - replaceInstruction(insertIndex, "move-object/from16 v$contextRegister, p0") - addInstructions( - insertIndex + 1, """ - iget-object v$contextRegister, v$contextRegister, $conversionContextFieldReference # copy obfuscated context field into free register - invoke-static {v$contextRegister, v$atomicReferenceRegister, v$charSequenceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; - move-result-object v$charSequenceRegister - move-object v${moveCharSequenceInstruction.registerA}, v${charSequenceRegister} # original instruction at the insertion point - """ - ) - } - } ?: return TextComponentContextFingerprint.toErrorResult() - - // endregion - - // region Hook for Short videos. - - ShortsTextComponentParentFingerprint.result?.let { - context - .toMethodWalker(it.method) - .nextMethod(it.scanResult.patternScanResult!!.endIndex, true) - .getMethod().let { method -> - with(method as MutableMethod) { - // After walking, verify the found method is what's expected. - if (returnType != ("Ljava/lang/CharSequence;") || parameterTypes.size != 1) - return PatchResultError("Method signature did not match: $this $parameterTypes") - - val insertIndex = implementation!!.instructions.size - 1 - val spannedParameterRegister = (instruction(insertIndex) as OneRegisterInstruction).registerA - val parameter = (instruction(insertIndex - 2) as BuilderInstruction35c).reference - - if (!parameter.toString().endsWith("Landroid/text/Spanned;")) - return PatchResultError("Method signature parameter did not match: $parameter") - - insertShorts(insertIndex, spannedParameterRegister) - } - } - - // Additional hook, called after user dislikes. - with(it.mutableMethod) { - val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2 - val overwriteRegister = (implementation!!.instructions.elementAt(insertIndex - 1) - as OneRegisterInstruction).registerA - insertShorts(insertIndex, overwriteRegister) - } - } ?: return ShortsTextComponentParentFingerprint.toErrorResult() - - // endregion - - // region Hook old UI layout dislikes, for the older app spoofs used with spoof-app-version. - - DislikesOldLayoutTextViewFingerprint.result?.let { - it.mutableMethod.apply { - val startIndex = it.scanResult.patternScanResult!!.startIndex - val resourceIdentifierRegister = (instruction(startIndex) as OneRegisterInstruction).registerA - val textViewRegister = (instruction(startIndex + 4) as OneRegisterInstruction).registerA - addInstruction(startIndex + 4, - "invoke-static {v$resourceIdentifierRegister, v$textViewRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setOldUILayoutDislikes(ILandroid/widget/TextView;)V" - ) - } - } ?: return DislikesOldLayoutTextViewFingerprint.toErrorResult() - - // endregion - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;" - - private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind) - private data class VotePatch(val fingerprint: MethodFingerprint, val voteKind: Vote) - private enum class Vote(val value: Int) { - LIKE(1), - DISLIKE(-1), - REMOVE_LIKE(0) - } - - private fun MutableMethod.insertShorts(index: Int, register: Int) { - addInstructions( - index, """ - invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->onShortsComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned; - move-result-object v$register - """ - ) - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt deleted file mode 100644 index 41e8eb34a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt +++ /dev/null @@ -1,50 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.Preference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.util.resources.ResourceUtils.mergeStrings - -@DependsOn([SettingsPatch::class]) -@Name("return-youtube-dislike-resource-patch") -@Description("Adds the preferences for Return YouTube Dislike.") -@ReturnYouTubeDislikeCompatibility -@Version("0.0.1") -class ReturnYouTubeDislikeResourcePatch : ResourcePatch { - companion object { - internal var oldUIDislikeId: Long = -1 - } - - override fun execute(context: ResourceContext): PatchResult { - val youtubePackage = "com.google.android.youtube" - SettingsPatch.addPreference( - Preference( - StringResource("revanced_ryd_settings_title", "Return YouTube Dislike"), - Preference.Intent( - youtubePackage, - "ryd_settings", - "com.google.android.libraries.social.licenses.LicenseActivity" - ), - StringResource("revanced_ryd_settings_summary", "Settings for Return YouTube Dislike"), - ) - ) - // merge strings - context.mergeStrings("returnyoutubedislike/host/values/strings.xml") - - oldUIDislikeId = ResourceMappingPatch.resourceMappings.single { - it.type == "id" && it.name == "dislike_button" - }.id - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt deleted file mode 100644 index 00908cd17..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.searchbar.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class WideSearchbarCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/CreateSearchSuggestionsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/CreateSearchSuggestionsFingerprint.kt deleted file mode 100644 index bef00e2f3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/CreateSearchSuggestionsFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.layout.searchbar.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object CreateSearchSuggestionsFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.CONST_4 - ), - strings = listOf("ss_rds") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/SetWordmarkHeaderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/SetWordmarkHeaderFingerprint.kt deleted file mode 100644 index 97cb02215..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/fingerprints/SetWordmarkHeaderFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.searchbar.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object SetWordmarkHeaderFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_STATIC, - ), - customFingerprint = { methodDef -> methodDef.parameterTypes.first() == "Landroid/widget/ImageView;" } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/patch/WideSearchbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/patch/WideSearchbarPatch.kt deleted file mode 100644 index 62bd87fe9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/patch/WideSearchbarPatch.kt +++ /dev/null @@ -1,88 +0,0 @@ -package app.revanced.patches.youtube.layout.searchbar.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.searchbar.annotations.WideSearchbarCompatibility -import app.revanced.patches.youtube.layout.searchbar.fingerprints.CreateSearchSuggestionsFingerprint -import app.revanced.patches.youtube.layout.searchbar.fingerprints.SetWordmarkHeaderFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("wide-searchbar") -@Description("Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.") -@WideSearchbarCompatibility -@Version("0.0.1") -class WideSearchbarPatch : BytecodePatch( - listOf( - SetWordmarkHeaderFingerprint, CreateSearchSuggestionsFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_wide_searchbar", - StringResource("revanced_wide_searchbar_enabled_title", "Enable wide search bar"), - false, - StringResource("revanced_wide_searchbar_summary_on", "Wide search bar is enabled"), - StringResource("revanced_wide_searchbar_summary_off", "Wide search bar is disabled") - ) - ) - - val result = CreateSearchSuggestionsFingerprint.result ?: return CreateSearchSuggestionsFingerprint.toErrorResult() - - // patch methods - mapOf( - SetWordmarkHeaderFingerprint to 1, - CreateSearchSuggestionsFingerprint to result.scanResult.patternScanResult!!.startIndex - ).forEach { (fingerprint, callIndex) -> - context.walkMutable(callIndex, fingerprint).injectSearchBarHook() - } - - return PatchResultSuccess() - } - - private companion object { - /** - * Walk a fingerprints method at a given index mutably. - * - * @param index The index to walk at. - * @param fromFingerprint The fingerprint to walk the method on. - * @return The [MutableMethod] which was walked on. - */ - fun BytecodeContext.walkMutable(index: Int, fromFingerprint: MethodFingerprint) = - fromFingerprint.result?.let { - toMethodWalker(it.method).nextMethod(index, true).getMethod() as MutableMethod - } ?: throw fromFingerprint.toErrorResult() - - - /** - * Injects instructions required for certain methods. - * - */ - fun MutableMethod.injectSearchBarHook() { - addInstructions( - implementation!!.instructions.size - 1, - """ - invoke-static {}, Lapp/revanced/integrations/patches/WideSearchbarPatch;->enableWideSearchbar()Z - move-result p0 - """ - ) - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt deleted file mode 100644 index fa5230cc3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.layout.sponsorblock.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package("com.google.android.youtube", arrayOf("18.08.37", "18.15.40"))] -) -@Target(AnnotationTarget.CLASS) -internal annotation class SponsorBlockCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/AppendTimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/AppendTimeFingerprint.kt deleted file mode 100644 index 2c6d4720c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/AppendTimeFingerprint.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object AppendTimeFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L", "L", "L"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/PlayerOverlaysLayoutInitFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/PlayerOverlaysLayoutInitFingerprint.kt deleted file mode 100644 index 975bdfe7a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/PlayerOverlaysLayoutInitFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PlayerOverlaysLayoutInitFingerprint : MethodFingerprint( - - customFingerprint = { methodDef -> methodDef.returnType.endsWith("YouTubePlayerOverlaysLayout;") } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/RectangleFieldInvalidatorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/RectangleFieldInvalidatorFingerprint.kt deleted file mode 100644 index 822484a89..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/RectangleFieldInvalidatorFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.MethodReference - -object RectangleFieldInvalidatorFingerprint : MethodFingerprint( - "V", - customFingerprint = custom@{ methodDef -> - val instructions = methodDef.implementation?.instructions!! - val instructionCount = instructions.count() - - // the method has definitely more than 5 instructions - if (instructionCount < 5) return@custom false - - val referenceInstruction = instructions.elementAt(instructionCount - 2) // the second to last instruction - val reference = ((referenceInstruction as? ReferenceInstruction)?.reference as? MethodReference) - - reference?.parameterTypes?.size == 1 && reference.name == "invalidate" // the reference is the invalidate(..) method - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt deleted file mode 100644 index 931fbfd56..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt +++ /dev/null @@ -1,297 +0,0 @@ -package app.revanced.patches.youtube.layout.sponsorblock.bytecode.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.fingerprints.SeekbarFingerprint -import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility -import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.AppendTimeFingerprint -import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.PlayerOverlaysLayoutInitFingerprint -import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.RectangleFieldInvalidatorFingerprint -import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch -import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatFingerprint -import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch -import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch -import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch -import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.* -import org.jf.dexlib2.iface.instruction.formats.Instruction35c -import org.jf.dexlib2.iface.reference.FieldReference -import org.jf.dexlib2.iface.reference.MethodReference -import org.jf.dexlib2.iface.reference.StringReference - -@Patch -@DependsOn( - dependencies = [ - IntegrationsPatch::class, - VideoIdPatch::class, - // Required to skip segments on time. - VideoInformationPatch::class, - // Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts. - PlayerTypeHookPatch::class, - PlayerControlsBytecodePatch::class, - SponsorBlockResourcePatch::class, - ] -) -@Name("sponsorblock") -@Description("Integrates SponsorBlock which allows skipping video segments such as sponsored content.") -@SponsorBlockCompatibility -@Version("0.0.1") -class SponsorBlockBytecodePatch : BytecodePatch( - listOf( - SeekbarFingerprint, - AppendTimeFingerprint, - PlayerOverlaysLayoutInitFingerprint, - AutoRepeatParentFingerprint, - ) -) { - - private companion object { - const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;" - const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;" - const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;" - const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;" - } - - override fun execute(context: BytecodeContext): PatchResult { - /* - * Hook the video time methods - */ - with(VideoInformationPatch) { - videoTimeHook( - INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, - "setVideoTime" - ) - } - - /* - * Set current video id - */ - VideoIdPatch.injectCallBackgroundPlay("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V") - - /* - * Seekbar drawing - */ - val seekbarSignatureResult = SeekbarFingerprint.result!!.let { - SeekbarOnDrawFingerprint.apply { resolve(context, it.mutableClass) } - }.result!! - val seekbarMethod = seekbarSignatureResult.mutableMethod - val seekbarMethodInstructions = seekbarMethod.implementation!!.instructions - - /* - * Get the instance of the seekbar rectangle - */ - for ((index, instruction) in seekbarMethodInstructions.withIndex()) { - if (instruction.opcode != Opcode.MOVE_OBJECT_FROM16) continue - seekbarMethod.addInstruction( - index + 1, - "invoke-static/range {p0 .. p0}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V" - ) - break - } - - for ((index, instruction) in seekbarMethodInstructions.withIndex()) { - if (instruction.opcode != Opcode.INVOKE_STATIC) continue - - val invokeInstruction = instruction as Instruction35c - if ((invokeInstruction.reference as MethodReference).name != "round") continue - - val insertIndex = index + 2 - - // set the thickness of the segment - seekbarMethod.addInstruction( - insertIndex, - "invoke-static {v${invokeInstruction.registerC}}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V" - ) - break - } - - /* - * Set rectangle absolute left and right positions - */ - val drawRectangleInstructions = seekbarMethodInstructions.withIndex().filter { (_, instruction) -> - instruction is ReferenceInstruction && (instruction.reference as? MethodReference)?.name == "drawRect" - }.map { (index, instruction) -> // TODO: improve code - index to (instruction as FiveRegisterInstruction).registerD - } - - val (indexRight, rectangleRightRegister) = drawRectangleInstructions[0] - val (indexLeft, rectangleLeftRegister) = drawRectangleInstructions[3] - - // order of operation is important here due to the code above which has to be improved - // the reason for that is that we get the index, add instructions and then the offset would be wrong - seekbarMethod.addInstruction( - indexLeft + 1, - "invoke-static {v$rectangleLeftRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteLeft(Landroid/graphics/Rect;)V" - ) - seekbarMethod.addInstruction( - indexRight + 1, - "invoke-static {v$rectangleRightRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteRight(Landroid/graphics/Rect;)V" - ) - - /* - * Draw segment - */ - - // Find the drawCircle call and draw the segment before it - for (i in seekbarMethodInstructions.size - 1 downTo 0) { - val invokeInstruction = seekbarMethodInstructions[i] as? ReferenceInstruction ?: continue - if ((invokeInstruction.reference as MethodReference).name != "drawCircle") continue - - val (canvasInstance, centerY) = (invokeInstruction as FiveRegisterInstruction).let { - it.registerC to it.registerE - } - seekbarMethod.addInstruction( - i, - "invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V" - ) - - break - } - - /* - * Voting & Shield button - */ - val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult - - val controlsLayoutStubResourceId = - ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id - val zoomOverlayResourceId = - ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id - - methods@ for (method in controlsMethodResult.mutableClass.methods) { - val instructions = method.implementation?.instructions!! - instructions@ for ((index, instruction) in instructions.withIndex()) { - // search for method which inflates the controls layout view - if (instruction.opcode != Opcode.CONST) continue@instructions - - when ((instruction as NarrowLiteralInstruction).wideLiteral) { - controlsLayoutStubResourceId -> { - // replace the view with the YouTubeControlsOverlay - val moveResultInstructionIndex = index + 5 - val inflatedViewRegister = - (instructions[moveResultInstructionIndex] as OneRegisterInstruction).registerA - // initialize with the player overlay object - method.addInstructions( - moveResultInstructionIndex + 1, // insert right after moving the view to the register and use that register - """ - invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Ljava/lang/Object;)V - invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Ljava/lang/Object;)V - """ - ) - } - - zoomOverlayResourceId -> { - val invertVisibilityMethod = - context.toMethodWalker(method).nextMethod(index - 6, true).getMethod() as MutableMethod - // change visibility of the buttons - invertVisibilityMethod.addInstructions( - 0, """ - invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V - invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V - """.trimIndent() - ) - } - } - } - } - - // change visibility of the buttons - PlayerControlsBytecodePatch.injectVisibilityCheckCall("$INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibility(Z)V") - PlayerControlsBytecodePatch.injectVisibilityCheckCall("$INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibility(Z)V") - - // append the new time to the player layout - val appendTimeFingerprintResult = AppendTimeFingerprint.result!! - val appendTimePatternScanStartIndex = appendTimeFingerprintResult.scanResult.patternScanResult!!.startIndex - val targetRegister = - (appendTimeFingerprintResult.method.implementation!!.instructions.elementAt(appendTimePatternScanStartIndex + 1) as OneRegisterInstruction).registerA - - appendTimeFingerprintResult.mutableMethod.addInstructions( - appendTimePatternScanStartIndex + 2, """ - invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$targetRegister - """ - ) - - // initialize the player controller - VideoInformationPatch.onCreateHook(INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, "initialize") - - // initialize the sponsorblock view - PlayerOverlaysLayoutInitFingerprint.result!!.mutableMethod.addInstruction( - 6, // after inflating the view - "invoke-static {p0}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Ljava/lang/Object;)V" - ) - - // get rectangle field name - RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef) - val rectangleFieldInvalidatorInstructions = - RectangleFieldInvalidatorFingerprint.result!!.method.implementation!!.instructions - val rectangleFieldName = - ((rectangleFieldInvalidatorInstructions.elementAt(rectangleFieldInvalidatorInstructions.count() - 3) as ReferenceInstruction).reference as FieldReference).name - - // replace the "replaceMeWith*" strings - context - .proxy(context.classes.first { it.type.endsWith("SegmentPlaybackController;") }) - .mutableClass - .methods - .find { it.name == "setSponsorBarRect" } - ?.let { method -> - fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) { - val register = (instruction as OneRegisterInstruction).registerA - this.replaceInstruction( - index, "const-string v$register, \"$with\"" - ) - } - for ((index, it) in method.implementation!!.instructions.withIndex()) { - if (it.opcode.ordinal != Opcode.CONST_STRING.ordinal) continue - - when (((it as ReferenceInstruction).reference as StringReference).string) { - "replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction( - index, - it, - rectangleFieldName - ) - } - } - } ?: return PatchResultError("Could not find the method which contains the replaceMeWith* strings") - - - // The vote and create segment buttons automatically change their visibility when appropriate, - // but if buttons are showing when the end of the video is reached then they will not automatically hide. - // Add a hook to forcefully hide when the end of the video is reached. - AutoRepeatParentFingerprint.result ?: return AutoRepeatParentFingerprint.toErrorResult() - AutoRepeatFingerprint.also { - it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef) - }.result?.mutableMethod?.addInstruction( - 0, - "invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V" - ) ?: return AutoRepeatFingerprint.toErrorResult() - - // TODO: isSBChannelWhitelisting implementation - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt deleted file mode 100644 index 7c59a9ace..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt +++ /dev/null @@ -1,108 +0,0 @@ -package app.revanced.patches.youtube.layout.sponsorblock.resource.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.impl.Preference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources -import app.revanced.util.resources.ResourceUtils.copyXmlNode -import app.revanced.util.resources.ResourceUtils.mergeStrings - -@Name("sponsorblock-resource-patch") -@SponsorBlockCompatibility -@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) -@Version("0.0.1") -class SponsorBlockResourcePatch : ResourcePatch { - - override fun execute(context: ResourceContext): PatchResult { - val youtubePackage = "com.google.android.youtube" - SettingsPatch.addPreference( - Preference( - StringResource("sb_settings", "SponsorBlock"), - Preference.Intent( - youtubePackage, - "sponsorblock_settings", - "com.google.android.libraries.social.licenses.LicenseActivity" - ), - StringResource("revanced_sponsorblock_settings_summary", "SponsorBlock related settings"), - ) - ) - val classLoader = this.javaClass.classLoader - - /* - merge SponsorBlock strings to main strings - */ - context.mergeStrings("sponsorblock/host/values/strings.xml") - - /* - merge SponsorBlock drawables to main drawables - */ - - arrayOf( - ResourceUtils.ResourceGroup( - "layout", - "inline_sponsor_overlay.xml", - "new_segment.xml", - "skip_sponsor_button.xml" - ), - ResourceUtils.ResourceGroup( - // required resource for back button, because when the base APK is used, this resource will not exist - "drawable", - "ic_sb_adjust.xml", - "ic_sb_compare.xml", - "ic_sb_edit.xml", - "ic_sb_logo.xml", - "ic_sb_publish.xml", - "ic_sb_voting.xml" - ), - ResourceUtils.ResourceGroup( - // required resource for back button, because when the base APK is used, this resource will not exist - "drawable-xxxhdpi", "quantum_ic_skip_next_white_24.png" - ) - ).forEach { resourceGroup -> - context.copyResources("sponsorblock", resourceGroup) - } - - /* - merge xml nodes from the host to their real xml files - */ - - // copy nodes from host resources to their real xml files - val hostingResourceStream = - classLoader.getResourceAsStream("sponsorblock/host/layout/youtube_controls_layout.xml")!! - - val targetXmlEditor = context.xmlEditor["res/layout/youtube_controls_layout.xml"] - "RelativeLayout".copyXmlNode( - context.xmlEditor[hostingResourceStream], - targetXmlEditor - ).also { - val children = targetXmlEditor.file.getElementsByTagName("RelativeLayout").item(0).childNodes - - // Replace the startOf with the voting button view so that the button does not overlap - for (i in 1 until children.length) { - val view = children.item(i) - - // Replace the attribute for a specific node only - if (!(view.hasAttributes() && view.attributes.getNamedItem("android:id").nodeValue.endsWith("live_chat_overlay_button"))) continue - - // voting button id from the voting button view from the youtube_controls_layout.xml host file - val votingButtonId = "@+id/sb_voting_button" - - view.attributes.getNamedItem("android:layout_toStartOf").nodeValue = votingButtonId - - break - } - }.close() // close afterwards - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt deleted file mode 100644 index 88864d534..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.layout.spoofappversion.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class SpoofAppVersionCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/fingerprints/SpoofAppVersionFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/fingerprints/SpoofAppVersionFingerprint.kt deleted file mode 100644 index 8a5736f12..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/fingerprints/SpoofAppVersionFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.youtube.layout.spoofappversion.bytecode.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object SpoofAppVersionFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf( - Opcode.IGET_OBJECT, - Opcode.GOTO, - Opcode.CONST_STRING, - ), - - // Instead of applying a bytecode patch, it might be possible to only rely on code from the integrations and - // manually set the desired version string as this keyed value in the SharedPreferences. - // But, this bytecode patch is simple and it works. - strings = listOf("pref_override_build_version_name") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt deleted file mode 100644 index add8947a6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt +++ /dev/null @@ -1,94 +0,0 @@ -package app.revanced.patches.youtube.layout.spoofappversion.bytecode.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.ListPreference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.spoofappversion.annotations.SpoofAppVersionCompatibility -import app.revanced.patches.youtube.layout.spoofappversion.bytecode.fingerprints.SpoofAppVersionFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@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.") -@SpoofAppVersionCompatibility -@Version("0.0.1") -class SpoofAppVersionPatch : BytecodePatch( - listOf( - SpoofAppVersionFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_spoof_app_version", - StringResource("revanced_spoof_app_version_title", "Spoof app version"), - false, - StringResource("revanced_spoof_app_version_summary_on", "Version spoofed"), - StringResource("revanced_spoof_app_version_summary_off", "Version not spoofed"), - StringResource("revanced_spoof_app_version_user_dialog_message", - "App version will be spoofed to an older version of YouTube. This will change the appearance of the app, but unknown side effects may occur." - + " If later turned off, the old UI may remain until you log out or clear the app data.") - ), - ListPreference( - "revanced_spoof_app_version_target", - StringResource( - "revanced_spoof_app_version_target_title", - "Spoof app version target" - ), - ArrayResource( - "revanced_spoof_app_version_target_entries", - listOf( - StringResource("revanced_spoof_app_version_target_entry_1", "17.30.35 - Restore old UI layout"), - StringResource("revanced_spoof_app_version_target_entry_2", "17.01.35 - Enable sorting videos by oldest"), - StringResource("revanced_spoof_app_version_target_entry_3", "16.08.35 - Restore explore tab"), - StringResource("revanced_spoof_app_version_target_entry_4", "16.01.35 - Restore old shorts player"), - ) - ), - ArrayResource( - "revanced_spoof_app_version_target_entry_values", - listOf( - StringResource("revanced_spoof_app_version_target_entry_value_1", "17.30.35"), - StringResource("revanced_spoof_app_version_target_entry_value_2", "17.01.35"), - StringResource("revanced_spoof_app_version_target_entry_value_3", "16.08.35"), - StringResource("revanced_spoof_app_version_target_entry_value_4", "16.01.35"), - ) - ) - ) - ) - - SpoofAppVersionFingerprint.result?.apply { - val insertIndex = scanResult.patternScanResult!!.startIndex + 1 - val buildOverrideNameRegister = - (mutableMethod.implementation!!.instructions[insertIndex - 1] as OneRegisterInstruction).registerA - - mutableMethod.addInstructions( - insertIndex, - """ - invoke-static {v$buildOverrideNameRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR;->getYouTubeVersionOverride(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$buildOverrideNameRegister - """ - ) - } ?: return SpoofAppVersionFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SpoofAppVersionPatch" - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt deleted file mode 100644 index 99cecd5fa..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.startupshortsreset.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class StartupShortsResetCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/fingerprints/UserWasInShortsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/fingerprints/UserWasInShortsFingerprint.kt deleted file mode 100644 index a994a26d6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/fingerprints/UserWasInShortsFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.layout.startupshortsreset.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(3) -object UserWasInShortsFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - ), - strings = listOf("Failed to read user_was_in_shorts proto after successful warmup"), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/patch/DisableShortsOnStartupPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/patch/DisableShortsOnStartupPatch.kt deleted file mode 100644 index af2fae09c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/patch/DisableShortsOnStartupPatch.kt +++ /dev/null @@ -1,59 +0,0 @@ -package app.revanced.patches.youtube.layout.startupshortsreset.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.startupshortsreset.annotations.StartupShortsResetCompatibility -import app.revanced.patches.youtube.layout.startupshortsreset.fingerprints.UserWasInShortsFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("disable-shorts-on-startup") -@Description("Disables playing YouTube Shorts when launching YouTube.") -@StartupShortsResetCompatibility -@Version("0.0.1") -class DisableShortsOnStartupPatch : BytecodePatch( - listOf( - UserWasInShortsFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_startup_shorts_player_enabled", - StringResource("revanced_startup_shorts_player_title", "Disable shorts player at app startup"), - false, - StringResource("revanced_startup_shorts_player_summary_on", "Shorts player is disabled at app startup"), - StringResource("revanced_startup_shorts_player_summary_off", "Shorts player is enabled at app startup") - ) - ) - - val userWasInShortsResult = UserWasInShortsFingerprint.result!! - val userWasInShortsMethod = userWasInShortsResult.mutableMethod - val moveResultIndex = userWasInShortsResult.scanResult.patternScanResult!!.endIndex - - userWasInShortsMethod.addInstructions( - moveResultIndex + 1, """ - invoke-static { }, Lapp/revanced/integrations/patches/DisableStartupShortsPlayerPatch;->disableStartupShortsPlayer()Z - move-result v5 - if-eqz v5, :disable_shorts_player - return-void - :disable_shorts_player - nop - """ - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt deleted file mode 100644 index c0fef1f1b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube", arrayOf("18.15.40"))]) -@Target(AnnotationTarget.CLASS) -internal annotation class TabletMiniPlayerCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt deleted file mode 100644 index 247655248..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) -object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.FLOAT_TO_DOUBLE, - Opcode.CONST_WIDE_HIGH16, - Opcode.CMPL_DOUBLE, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt deleted file mode 100644 index 59350da28..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object MiniPlayerOverrideFingerprint : MethodFingerprint( - "Z", AccessFlags.STATIC or AccessFlags.PUBLIC, - opcodes = listOf(Opcode.RETURN), // anchor to insert the instruction -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideNoContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideNoContextFingerprint.kt deleted file mode 100644 index aba50b3d4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideNoContextFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint( - "Z", AccessFlags.FINAL or AccessFlags.PRIVATE, - opcodes = listOf(Opcode.RETURN), // anchor to insert the instruction -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt deleted file mode 100644 index 14593d31f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - - -object MiniPlayerOverrideParentFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("L"), - strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt deleted file mode 100644 index e4777c4c1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerResponseModelSizeCheckFingerprint.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object MiniPlayerResponseModelSizeCheckFingerprint : MethodFingerprint( - "L", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L", "L"), - listOf( - Opcode.RETURN_OBJECT, - Opcode.CHECK_CAST, - Opcode.CHECK_CAST, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt deleted file mode 100644 index 8769448d1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt +++ /dev/null @@ -1,112 +0,0 @@ -package app.revanced.patches.youtube.layout.tabletminiplayer.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.* -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -@Name("tablet-mini-player") -@Description("Enables the tablet mini player layout.") -@TabletMiniPlayerCompatibility -@Version("0.0.1") -class TabletMiniPlayerPatch : BytecodePatch( - listOf( - MiniPlayerDimensionsCalculatorFingerprint, - MiniPlayerResponseModelSizeCheckFingerprint, - MiniPlayerOverrideParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( - SwitchPreference( - "revanced_tablet_miniplayer", - StringResource("revanced_tablet_miniplayer_title", "Enable tablet mini player"), - false, - StringResource("revanced_tablet_miniplayer_summary_on", "Mini player is enabled"), - StringResource("revanced_tablet_miniplayer_summary_off", "Mini player is disabled") - ) - ) - - // First resolve the fingerprints via the parent fingerprint. - val miniPlayerClass = MiniPlayerDimensionsCalculatorFingerprint.result!!.classDef - - /* - * No context parameter method. - */ - MiniPlayerOverrideNoContextFingerprint.resolve(context, miniPlayerClass) - val (method, _, parameterRegister) = MiniPlayerOverrideNoContextFingerprint.addProxyCall() - - // Insert right before the return instruction. - val secondInsertIndex = method.implementation!!.instructions.size - 1 - method.insertOverride( - secondInsertIndex, parameterRegister - /** same register used to return **/ - ) - - /* - * Method with context parameter. - */ - MiniPlayerOverrideParentFingerprint.result?.let { - if (!MiniPlayerOverrideFingerprint.resolve(context, it.classDef)) - throw MiniPlayerOverrideFingerprint.toErrorResult() - - MiniPlayerOverrideFingerprint.addProxyCall() - } ?: return MiniPlayerOverrideParentFingerprint.toErrorResult() - - /* - * Size check return value override. - */ - MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall() - - return PatchResultSuccess() - } - - // Helper methods. - private companion object { - fun MethodFingerprint.addProxyCall(): Triple { - val (method, scanIndex, parameterRegister) = this.unwrap() - method.insertOverride(scanIndex, parameterRegister) - - return Triple(method, scanIndex, parameterRegister) - } - - fun MutableMethod.insertOverride(index: Int, overrideRegister: Int) { - this.addInstructions( - index, - """ - invoke-static {v$overrideRegister}, Lapp/revanced/integrations/patches/TabletMiniPlayerOverridePatch;->getTabletMiniPlayerOverride(Z)Z - move-result v$overrideRegister - """ - ) - } - - fun MethodFingerprint.unwrap(): Triple { - val result = this.result!! - val scanIndex = result.scanResult.patternScanResult!!.endIndex - val method = result.mutableMethod - val instructions = method.implementation!!.instructions - val parameterRegister = (instructions[scanIndex] as OneRegisterInstruction).registerA - - return Triple(method, scanIndex, parameterRegister) - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/annotations/ThemeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/annotations/ThemeCompatibility.kt deleted file mode 100644 index 0ca6ded20..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/annotations/ThemeCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.theme.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class ThemeCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/fingerprints/LithoThemeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/fingerprints/LithoThemeFingerprint.kt deleted file mode 100644 index ba6e29cf5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/fingerprints/LithoThemeFingerprint.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.youtube.layout.theme.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object LithoThemeFingerprint : MethodFingerprint( - "V", AccessFlags.PROTECTED or AccessFlags.FINAL, listOf("L"), listOf( - Opcode.APUT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IPUT_OBJECT, - Opcode.IGET, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/LithoThemePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/LithoThemePatch.kt deleted file mode 100644 index 6575ff4ec..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/LithoThemePatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.youtube.layout.theme.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility -import app.revanced.patches.youtube.layout.theme.fingerprints.LithoThemeFingerprint - -@Name("litho-components-theme") -@Description("Applies a custom theme to litho components.") -@ThemeCompatibility -@Version("0.0.1") -class LithoThemePatch : BytecodePatch( - listOf( - LithoThemeFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val result = LithoThemeFingerprint.result!! - val method = result.mutableMethod - val patchIndex = result.scanResult.patternScanResult!!.endIndex - 1 - - method.addInstructions( - patchIndex, """ - invoke-static {p1}, Lapp/revanced/integrations/patches/LithoThemePatch;->applyLithoTheme(I)I - move-result p1 - """ - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt deleted file mode 100644 index 8bc9c1c1c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt +++ /dev/null @@ -1,81 +0,0 @@ -package app.revanced.patches.youtube.layout.theme.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources -import org.w3c.dom.Element - -@Patch -@DependsOn([LithoThemePatch::class]) -@Name("theme") -@Description("Applies a custom theme.") -@ThemeCompatibility -@Version("0.0.1") -class ThemePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - val darkThemeBackgroundColor = darkThemeBackgroundColor!! - val lightThemeBackgroundColor = lightThemeBackgroundColor!! - val darkThemeSeekbarColor = darkThemeSeekbarColor!! - - context.xmlEditor["res/values/colors.xml"].use { editor -> - val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element - - for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as? Element ?: continue - - node.textContent = when (node.getAttribute("name")) { - "yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3", "yt_black4", "yt_status_bar_background_dark", "material_grey_850" -> darkThemeBackgroundColor - - "yt_white1", "yt_white1_opacity95", "yt_white1_opacity98", "yt_white2", "yt_white3", "yt_white4", - -> lightThemeBackgroundColor - - "inline_time_bar_colorized_bar_played_color_dark" -> darkThemeSeekbarColor - else -> continue - } - } - } - - // copies the resource file to change the splash screen color - context.copyResources( - "theme", ResourceUtils.ResourceGroup("values-night-v31", "styles.xml") - ) - - return PatchResultSuccess() - } - - companion object : OptionsContainer() { - var darkThemeBackgroundColor: String? by option( - PatchOption.StringOption( - 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.", - ) - ) - - var lightThemeBackgroundColor: String? by option( - PatchOption.StringOption( - 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.", - ) - ) - - var darkThemeSeekbarColor: String? by option( - PatchOption.StringOption( - key = "darkThemeSeekbarColor", - default = "#ffff0000", - title = "Dark theme seekbar color", - description = "The background color of the seekbar of the dark theme. Leave empty for default color.", - ) - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt deleted file mode 100644 index 24f13f952..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.autorepeat.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class AutoRepeatCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/fingerprints/AutoRepeatFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/fingerprints/AutoRepeatFingerprint.kt deleted file mode 100644 index a16683b14..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/fingerprints/AutoRepeatFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.misc.autorepeat.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object AutoRepeatFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf(), - customFingerprint = { methodDef -> methodDef.implementation!!.instructions.count() == 3 && methodDef.annotations.isEmpty()} -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/fingerprints/AutoRepeatParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/fingerprints/AutoRepeatParentFingerprint.kt deleted file mode 100644 index 81d6b0083..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/fingerprints/AutoRepeatParentFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.youtube.misc.autorepeat.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object AutoRepeatParentFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - strings = listOf( - "play() called when the player wasn't loaded.", - "play() blocked because Background Playability failed" - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/patch/AutoRepeatPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/patch/AutoRepeatPatch.kt deleted file mode 100644 index 38617967d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/patch/AutoRepeatPatch.kt +++ /dev/null @@ -1,88 +0,0 @@ -package app.revanced.patches.youtube.misc.autorepeat.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.removeInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility -import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatFingerprint -import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference - -@Patch -@DependsOn([IntegrationsPatch::class]) -@Name("always-autorepeat") -@Description("Always repeats the playing video again.") -@AutoRepeatCompatibility -@Version("0.0.1") -class AutoRepeatPatch : BytecodePatch( - listOf( - AutoRepeatParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - SwitchPreference( - "revanced_pref_auto_repeat", - StringResource("revanced_auto_repeat_enabled_title", "Enable auto-repeat"), - false, - StringResource("revanced_auto_repeat_summary_on", "Auto-repeat is enabled"), - StringResource("revanced_auto_repeat_summary_off", "Auto-repeat is disabled") - ) - ) - - //Get Result from the ParentFingerprint which is the playMethod we need to get. - val parentResult = AutoRepeatParentFingerprint.result - ?: return PatchResultError("ParentFingerprint did not resolve.") - - //this one needs to be called when app/revanced/integrations/patches/AutoRepeatPatch;->shouldAutoRepeat() returns true - val playMethod = parentResult.mutableMethod - AutoRepeatFingerprint.resolve(context, parentResult.classDef) - //String is: Laamp;->E()V - val methodToCall = playMethod.definingClass + "->" + playMethod.name + "()V"; - - //This is the method we search for - val result = AutoRepeatFingerprint.result - ?: return PatchResultError("FingerPrint did not resolve.") - val method = result.mutableMethod - - //Instructions to add to the smali code - val instructions = """ - invoke-static {}, Lapp/revanced/integrations/patches/AutoRepeatPatch;->shouldAutoRepeat()Z - move-result v0 - if-eqz v0, :noautorepeat - invoke-virtual {p0}, $methodToCall - :noautorepeat - return-void - """ - - //Get the implementation so we can do a check for null and get instructions size. - val implementation = method.implementation - ?: return PatchResultError("No Method Implementation found!") - - //Since addInstructions needs an index which starts counting at 0 and size starts counting at 1, - //we have to remove 1 to get the latest instruction - val index = implementation.instructions.size - 1 - - - //remove last instruction which is return-void - method.removeInstruction(index) - // Add our own instructions there - method.addInstructions(index, instructions) - - //Everything worked as expected, return Success - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/annotations/DebuggingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/annotations/DebuggingCompatibility.kt deleted file mode 100644 index c905ea588..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/annotations/DebuggingCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.debugging.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class DebuggingCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt deleted file mode 100644 index ef0dba238..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt +++ /dev/null @@ -1,71 +0,0 @@ -package app.revanced.patches.youtube.misc.debugging.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.all.misc.debugging.patch.EnableAndroidDebuggingPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.debugging.annotations.DebuggingCompatibility -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch - -@Patch -@Name("enable-debugging") -@DependsOn([IntegrationsPatch::class, SettingsPatch::class, EnableAndroidDebuggingPatch::class]) -@Description("Adds debugging options.") -@DebuggingCompatibility -@Version("0.0.2") -class DebuggingPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - app.revanced.patches.shared.settings.preference.impl.PreferenceScreen( - "revanced_debug", - StringResource("revanced_debug_title", "Debugging"), - listOf( - SwitchPreference( - "revanced_debug_enabled", - StringResource("revanced_debug_enabled_title", "Debug logging"), - false, - StringResource("revanced_debug_summary_on", "Debug logs are enabled"), - StringResource("revanced_debug_summary_off", "Debug logs are disabled") - ), - SwitchPreference( - "revanced_debug_stacktrace_enabled", - StringResource( - "revanced_debug_stacktrace_enabled_title", - "Log stack traces" - ), - false, - StringResource("revanced_debug_stacktrace_summary_on", "Debug logs include stack trace"), - StringResource("revanced_debug_stacktrace_summary_off", "Debug logs do not include stack trace") - ), - SwitchPreference( - "revanced_debug_toast_on_error_enabled", - StringResource( - "revanced_debug_toast_on_error_enabled_title", - "Show toast on ReVanced error" - ), - true, - StringResource("revanced_debug_toast_on_error_summary_on", "Toast shown if error occurs"), - StringResource("revanced_debug_toast_on_error_summary_off", "Toast not shown if error occurs"), - StringResource("revanced_debug_toast_on_error_user_dialog_message", - "Turning off error toasts hides all ReVanced error notifications." + - " This includes hiding normal network connection timeouts, " + - "but also hides notification of any unexpected and more serious errors." - ) - ), - ), - StringResource("revanced_debug_summary", "Enable or disable debugging options") - ) - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt deleted file mode 100644 index aef6513c4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.backtoexitgesture.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class FixBackToExitGestureCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/OnBackPressedFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/OnBackPressedFingerprint.kt deleted file mode 100644 index 010fd65ca..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/OnBackPressedFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object OnBackPressedFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.RETURN_VOID - ), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("WatchWhileActivity;") - && methodDef.name == "onBackPressed" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewScrollingFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewScrollingFingerprint.kt deleted file mode 100644 index 7307d9abc..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewScrollingFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object RecyclerViewScrollingFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_LEZ, - Opcode.IGET_OBJECT, - Opcode.CONST_4, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingFingerprint.kt deleted file mode 100644 index 994436544..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingFingerprint.kt +++ /dev/null @@ -1,27 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object RecyclerViewTopScrollingFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.GOTO, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingParentFingerprint.kt deleted file mode 100644 index 09964ba5f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/fingerprints/RecyclerViewTopScrollingParentFingerprint.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST_16, - Opcode.INVOKE_VIRTUAL, - Opcode.NEW_INSTANCE - ), - customFingerprint = { methodDef -> - methodDef.name == "" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/patch/FixBackToExitGesturePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/patch/FixBackToExitGesturePatch.kt deleted file mode 100644 index a24b5db16..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/patch/FixBackToExitGesturePatch.kt +++ /dev/null @@ -1,86 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.backtoexitgesture.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.youtube.misc.fix.backtoexitgesture.annotation.FixBackToExitGestureCompatibility -import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.OnBackPressedFingerprint -import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.RecyclerViewScrollingFingerprint -import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.RecyclerViewTopScrollingFingerprint -import app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints.RecyclerViewTopScrollingParentFingerprint - -@Description("Fixes the swipe back to exit gesture.") -@FixBackToExitGestureCompatibility -@Version("0.0.1") -class FixBackToExitGesturePatch : BytecodePatch( - listOf( - RecyclerViewTopScrollingParentFingerprint, - RecyclerViewScrollingFingerprint, - OnBackPressedFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - RecyclerViewTopScrollingFingerprint.apply { - resolve( - context, - RecyclerViewTopScrollingParentFingerprint.result?.classDef - ?: return RecyclerViewTopScrollingParentFingerprint.toErrorResult() - ) - } - - mapOf( - RecyclerViewTopScrollingFingerprint to IntegrationsMethod( - methodName = "onTopView" - ), - RecyclerViewScrollingFingerprint to IntegrationsMethod( - methodName = "onScrollingViews" - ), - OnBackPressedFingerprint to IntegrationsMethod( - "p0", "onBackPressed", "Lcom/google/android/apps/youtube/app/watchwhile/WatchWhileActivity;" - ) - ).forEach { (fingerprint, target) -> - try { - fingerprint.injectCall(target) - } catch (error: PatchResultError) { - return error - } - } - - return PatchResultSuccess() - } - - private companion object { - /** - * A reference to a method from the integrations for [FixBackToExitGesturePatch]. - * - * @param register The method registers. - * @param methodName The method name. - * @param parameterTypes The parameters of the method. - */ - data class IntegrationsMethod( - val register: String = "", val methodName: String, val parameterTypes: String = "" - ) { - override fun toString() = - "invoke-static {$register}, Lapp/revanced/integrations/patches/FixBackToExitGesturePatch;->$methodName($parameterTypes)V" - } - - /** - * Inject a call to a method from the integrations. - * - * @param targetMethod The target method to call. - */ - fun MethodFingerprint.injectCall(targetMethod: IntegrationsMethod) = result?.apply { - mutableMethod.addInstruction( - scanResult.patternScanResult!!.endIndex, targetMethod.toString() - ) - } ?: throw this.toErrorResult() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotation/ProtobufSpoofCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotation/ProtobufSpoofCompatibility.kt deleted file mode 100644 index 5d010ecd0..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotation/ProtobufSpoofCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class ProtobufSpoofCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/OpenCronetDataSourceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/OpenCronetDataSourceFingerprint.kt deleted file mode 100644 index 559ab0ea0..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/OpenCronetDataSourceFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -// Resolves to the method CronetDataSource.open -// https://androidx.tech/artifacts/media3/media3-datasource-cronet/1.0.0-alpha03-source/androidx/media3/datasource/cronet/CronetDataSource.java.html -object OpenCronetDataSourceFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.MOVE_RESULT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - ), - strings = listOf( - "err_cleartext_not_permitted", - ), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/ProtobufParameterBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/ProtobufParameterBuilderFingerprint.kt deleted file mode 100644 index 3b61b09dd..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/ProtobufParameterBuilderFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object ProtobufParameterBuilderFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL_RANGE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT - ), - strings = listOf("Unexpected empty videoId.", "Prefetch request are disabled.") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/SubtitleWindowSettingsConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/SubtitleWindowSettingsConstructorFingerprint.kt deleted file mode 100644 index 0cb104f24..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/SubtitleWindowSettingsConstructorFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SubtitleWindowSettingsConstructorFingerprint : MethodFingerprint( - parameters = listOf("I", "I", "I", "Z", "Z"), - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleWindowSettings;" - && methodDef.name == "" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt deleted file mode 100644 index 242e10fef..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt +++ /dev/null @@ -1,130 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.misc.fix.spoof.patch.ClientSpoofPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.fix.playback.annotation.ProtobufSpoofCompatibility -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.OpenCronetDataSourceFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.SubtitleWindowSettingsConstructorFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@Name("spoof-signature-verification") -@Description("Spoofs a patched client to prevent playback issues.") -@ProtobufSpoofCompatibility -@DependsOn([ - IntegrationsPatch::class, - SettingsPatch::class, - PlayerTypeHookPatch::class, - ClientSpoofPatch::class, - VideoIdPatch::class -]) -@Version("0.0.1") -class SpoofSignatureVerificationPatch : BytecodePatch( - listOf( - ProtobufParameterBuilderFingerprint, - OpenCronetDataSourceFingerprint, - SubtitleWindowSettingsConstructorFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - SwitchPreference( - "revanced_spoof_signature_verification", - StringResource("revanced_spoof_signature_verification_title", "Spoof app signature"), - true, - StringResource("revanced_spoof_signature_verification_summary_on", - "App signature spoofed\\n\\n" - + "Side effects include:\\n" - + "• End screen cards are always hidden\\n" - + "• Download button may be hidden"), - StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"), - StringResource("revanced_spoof_signature_verification_user_dialog_message", - "Turning off this setting may cause playback issues.") - ) - ) - - // Hook video id, required for subtitle fix. - VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V") - - // hook parameter - ProtobufParameterBuilderFingerprint.result?.let { - val setParamMethod = context - .toMethodWalker(it.method) - .nextMethod(it.scanResult.patternScanResult!!.startIndex, true).getMethod() as MutableMethod - - setParamMethod.apply { - val protobufParameterRegister = 3 - - addInstructions( - 0, - """ - invoke-static {p$protobufParameterRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideProtobufParameter(Ljava/lang/String;)Ljava/lang/String; - move-result-object p$protobufParameterRegister - """ - ) - } - } ?: return ProtobufParameterBuilderFingerprint.toErrorResult() - - // hook video playback result - OpenCronetDataSourceFingerprint.result?.let { - it.mutableMethod.apply { - val getHeadersInstructionIndex = it.scanResult.patternScanResult!!.endIndex - val responseCodeRegister = - (instruction(getHeadersInstructionIndex - 2) as OneRegisterInstruction).registerA - - addInstructions( - getHeadersInstructionIndex + 1, - """ - invoke-static {v$responseCodeRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onResponse(I)V - """ - ) - } - - } ?: return OpenCronetDataSourceFingerprint.toErrorResult() - - // hook override subtitles - SubtitleWindowSettingsConstructorFingerprint.result?.let { - it.mutableMethod.apply { - addInstructions( - 0, - """ - invoke-static {p1, p2, p3, p4, p5}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSubtitleWindowSettingsOverride(IIIZZ)[I - move-result-object v0 - const/4 v1, 0x0 - aget p1, v0, v1 # ap, anchor position - const/4 v1, 0x1 - aget p2, v0, v1 # ah, horizontal anchor - const/4 v1, 0x2 - aget p3, v0, v1 # av, vertical anchor - """ - ) - } - } ?: return SubtitleWindowSettingsConstructorFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SpoofSignatureVerificationPatch;" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/annotations/HDRBrightnessCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/annotations/HDRBrightnessCompatibility.kt deleted file mode 100644 index 361aefb71..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/annotations/HDRBrightnessCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.hdrbrightness.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class HDRBrightnessCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/fingerprints/HDRBrightnessFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/fingerprints/HDRBrightnessFingerprint.kt deleted file mode 100644 index 979f4e8a5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/fingerprints/HDRBrightnessFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.hdrbrightness.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object HDRBrightnessFingerprint : MethodFingerprint( - "V", - opcodes = listOf(Opcode.CMPL_FLOAT), - strings = listOf("c.SettingNotFound;", "screen_brightness", "android.mediaview"), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/patch/HDRBrightnessPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/patch/HDRBrightnessPatch.kt deleted file mode 100644 index f84efbee9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/patch/HDRBrightnessPatch.kt +++ /dev/null @@ -1,64 +0,0 @@ -package app.revanced.patches.youtube.misc.hdrbrightness.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.misc.hdrbrightness.annotations.HDRBrightnessCompatibility -import app.revanced.patches.youtube.misc.hdrbrightness.fingerprints.HDRBrightnessFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction -import org.jf.dexlib2.iface.reference.FieldReference - -@Patch -@Name("hdr-auto-brightness") -@Description("Makes the brightness of HDR videos follow the system default.") -@HDRBrightnessCompatibility -@Version("0.0.2") -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) -class HDRBrightnessPatch : BytecodePatch( - listOf(HDRBrightnessFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - SwitchPreference( - "revanced_pref_hdr_autobrightness", - StringResource("revanced_hdr_autobrightness_enabled_title", "Enable auto HDR brightness"), - true, - StringResource("revanced_hdr_autobrightness_summary_on", "Auto HDR brightness is enabled"), - StringResource("revanced_hdr_autobrightness_summary_off", "Auto HDR brightness is disabled") - ) - ) - - val method = HDRBrightnessFingerprint.result!!.mutableMethod - - method.implementation!!.instructions.filter { instruction -> - val fieldReference = (instruction as? ReferenceInstruction)?.reference as? FieldReference - fieldReference?.let { it.name == "screenBrightness" } == true - }.forEach { instruction -> - val brightnessRegisterIndex = method.implementation!!.instructions.indexOf(instruction) - val register = (instruction as TwoRegisterInstruction).registerA - - val insertIndex = brightnessRegisterIndex + 1 - method.addInstructions( - insertIndex, - """ - invoke-static {v$register}, Lapp/revanced/integrations/patches/HDRAutoBrightnessPatch;->getHDRBrightness(F)F - move-result v$register - """ - ) - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt deleted file mode 100644 index 3d152580b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.integrations.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class IntegrationsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/InitFingerprint.kt deleted file mode 100644 index be3b5d8b7..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/InitFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.youtube.misc.integrations.fingerprints - -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint - -object InitFingerprint : IntegrationsFingerprint( - strings = listOf("Application creation", "Application.onCreate"), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/ServiceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/ServiceFingerprint.kt deleted file mode 100644 index 813aaf573..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/ServiceFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.integrations.fingerprints - -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint - -object ServiceFingerprint : IntegrationsFingerprint( - customFingerprint = { methodDef -> methodDef.definingClass.endsWith("ApiPlayerService;") && methodDef.name == "" }, - contextRegisterResolver = { it.implementation!!.registerCount - it.parameters.size } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/StandalonePlayerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/StandalonePlayerFingerprint.kt deleted file mode 100644 index ff7106145..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/StandalonePlayerFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.integrations.fingerprints - -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint - -object StandalonePlayerFingerprint : IntegrationsFingerprint( - strings = listOf( - "Invalid PlaybackStartDescriptor. Returning the instance itself.", - "com.google.android.music", - ), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt deleted file mode 100644 index 6fb114baf..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.misc.integrations.patch - -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.patch.annotations.RequiresIntegrations -import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch -import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility -import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint -import app.revanced.patches.youtube.misc.integrations.fingerprints.ServiceFingerprint -import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerFingerprint - -@Name("integrations") -@IntegrationsCompatibility -@RequiresIntegrations -class IntegrationsPatch : AbstractIntegrationsPatch( - "Lapp/revanced/integrations/utils/ReVancedUtils;", - listOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt deleted file mode 100644 index 737ceabb8..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.links.open.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class OpenLinksExternallyCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/BindSessionServiceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/BindSessionServiceFingerprint.kt deleted file mode 100644 index f7b41a242..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/BindSessionServiceFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.misc.links.open.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object BindSessionServiceFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST_STRING - ), - strings = listOf("android.support.customtabs.action.CustomTabsService") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/GetCustomTabPackageNameFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/GetCustomTabPackageNameFingerprint.kt deleted file mode 100644 index ffacf0355..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/GetCustomTabPackageNameFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.youtube.misc.links.open.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object GetCustomTabPackageNameFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - opcodes = listOf( - Opcode.CHECK_CAST, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.CONST_STRING - ), - strings = listOf("android.support.customtabs.action.CustomTabsService") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/InitializeCustomTabSupportFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/InitializeCustomTabSupportFingerprint.kt deleted file mode 100644 index 0901efbbd..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/InitializeCustomTabSupportFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.youtube.misc.links.open.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object InitializeCustomTabSupportFingerprint : MethodFingerprint( - returnType = "V", - access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - opcodes = listOf( - Opcode.CHECK_CAST, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.CONST_STRING - ), - strings = listOf("android.support.customtabs.action.CustomTabsService") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/patch/OpenLinksExternallyPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/patch/OpenLinksExternallyPatch.kt deleted file mode 100644 index ec2e2b5fa..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/patch/OpenLinksExternallyPatch.kt +++ /dev/null @@ -1,65 +0,0 @@ -package app.revanced.patches.youtube.misc.links.open.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.links.open.annotations.OpenLinksExternallyCompatibility -import app.revanced.patches.youtube.misc.links.open.fingerprints.BindSessionServiceFingerprint -import app.revanced.patches.youtube.misc.links.open.fingerprints.GetCustomTabPackageNameFingerprint -import app.revanced.patches.youtube.misc.links.open.fingerprints.InitializeCustomTabSupportFingerprint -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.iface.instruction.formats.Instruction21c - -@Patch -@Name("open-links-externally") -@Description("Open links outside of the app directly in your browser.") -@OpenLinksExternallyCompatibility -@Version("0.0.1") -class OpenLinksExternallyPatch : BytecodePatch( - listOf( - GetCustomTabPackageNameFingerprint, - BindSessionServiceFingerprint, - InitializeCustomTabSupportFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - SwitchPreference( - "revanced_enable_external_browser", - StringResource("revanced_enable_external_browser_title", "Open links in browser"), - true, - StringResource("revanced_enable_external_browser_summary_on", "Opening links externally"), - StringResource("revanced_enable_external_browser_summary_off", "Opening links in app") - ) - ) - - arrayOf( - GetCustomTabPackageNameFingerprint, - BindSessionServiceFingerprint, - InitializeCustomTabSupportFingerprint - ).forEach { - val result = it.result ?: return it.toErrorResult() - val insertIndex = result.scanResult.patternScanResult!!.endIndex + 1 - with(result.mutableMethod) { - val register = (implementation!!.instructions[insertIndex - 1] as Instruction21c).registerA - addInstructions( - insertIndex, """ - invoke-static {v$register}, Lapp/revanced/integrations/patches/OpenLinksExternallyPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$register - """ - ) - } - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/annotation/LithoFilterCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/annotation/LithoFilterCompatibility.kt deleted file mode 100644 index 40811ebb2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/annotation/LithoFilterCompatibility.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.misc.litho.filter.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class LithoFilterCompatibility - diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt deleted file mode 100644 index 498f7ca25..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.misc.litho.filter.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object ComponentContextParserFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE - ), - strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/EmptyComponentBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/EmptyComponentBuilderFingerprint.kt deleted file mode 100644 index 7c77b9f96..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/EmptyComponentBuilderFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.misc.litho.filter.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object EmptyComponentBuilderFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_INTERFACE, - Opcode.INVOKE_STATIC_RANGE - ), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ReadComponentIdentifierFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ReadComponentIdentifierFingerprint.kt deleted file mode 100644 index b78e48af1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ReadComponentIdentifierFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.misc.litho.filter.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object ReadComponentIdentifierFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.IF_NEZ, - null, - Opcode.MOVE_RESULT_OBJECT // Register stores the component identifier string - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt deleted file mode 100644 index f5174c190..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt +++ /dev/null @@ -1,90 +0,0 @@ -package app.revanced.patches.youtube.misc.litho.filter.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility -import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ComponentContextParserFingerprint -import app.revanced.patches.youtube.misc.litho.filter.fingerprints.EmptyComponentBuilderFingerprint -import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ReadComponentIdentifierFingerprint -import org.jf.dexlib2.iface.instruction.Instruction -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction - -@DependsOn([IntegrationsPatch::class]) -@Description("Hooks the method which parses the bytes into a ComponentContext to filter components.") -@LithoFilterCompatibility -@Version("0.0.1") -class LithoFilterPatch : BytecodePatch( - listOf(ComponentContextParserFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - ComponentContextParserFingerprint.result?.also { - arrayOf(EmptyComponentBuilderFingerprint, ReadComponentIdentifierFingerprint).forEach { fingerprint -> - if (!fingerprint.resolve(context, it.mutableMethod, it.mutableClass)) - return fingerprint.toErrorResult() - } - }?.let { result -> - val builderMethodIndex = EmptyComponentBuilderFingerprint.patternScanEndIndex - val emptyComponentFieldIndex = builderMethodIndex + 2 - - result.mutableMethod.apply { - val insertHookIndex = result.scanResult.patternScanResult!!.endIndex - val builderMethodDescriptor = instruction(builderMethodIndex).descriptor - val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).descriptor - // Register is overwritten right after it is used in this patch, therefore free to clobber. - val clobberedRegister = instruction(insertHookIndex - 1).twoRegisterA - - @Suppress("UnnecessaryVariable") - // The register, this patch clobbers, is previously used for the StringBuilder, - // later on a new StringBuilder is instantiated on it. - val stringBuilderRegister = clobberedRegister - - val identifierRegister = instruction(ReadComponentIdentifierFingerprint.patternScanEndIndex).oneRegisterA - - addInstructions( - insertHookIndex, // right after setting the component.pathBuilder field, - """ - invoke-static {v$stringBuilderRegister, v$identifierRegister}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z - move-result v$clobberedRegister - if-eqz v$clobberedRegister, :not_an_ad - move-object/from16 v$clobberedRegister, p1 - invoke-static {v$clobberedRegister}, $builderMethodDescriptor - move-result-object v$clobberedRegister - iget-object v$clobberedRegister, v$clobberedRegister, $emptyComponentFieldDescriptor - return-object v$clobberedRegister - """, - listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex))) - ) - } - } ?: return ComponentContextParserFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - val MethodFingerprint.patternScanEndIndex - get() = result!!.scanResult.patternScanResult!!.endIndex - - val Instruction.descriptor - get() = (this as ReferenceInstruction).reference.toString() - - val Instruction.oneRegisterA - get() = (this as OneRegisterInstruction).registerA - - val Instruction.twoRegisterA - get() = (this as TwoRegisterInstruction).registerA - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt deleted file mode 100644 index b417cadc9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class MicroGPatchCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastContextFetchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastContextFetchFingerprint.kt deleted file mode 100644 index 577f1016a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastContextFetchFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CastContextFetchFingerprint : MethodFingerprint( - strings = listOf("Error fetching CastContext.") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastDynamiteModuleFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastDynamiteModuleFingerprint.kt deleted file mode 100644 index bf1f58cbe..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastDynamiteModuleFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CastDynamiteModuleFingerprint : MethodFingerprint( - strings = listOf("com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastDynamiteModuleV2Fingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastDynamiteModuleV2Fingerprint.kt deleted file mode 100644 index 8939593cd..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/CastDynamiteModuleV2Fingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CastDynamiteModuleV2Fingerprint : MethodFingerprint( - strings = listOf("Failed to load module via V2: ") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/GooglePlayUtilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/GooglePlayUtilityFingerprint.kt deleted file mode 100644 index e50f65699..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/GooglePlayUtilityFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object GooglePlayUtilityFingerprint : MethodFingerprint( - "I", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L", "L"), - strings = listOf("This should never happen.", "MetadataValueReader", "com.google.android.gms") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/PrimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/PrimeFingerprint.kt deleted file mode 100644 index 04fcf8613..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/PrimeFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PrimeFingerprint : MethodFingerprint( - strings = listOf("com.google.android.GoogleCamera", "com.android.vending") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/ServiceCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/ServiceCheckFingerprint.kt deleted file mode 100644 index 9a07e2546..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/ServiceCheckFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object ServiceCheckFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "I"), - strings = listOf("Google Play Services not available", "GooglePlayServices not available due to error ") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt deleted file mode 100644 index 9a5926896..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt +++ /dev/null @@ -1,73 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.patch.bytecode - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.fingerprints.WatchWhileActivityFingerprint -import app.revanced.patches.shared.misc.fix.spoof.patch.ClientSpoofPatch -import app.revanced.patches.youtube.layout.buttons.cast.patch.HideCastButtonPatch -import app.revanced.patches.youtube.misc.fix.playback.patch.SpoofSignatureVerificationPatch -import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility -import app.revanced.patches.youtube.misc.microg.fingerprints.* -import app.revanced.patches.youtube.misc.microg.patch.resource.MicroGResourcePatch -import app.revanced.patches.youtube.misc.microg.shared.Constants.PACKAGE_NAME -import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_PACKAGE_NAME -import app.revanced.util.microg.MicroGBytecodeHelper - -@Patch -@DependsOn( - [ - MicroGResourcePatch::class, - HideCastButtonPatch::class, - ] -) -@Name("vanced-microg-support") -@Description("Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.") -@MicroGPatchCompatibility -@Version("0.0.1") -class MicroGBytecodePatch : BytecodePatch( - listOf( - ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, - CastDynamiteModuleFingerprint, - CastDynamiteModuleV2Fingerprint, - CastContextFetchFingerprint, - PrimeFingerprint, - WatchWhileActivityFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - // apply common microG patch - MicroGBytecodeHelper.patchBytecode( - context, arrayOf( - MicroGBytecodeHelper.packageNameTransform( - PACKAGE_NAME, - REVANCED_PACKAGE_NAME - ) - ), - MicroGBytecodeHelper.PrimeMethodTransformationData( - PrimeFingerprint, - PACKAGE_NAME, - REVANCED_PACKAGE_NAME - ), - listOf( - ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, - CastDynamiteModuleFingerprint, - CastDynamiteModuleV2Fingerprint, - CastContextFetchFingerprint - ) - ) - - // inject the notice for MicroG - MicroGBytecodeHelper.injectNotice(WatchWhileActivityFingerprint) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/resource/MicroGResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/resource/MicroGResourcePatch.kt deleted file mode 100644 index 257f779e2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/resource/MicroGResourcePatch.kt +++ /dev/null @@ -1,61 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.patch.resource - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.settings.preference.impl.Preference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility -import app.revanced.patches.youtube.misc.microg.shared.Constants.PACKAGE_NAME -import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_APP_NAME -import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_PACKAGE_NAME -import app.revanced.patches.youtube.misc.microg.shared.Constants.SPOOFED_PACKAGE_NAME -import app.revanced.patches.youtube.misc.microg.shared.Constants.SPOOFED_PACKAGE_SIGNATURE -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch -import app.revanced.util.microg.Constants.MICROG_VENDOR -import app.revanced.util.microg.MicroGManifestHelper -import app.revanced.util.microg.MicroGResourceHelper - -@Name("microg-resource-patch") -@DependsOn([SettingsResourcePatch::class]) -@Description("Resource patch to allow YouTube ReVanced to run without root and under a different package name.") -@MicroGPatchCompatibility -@Version("0.0.1") -class MicroGResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - SettingsPatch.addPreference( - Preference( - StringResource("microg_settings", "MicroG Settings"), - Preference.Intent("$MICROG_VENDOR.android.gms", "", "org.microg.gms.ui.SettingsActivity"), - StringResource("microg_settings_summary", "Settings for MicroG"), - ) - ) - SettingsPatch.renameIntentsTargetPackage(REVANCED_PACKAGE_NAME) - - // update manifest - MicroGResourceHelper.patchManifest( - context, - PACKAGE_NAME, - REVANCED_PACKAGE_NAME, - REVANCED_APP_NAME - ) - - // add metadata to manifest - MicroGManifestHelper.addSpoofingMetadata( - context, - SPOOFED_PACKAGE_NAME, - SPOOFED_PACKAGE_SIGNATURE - ) - - // add strings - MicroGResourceHelper.addStrings(context) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/shared/Constants.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/shared/Constants.kt deleted file mode 100644 index 8aa66d3ce..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/shared/Constants.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.shared - -internal object Constants { - const val REVANCED_APP_NAME = "YouTube ReVanced" - const val REVANCED_PACKAGE_NAME = "app.revanced.android.youtube" - const val PACKAGE_NAME = "com.google.android.youtube" - const val SPOOFED_PACKAGE_NAME = PACKAGE_NAME - const val SPOOFED_PACKAGE_SIGNATURE = "24bb24c05e47e0aefa68a58a766179d9b613a600" -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt deleted file mode 100644 index 1750ba254..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class MinimizedPlaybackCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt deleted file mode 100644 index 9a9f629bd..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint( - returnType = "V", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("I", "L", "L"), - opcodes = listOf( - Opcode.IF_EQZ, - Opcode.SGET_OBJECT, - Opcode.IF_NE, - Opcode.CONST_4, - Opcode.IPUT_BOOLEAN, - Opcode.IF_EQZ, - Opcode.IGET, - Opcode.INVOKE_STATIC - ), - customFingerprint = { it.definingClass.endsWith("MinimizedPlaybackPolicyController;") } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt deleted file mode 100644 index 015736b73..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -object MinimizedPlaybackManagerFingerprint : MethodFingerprint( - "Z", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L"), - listOf( - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET, - Opcode.AND_INT_LIT16, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_EQZ - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt deleted file mode 100644 index af3840d08..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/fingerprints/MinimizedPlaybackSettingsFingerprint.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) -object MinimizedPlaybackSettingsFingerprint : MethodFingerprint( - "L", - AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.IF_NEZ, - Opcode.GOTO, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST - ), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt deleted file mode 100644 index ee2ad6f25..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/patch/MinimizedPlaybackPatch.kt +++ /dev/null @@ -1,94 +0,0 @@ -package app.revanced.patches.youtube.misc.minimizedplayback.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.settings.preference.impl.NonInteractivePreference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.minimizedplayback.annotations.MinimizedPlaybackCompatibility -import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint -import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint -import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint -import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.MethodReference - -@Patch -@Name("minimized-playback") -@Description("Enables minimized and background playback.") -@DependsOn([IntegrationsPatch::class, PlayerTypeHookPatch::class, SettingsPatch::class]) -@MinimizedPlaybackCompatibility -@Version("0.0.1") -class MinimizedPlaybackPatch : BytecodePatch( - listOf( - MinimizedPlaybackManagerFingerprint, - MinimizedPlaybackSettingsFingerprint, - KidsMinimizedPlaybackPolicyControllerFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - // TODO: remove this empty preference sometime after mid 2023 - SettingsPatch.PreferenceScreen.MISC.addPreferences( - NonInteractivePreference( - StringResource("revanced_minimized_playback_enabled_title", "Minimized playback"), - StringResource("revanced_minimized_playback_summary_on", "This setting can be found in Settings -> General") - ) - ) - - MinimizedPlaybackManagerFingerprint.result?.apply { - mutableMethod.addInstructions( - 0, """ - invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->isPlaybackNotShort()Z - move-result v0 - return v0 - """ - ) - } ?: return MinimizedPlaybackManagerFingerprint.toErrorResult() - - // Enable minimized playback option in YouTube settings - MinimizedPlaybackSettingsFingerprint.result?.apply { - val booleanCalls = method.implementation!!.instructions.withIndex() - .filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" } - - val settingsBooleanIndex = booleanCalls.elementAt(1).index - val settingsBooleanMethod = - context.toMethodWalker(method).nextMethod(settingsBooleanIndex, true).getMethod() as MutableMethod - - settingsBooleanMethod.addInstructions( - 0, """ - invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideMinimizedPlaybackAvailable()Z - move-result v0 - return v0 - """ - ) - } ?: return MinimizedPlaybackSettingsFingerprint.toErrorResult() - - // Force allowing background play for videos labeled for kids. - // Some regions and YouTube accounts do not require this patch. - KidsMinimizedPlaybackPolicyControllerFingerprint.result?.apply { - mutableMethod.addInstruction( - 0, - "return-void" - ) - } ?: return KidsMinimizedPlaybackPolicyControllerFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/MinimizedPlaybackPatch;" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt deleted file mode 100644 index 2914b4572..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.playercontrols.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class PlayerControlsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt deleted file mode 100644 index 50b3d5cf1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/bytecode/patch/PlayerControlsBytecodePatch.kt +++ /dev/null @@ -1,83 +0,0 @@ -package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility -import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint -import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Name("player-controls-bytecode-patch") -@DependsOn([ResourceMappingPatch::class]) -@Description("Manages the code for the player controls of the YouTube player.") -@PlayerControlsCompatibility -@Version("0.0.1") -class PlayerControlsBytecodePatch : BytecodePatch( - listOf(PlayerControlsVisibilityFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!! - - bottomUiContainerResourceId = ResourceMappingPatch - .resourceMappings - .single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id - - // TODO: another solution is required, this is hacky - listOf(BottomControlsInflateFingerprint).resolve(context, context.classes) - inflateFingerprintResult = BottomControlsInflateFingerprint.result!! - - return PatchResultSuccess() - } - - internal companion object { - var bottomUiContainerResourceId: Long = 0 - - lateinit var showPlayerControlsFingerprintResult: MethodFingerprintResult - - private var inflateFingerprintResult: MethodFingerprintResult? = null - set(fingerprint) { - field = fingerprint!!.also { - moveToRegisterInstructionIndex = it.scanResult.patternScanResult!!.endIndex - viewRegister = - (it.mutableMethod.implementation!!.instructions[moveToRegisterInstructionIndex] as OneRegisterInstruction).registerA - } - } - - private var moveToRegisterInstructionIndex: Int = 0 - private var viewRegister: Int = 0 - - /** - * Injects the code to change the visibility of controls. - * @param descriptor The descriptor of the method which should be called. - */ - fun injectVisibilityCheckCall(descriptor: String) { - showPlayerControlsFingerprintResult.mutableMethod.addInstruction( - 0, - """ - invoke-static {p1}, $descriptor - """ - ) - } - - /** - * Injects the code to initialize the controls. - * @param descriptor The descriptor of the method which should be calleed. - */ - fun initializeControl(descriptor: String) { - inflateFingerprintResult!!.mutableMethod.addInstruction( - moveToRegisterInstructionIndex + 1, - "invoke-static {v$viewRegister}, $descriptor" - ) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt deleted file mode 100644 index 9df6bcf0c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/BottomControlsInflateFingerprint.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.revanced.patches.youtube.misc.playercontrols.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object BottomControlsInflateFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT - ), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { instruction -> - instruction.opcode.ordinal == Opcode.CONST.ordinal && - (instruction as? WideLiteralInstruction)?.wideLiteral == PlayerControlsBytecodePatch.bottomUiContainerResourceId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt deleted file mode 100644 index 91e0acb01..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/fingerprints/PlayerControlsVisibilityFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.misc.playercontrols.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PlayerControlsVisibilityFingerprint : MethodFingerprint( - "V", - parameters = listOf("Z", "Z"), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("YouTubeControlsOverlay;") - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt deleted file mode 100644 index d6fb1889c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt +++ /dev/null @@ -1,82 +0,0 @@ -package app.revanced.patches.youtube.misc.playercontrols.resource.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.DomFileEditor -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility - -@Name("bottom-controls-resource-patch") -@Description("Manages the resources for the bottom controls of the YouTube player.") -@PlayerControlsCompatibility -@Version("0.0.1") -class BottomControlsResourcePatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - resourceContext = context - targetXmlEditor = context.xmlEditor[TARGET_RESOURCE] - - return PatchResultSuccess() - } - - companion object { - internal const val TARGET_RESOURCE_NAME = "youtube_controls_bottom_ui_container.xml" - private const val TARGET_RESOURCE = "res/layout/$TARGET_RESOURCE_NAME" - - private lateinit var resourceContext: ResourceContext - private lateinit var targetXmlEditor: DomFileEditor - - // The element to which to add the new elements to - private var lastLeftOf = "fullscreen_button" - - - - /** - * Add new controls to the bottom of the YouTube player. - * @param hostYouTubeControlsBottomUiResourceName The hosting resource name containing the elements. - */ - internal fun addControls(hostYouTubeControlsBottomUiResourceName: String) { - val sourceXmlEditor = - resourceContext.xmlEditor[this::class.java.classLoader.getResourceAsStream( - hostYouTubeControlsBottomUiResourceName - )!!] - - val targetElement = - "android.support.constraint.ConstraintLayout" - - val hostElements = sourceXmlEditor.file.getElementsByTagName(targetElement).item(0).childNodes - - val destinationResourceFile = this.targetXmlEditor.file - val destinationElement = - destinationResourceFile.getElementsByTagName(targetElement).item(0) - - for (index in 1 until hostElements.length) { - val element = hostElements.item(index).cloneNode(true) - - // if the element has no attributes theres no point to adding it to the destination - if (!element.hasAttributes()) continue - - // set the elements lastLeftOf attribute to the lastLeftOf value - val namespace = "@+id" - element.attributes.getNamedItem("yt:layout_constraintRight_toLeftOf").nodeValue = - "$namespace/$lastLeftOf" - - // set lastLeftOf attribute to the current element - val nameSpaceLength = 5 - lastLeftOf = element.attributes.getNamedItem("android:id").nodeValue.substring(nameSpaceLength) - - // copy the element - destinationResourceFile.adoptNode(element) - destinationElement.appendChild(element) - } - sourceXmlEditor.close() - } - } - - override fun close() { - targetXmlEditor.close() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt deleted file mode 100644 index e8fa925f9..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.playeroverlay.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class PlayerOverlaysHookCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt deleted file mode 100644 index 1defdfe65..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.playeroverlay.fingerprint - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PlayerOverlaysOnFinishInflateFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;") && methodDef.name == "onFinishInflate" - } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/patch/PlayerOverlaysHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/patch/PlayerOverlaysHookPatch.kt deleted file mode 100644 index 9b1c95bc4..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/patch/PlayerOverlaysHookPatch.kt +++ /dev/null @@ -1,35 +0,0 @@ -package app.revanced.patches.youtube.misc.playeroverlay.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.playeroverlay.annotation.PlayerOverlaysHookCompatibility -import app.revanced.patches.youtube.misc.playeroverlay.fingerprint.PlayerOverlaysOnFinishInflateFingerprint - -@Name("player-overlays-hook") -@Description("Hook for adding custom overlays to the video player.") -@PlayerOverlaysHookCompatibility -@Version("0.0.1") -@DependsOn([IntegrationsPatch::class]) -class PlayerOverlaysHookPatch : BytecodePatch( - listOf( - PlayerOverlaysOnFinishInflateFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - // hook YouTubePlayerOverlaysLayout.onFinishInflate() - val method = PlayerOverlaysOnFinishInflateFingerprint.result!!.mutableMethod - method.addInstruction( - method.implementation!!.instructions.size - 2, - "invoke-static { p0 }, Lapp/revanced/integrations/patches/PlayerOverlaysHookPatch;->YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava/lang/Object;)V" - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt deleted file mode 100644 index e88b256f6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.playertype.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class PlayerTypeHookCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/fingerprint/UpdatePlayerTypeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/fingerprint/UpdatePlayerTypeFingerprint.kt deleted file mode 100644 index 0eb8e9a11..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/fingerprint/UpdatePlayerTypeFingerprint.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.revanced.patches.youtube.misc.playertype.fingerprint - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) -object UpdatePlayerTypeFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IF_NE, - Opcode.RETURN_VOID, - Opcode.IPUT_OBJECT, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.CONST_4, - Opcode.INVOKE_STATIC, - Opcode.RETURN_VOID, - Opcode.CONST_4, - Opcode.INVOKE_STATIC, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/patch/PlayerTypeHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/patch/PlayerTypeHookPatch.kt deleted file mode 100644 index 75e722072..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/patch/PlayerTypeHookPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.youtube.misc.playertype.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.playertype.annotation.PlayerTypeHookCompatibility -import app.revanced.patches.youtube.misc.playertype.fingerprint.UpdatePlayerTypeFingerprint - -@Name("player-type-hook") -@Description("Hook to get the current player type of WatchWhileActivity") -@PlayerTypeHookCompatibility -@Version("0.0.1") -@DependsOn([IntegrationsPatch::class]) -class PlayerTypeHookPatch : BytecodePatch( - listOf( - UpdatePlayerTypeFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - // hook YouTubePlayerOverlaysLayout.updatePlayerLayout() - UpdatePlayerTypeFingerprint.result!!.mutableMethod.addInstruction( - 0, - "invoke-static { p1 }, Lapp/revanced/integrations/patches/PlayerTypeHookPatch;->YouTubePlayerOverlaysLayout_updatePlayerTypeHookEX(Ljava/lang/Object;)V" - ) - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/LicenseActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/LicenseActivityFingerprint.kt deleted file mode 100644 index 11395105f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/LicenseActivityFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object LicenseActivityFingerprint : MethodFingerprint( - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("LicenseActivity;") && methodDef.name == "onCreate" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterAppFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterAppFingerprint.kt deleted file mode 100644 index 1fceecd38..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterAppFingerprint.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object ThemeSetterAppFingerprint : MethodFingerprint( - "L", - AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("L", "L", "L", "L"), - opcodes = listOf( - Opcode.CONST, // target reference - Opcode.GOTO, - Opcode.CONST, // target reference - Opcode.INVOKE_DIRECT, - Opcode.RETURN_OBJECT, - Opcode.NEW_INSTANCE, - null, // changed from invoke interface to invoke virtual - Opcode.MOVE_RESULT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.IF_NE, - Opcode.CONST, // target reference - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterSystemFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterSystemFingerprint.kt deleted file mode 100644 index d57892735..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterSystemFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object ThemeSetterSystemFingerprint : MethodFingerprint( - "L", - opcodes = listOf(Opcode.RETURN_OBJECT), - customFingerprint = { methodDef -> - methodDef.implementation?.instructions?.any { - it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == SettingsResourcePatch.appearanceStringId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsPatch.kt deleted file mode 100644 index 331389068..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/patch/SettingsPatch.kt +++ /dev/null @@ -1,148 +0,0 @@ -package app.revanced.patches.youtube.misc.settings.bytecode.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.settings.preference.impl.Preference -import app.revanced.patches.shared.settings.util.AbstractPreferenceScreen -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.LicenseActivityFingerprint -import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterAppFingerprint -import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterSystemFingerprint -import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch -import org.jf.dexlib2.util.MethodUtil - -@DependsOn( - [ - IntegrationsPatch::class, - SettingsResourcePatch::class, - ] -) -@Name("settings") -@Description("Adds settings for ReVanced to YouTube.") -@Version("0.0.1") -class SettingsPatch : BytecodePatch( - listOf(LicenseActivityFingerprint, ThemeSetterSystemFingerprint, ThemeSetterAppFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - fun buildInvokeInstructionsString( - registers: String = "v0", - classDescriptor: String = THEME_HELPER_DESCRIPTOR, - methodName: String = SET_THEME_METHOD_NAME, - parameters: String = "Ljava/lang/Object;" - ) = "invoke-static {$registers}, $classDescriptor->$methodName($parameters)V" - - // apply the current theme of the settings page - ThemeSetterSystemFingerprint.result!!.let { result -> - val call = buildInvokeInstructionsString() - result.mutableMethod.apply { - addInstruction( - result.scanResult.patternScanResult!!.startIndex, call - ) - addInstructions( - implementation!!.instructions.size - 1, call - ) - } - } - - // set the theme based on the preference of the app - ThemeSetterAppFingerprint.result?.apply { - fun buildInstructionsString(theme: Int) = """ - const/4 v0, 0x$theme - ${buildInvokeInstructionsString(parameters = "I")} - """ - - val patternScanResult = scanResult.patternScanResult!! - - mutableMethod.apply { - addInstructions( - patternScanResult.endIndex + 1, buildInstructionsString(1) - ) - addInstructions( - patternScanResult.endIndex - 7, buildInstructionsString(0) - ) - addInstructions( - patternScanResult.endIndex - 9, buildInstructionsString(1) - ) - addInstructions( - implementation!!.instructions.size - 2, buildInstructionsString(0) - ) - } - } ?: return ThemeSetterAppFingerprint.toErrorResult() - - // set the theme based on the preference of the device - LicenseActivityFingerprint.result!!.apply licenseActivity@{ - mutableMethod.apply { - fun buildSettingsActivityInvokeString( - registers: String = "p0", - classDescriptor: String = SETTINGS_ACTIVITY_DESCRIPTOR, - methodName: String = "initializeSettings", - parameters: String = this@licenseActivity.mutableClass.type - ) = buildInvokeInstructionsString(registers, classDescriptor, methodName, parameters) - - // initialize the settings - addInstructions( - 1, """ - ${buildSettingsActivityInvokeString()} - return-void - """ - ) - - // set the current theme - addInstruction(0, buildSettingsActivityInvokeString(methodName = "setTheme")) - } - - // remove method overrides - mutableClass.apply { - methods.removeIf { it.name != "onCreate" && !MethodUtil.isConstructor(it) } - } - } - - return PatchResultSuccess() - } - - internal companion object { - private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations" - - private const val SETTINGS_ACTIVITY_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settingsmenu/ReVancedSettingActivity;" - - private const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/utils/ThemeHelper;" - private const val SET_THEME_METHOD_NAME = "setTheme" - - fun addString(identifier: String, value: String, formatted: Boolean = true) = - SettingsResourcePatch.addString(identifier, value, formatted) - - fun addPreferenceScreen(preferenceScreen: app.revanced.patches.shared.settings.preference.impl.PreferenceScreen) = - SettingsResourcePatch.addPreferenceScreen(preferenceScreen) - - fun addPreference(preference: Preference) = SettingsResourcePatch.addPreference(preference) - - fun renameIntentsTargetPackage(newPackage: String) { - SettingsResourcePatch.overrideIntentsTargetPackage = newPackage - } - } - - /** - * Preference screens patches should add their settings to. - */ - internal object PreferenceScreen : AbstractPreferenceScreen() { - val ADS = Screen("ads", "Ads", "Ad related settings") - val INTERACTIONS = Screen("interactions", "Interaction", "Settings related to interactions") - val LAYOUT = Screen("layout", "Layout", "Settings related to the layout") - val MISC = Screen("misc", "Misc", "Miscellaneous patches") - - override fun commit(screen: app.revanced.patches.shared.settings.preference.impl.PreferenceScreen) { - addPreferenceScreen(screen) - } - } - - override fun close() = PreferenceScreen.close() -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/resource/patch/SettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/resource/patch/SettingsResourcePatch.kt deleted file mode 100644 index 4248b6778..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/resource/patch/SettingsResourcePatch.kt +++ /dev/null @@ -1,170 +0,0 @@ -package app.revanced.patches.youtube.misc.settings.resource.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.DomFileEditor -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch -import app.revanced.patches.shared.settings.preference.addPreference -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.Preference -import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.resource.patch.AbstractSettingsResourcePatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.util.resources.ResourceUtils -import app.revanced.util.resources.ResourceUtils.copyResources -import app.revanced.util.resources.ResourceUtils.mergeStrings -import org.w3c.dom.Node - -@Name("settings-resource-patch") -@DependsOn([ResourceMappingPatch::class]) -@Description("Applies mandatory patches to implement ReVanced settings into the application.") -@Version("0.0.1") -class SettingsResourcePatch : AbstractSettingsResourcePatch( - "revanced_prefs", - "settings" -) { - override fun execute(context: ResourceContext): PatchResult { - super.execute(context) - - /* - * used by a fingerprint of SettingsPatch - */ - appearanceStringId = ResourceMappingPatch.resourceMappings.find { - it.type == "string" && it.name == "app_theme_appearance_dark" - }!!.id - - /* - * create missing directory for the resources - */ - context["res/drawable-ldrtl-xxxhdpi"].mkdirs() - - /* - * copy layout resources - */ - arrayOf( - ResourceUtils.ResourceGroup( - "layout", - "revanced_settings_toolbar.xml", - "revanced_settings_with_toolbar.xml", - "revanced_settings_with_toolbar_layout.xml" - ), ResourceUtils.ResourceGroup( - // required resource for back button, because when the base APK is used, this resource will not exist - "drawable-xxxhdpi", "quantum_ic_arrow_back_white_24.png" - ), ResourceUtils.ResourceGroup( - // required resource for back button, because when the base APK is used, this resource will not exist - "drawable-ldrtl-xxxhdpi", "quantum_ic_arrow_back_white_24.png" - ) - ).forEach { resourceGroup -> - context.copyResources("settings", resourceGroup) - } - - preferencesEditor = context.xmlEditor["res/xml/settings_fragment.xml"] - - // Add the ReVanced settings to the YouTube settings - val youtubePackage = "com.google.android.youtube" - SettingsPatch.addPreference( - Preference( - StringResource("revanced_settings", "ReVanced"), - Preference.Intent( - youtubePackage, "revanced_settings", "com.google.android.libraries.social.licenses.LicenseActivity" - ), - StringResource("revanced_settings_summary", "ReVanced specific settings"), - ) - ) - - context.mergeStrings("settings/host/values/strings.xml") - - return PatchResultSuccess() - } - - - internal companion object { - // Used by a fingerprint of SettingsPatch - // this field is located in the SettingsResourcePatch - // because if it were to be defined in the SettingsPatch companion object, - // the companion object could be initialized before ResourceMappingResourcePatch has executed. - internal var appearanceStringId: Long = -1 - - // if this is not null, all intents will be renamed to this - var overrideIntentsTargetPackage: String? = null - - private var preferencesNode: Node? = null - - private var preferencesEditor: DomFileEditor? = null - set(value) { - field = value - preferencesNode = value.getNode("PreferenceScreen") - } - - /* Companion delegates */ - - /** - * Add a preference fragment to the main preferences. - * - * @param preference The preference to add. - */ - fun addPreference(preference: Preference) = - preferencesNode!!.addPreference(preference) { it.include() } - - /** - * Add a new string to the resources. - * - * @param identifier The key of the string. - * @param value The value of the string. - * @throws IllegalArgumentException if the string already exists. - */ - fun addString(identifier: String, value: String, formatted: Boolean) = - AbstractSettingsResourcePatch.addString(identifier, value, formatted) - - /** - * Add an array to the resources. - * - * @param arrayResource The array resource to add. - */ - fun addArray(arrayResource: ArrayResource) = AbstractSettingsResourcePatch.addArray(arrayResource) - - /** - * Add a preference to the settings. - * - * @param preferenceScreen The name of the preference screen. - */ - fun addPreferenceScreen(preferenceScreen: PreferenceScreen) = addPreference(preferenceScreen) - } - - override fun close() { - super.close() - - // rename the intent package names if it was set - overrideIntentsTargetPackage?.let { packageName -> - val preferences = preferencesEditor!!.getNode("PreferenceScreen").childNodes - for (i in 1 until preferences.length) { - val preferenceNode = preferences.item(i) - // preferences have a child node with the intent tag, skip over every other node - if (preferenceNode.childNodes.length == 0) continue - - val intentNode = preferenceNode.firstChild - - // if the node doesn't have a target package attribute, skip it - val targetPackageAttribute = intentNode.attributes.getNamedItem("android:targetPackage") ?: continue - - // do not replace intent target package if the package name is not from YouTube - val youtubePackage = "com.google.android.youtube" - if (targetPackageAttribute.nodeValue != youtubePackage) continue - - // replace the target package name - intentNode.attributes.setNamedItem(preferenceNode.ownerDocument.createAttribute("android:targetPackage") - .also { attribute -> - attribute.value = packageName - }) - } - } - - preferencesEditor?.close() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt deleted file mode 100644 index 8981abf35..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package("com.google.android.youtube", arrayOf("18.08.37", "18.15.40"))] -) -@Target(AnnotationTarget.CLASS) -internal annotation class VideoInformationCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/CreateVideoPlayerSeekbarFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/CreateVideoPlayerSeekbarFingerprint.kt deleted file mode 100644 index 13f82a926..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/CreateVideoPlayerSeekbarFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object CreateVideoPlayerSeekbarFingerprint : MethodFingerprint( - "V", - strings = listOf("timed_markers_width") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt deleted file mode 100644 index 648f1a7e3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object OnPlaybackSpeedItemClickFingerprint : MethodFingerprint( - customFingerprint = { it.name == "onItemClick" }, - opcodes = listOf( - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/PlayerControllerSetTimeReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/PlayerControllerSetTimeReferenceFingerprint.kt deleted file mode 100644 index fe0355d68..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/PlayerControllerSetTimeReferenceFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -import org.jf.dexlib2.Opcode - -object PlayerControllerSetTimeReferenceFingerprint : MethodFingerprint( - opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE, Opcode.IGET_OBJECT), - strings = listOf("Media progress reported outside media playback: ") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/PlayerInitFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/PlayerInitFingerprint.kt deleted file mode 100644 index 7e6485525..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/PlayerInitFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object PlayerInitFingerprint : MethodFingerprint( - strings = listOf( - "playVideo called on player response with no videoStreamingData." - ), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/SeekFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/SeekFingerprint.kt deleted file mode 100644 index 8f2ba9663..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/SeekFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object SeekFingerprint : MethodFingerprint( - strings = listOf("Attempting to seek during an ad") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/VideoLengthFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/VideoLengthFingerprint.kt deleted file mode 100644 index 2d9e98682..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/VideoLengthFingerprint.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -import org.jf.dexlib2.Opcode - -object VideoLengthFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.MOVE_RESULT_WIDE, - Opcode.CMP_LONG, - Opcode.IF_LEZ, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_WIDE, - Opcode.GOTO, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_WIDE, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/VideoTimeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/VideoTimeFingerprint.kt deleted file mode 100644 index d04b75377..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/VideoTimeFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object VideoTimeFingerprint : MethodFingerprint( - strings = listOf("MedialibPlayerTimeInfo{currentPositionMillis=") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt deleted file mode 100644 index 77f44a9ed..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt +++ /dev/null @@ -1,243 +0,0 @@ -package app.revanced.patches.youtube.misc.video.information.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.data.toMethodWalker -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility -import app.revanced.patches.youtube.misc.video.information.fingerprints.* -import app.revanced.patches.youtube.misc.video.speed.remember.patch.RememberPlaybackSpeedPatch -import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.BuilderInstruction -import org.jf.dexlib2.builder.MutableMethodImplementation -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction -import org.jf.dexlib2.iface.instruction.Instruction -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.immutable.ImmutableMethod -import org.jf.dexlib2.immutable.ImmutableMethodParameter -import org.jf.dexlib2.util.MethodUtil - -@Name("video-information") -@Description("Hooks YouTube to get information about the current playing video.") -@VideoInformationCompatibility -@Version("0.0.1") -@DependsOn([IntegrationsPatch::class, VideoIdPatch::class]) -class VideoInformationPatch : BytecodePatch( - listOf( - PlayerInitFingerprint, - CreateVideoPlayerSeekbarFingerprint, - PlayerControllerSetTimeReferenceFingerprint, - VideoTimeFingerprint, - OnPlaybackSpeedItemClickFingerprint, - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - with(PlayerInitFingerprint.result!!) { - playerInitMethod = mutableClass.methods.first { MethodUtil.isConstructor(it) } - - // hook the player controller for use through integrations - onCreateHook(INTEGRATIONS_CLASS_DESCRIPTOR, "playerController_onCreateHook") - - // seek method - val seekFingerprintResultMethod = SeekFingerprint.also { it.resolve(context, classDef) }.result!!.method - - // create helper method - val seekHelperMethod = ImmutableMethod( - seekFingerprintResultMethod.definingClass, - "seekTo", - listOf(ImmutableMethodParameter("J", null, "time")), - "Z", - AccessFlags.PUBLIC or AccessFlags.FINAL, - null, null, - MutableMethodImplementation(4) - ).toMutable() - - // get enum type for the seek helper method - val seekSourceEnumType = seekFingerprintResultMethod.parameterTypes[1].toString() - - // insert helper method instructions - seekHelperMethod.addInstructions( - 0, - """ - sget-object v0, $seekSourceEnumType->a:$seekSourceEnumType - invoke-virtual {p0, p1, p2, v0}, ${seekFingerprintResultMethod.definingClass}->${seekFingerprintResultMethod.name}(J$seekSourceEnumType)Z - move-result p1 - return p1 - """ - ) - - // add the seekTo method to the class for the integrations to call - mutableClass.methods.add(seekHelperMethod) - } - - with(CreateVideoPlayerSeekbarFingerprint.result!!) { - val videoLengthMethodResult = VideoLengthFingerprint.also { it.resolve(context, classDef) }.result!! - - with(videoLengthMethodResult.mutableMethod) { - val videoLengthRegisterIndex = videoLengthMethodResult.scanResult.patternScanResult!!.endIndex - 2 - val videoLengthRegister = (instruction(videoLengthRegisterIndex) as OneRegisterInstruction).registerA - val dummyRegisterForLong = videoLengthRegister + 1 // required for long values since they are wide - - addInstruction( - videoLengthMethodResult.scanResult.patternScanResult!!.endIndex, - "invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, $INTEGRATIONS_CLASS_DESCRIPTOR->setVideoLength(J)V" - ) - } - } - - /* - * Inject call for video id - */ - val videoIdMethodDescriptor = "$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V" - VideoIdPatch.injectCall(videoIdMethodDescriptor) - VideoIdPatch.injectCallBackgroundPlay(videoIdMethodDescriptor) - - /* - * Set the video time method - */ - with(PlayerControllerSetTimeReferenceFingerprint.result!!) { - timeMethod = context.toMethodWalker(method) - .nextMethod(scanResult.patternScanResult!!.startIndex, true) - .getMethod() as MutableMethod - } - - /* - * Set the high precision video time method - */ - highPrecisionTimeMethod = - (object : MethodFingerprint("V", null, listOf("J", "J", "J", "J", "I", "L"), null) {}).also { - it.resolve(context, VideoTimeFingerprint.result!!.classDef) - }.result!!.mutableMethod - - /* - * Hook the methods which set the time - */ - highPrecisionTimeHook(INTEGRATIONS_CLASS_DESCRIPTOR, "setVideoTimeHighPrecision") - - - /* - * Hook the user playback speed selection - */ - OnPlaybackSpeedItemClickFingerprint.result?.apply { - speedSelectionInsertMethod = mutableMethod - speedSelectionInsertIndex = scanResult.patternScanResult!!.startIndex - 3 - speedSelectionValueRegister = - (mutableMethod.instruction(speedSelectionInsertIndex) as FiveRegisterInstruction).registerD - - val speedSelectionMethodInstructions = mutableMethod.implementation!!.instructions - setPlaybackSpeedContainerClassFieldReference = - getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ) - setPlaybackSpeedClassFieldReference = - getReference(speedSelectionMethodInstructions, 1, Opcode.IGET) - setPlaybackSpeedMethodReference = - getReference(speedSelectionMethodInstructions, 2, Opcode.IGET) - } ?: return OnPlaybackSpeedItemClickFingerprint.toErrorResult() - - userSelectedPlaybackSpeedHook(INTEGRATIONS_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed") - - return PatchResultSuccess() - } - - companion object { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/VideoInformation;" - - private lateinit var playerInitMethod: MutableMethod - private lateinit var timeMethod: MutableMethod - private lateinit var highPrecisionTimeMethod: MutableMethod - - private fun MutableMethod.insert(insert: InsertIndex, register: String, descriptor: String) = - addInstruction(insert.index, "invoke-static { $register }, $descriptor") - - private fun MutableMethod.insertTimeHook(insert: InsertIndex, descriptor: String) = - insert(insert, "p1, p2", descriptor) - - /** - * Hook the player controller. - * - * @param targetMethodClass The descriptor for the class to invoke when the player controller is created. - * @param targetMethodName The name of the static method to invoke when the player controller is created. - */ - internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) = - playerInitMethod.insert( - InsertIndex.CREATE, - "v0", - "$targetMethodClass->$targetMethodName(Ljava/lang/Object;)V" - ) - - /** - * Hook the video time. - * The hook is usually called once per second. - * - * @param targetMethodClass The descriptor for the static method to invoke when the player controller is created. - * @param targetMethodName The name of the static method to invoke when the player controller is created. - */ - internal fun videoTimeHook(targetMethodClass: String, targetMethodName: String) = - timeMethod.insertTimeHook( - InsertIndex.TIME, - "$targetMethodClass->$targetMethodName(J)V" - ) - - /** - * Hook the high precision video time. - * The hooks is called extremely often (10 to 15 times a seconds), so use with caution. - * Note: the hook is usually called _off_ the main thread - * - * @param targetMethodClass The descriptor for the static method to invoke when the player controller is created. - * @param targetMethodName The name of the static method to invoke when the player controller is created. - */ - internal fun highPrecisionTimeHook(targetMethodClass: String, targetMethodName: String) = - highPrecisionTimeMethod.insertTimeHook( - InsertIndex.HIGH_PRECISION_TIME, - "$targetMethodClass->$targetMethodName(J)V" - ) - - enum class InsertIndex(internal val index: Int) { - CREATE(4), - TIME(2), - HIGH_PRECISION_TIME(0), - } - - private fun getReference(instructions: List, offset: Int, opcode: Opcode) = - instructions[instructions.indexOfFirst { it.opcode == opcode } + offset].reference - - val Instruction.reference get() = (this as ReferenceInstruction).reference.toString() - - private lateinit var speedSelectionInsertMethod: MutableMethod - private var speedSelectionInsertIndex = 0 - private var speedSelectionValueRegister = 0 - - /** - * Hook the video speed selected by the user. - */ - internal fun userSelectedPlaybackSpeedHook(targetMethodClass: String, targetMethodName: String) = - speedSelectionInsertMethod.addInstruction( - speedSelectionInsertIndex++, - "invoke-static {v$speedSelectionValueRegister}, $targetMethodClass->$targetMethodName(F)V" - ) - - /** - * Used by [RememberPlaybackSpeedPatch] - */ - internal lateinit var setPlaybackSpeedContainerClassFieldReference: String - internal lateinit var setPlaybackSpeedClassFieldReference: String - internal lateinit var setPlaybackSpeedMethodReference: String - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/annotations/RememberVideoQualityCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/annotations/RememberVideoQualityCompatibility.kt deleted file mode 100644 index a7cf8ae6a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/annotations/RememberVideoQualityCompatibility.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.video.quality.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package("com.google.android.youtube", arrayOf("18.08.37", "18.15.40"))] -) -@Target(AnnotationTarget.CLASS) -internal annotation class RememberVideoQualityCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt deleted file mode 100644 index 896b5de3e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.youtube.misc.video.quality.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object SetQualityByIndexMethodClassFieldReferenceFingerprint : MethodFingerprint( - returnType = "V", - parameters = listOf("L"), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityItemOnClickParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityItemOnClickParentFingerprint.kt deleted file mode 100644 index 592c62fc0..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityItemOnClickParentFingerprint.kt +++ /dev/null @@ -1,9 +0,0 @@ - -package app.revanced.patches.youtube.misc.video.quality.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object VideoQualityItemOnClickParentFingerprint : MethodFingerprint( - "V", - strings = listOf("VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualitySetterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualitySetterFingerprint.kt deleted file mode 100644 index 9a29d162b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualitySetterFingerprint.kt +++ /dev/null @@ -1,21 +0,0 @@ - -package app.revanced.patches.youtube.misc.video.quality.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object VideoQualitySetterFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("[L", "I", "Z"), - listOf( - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IPUT_BOOLEAN, - ), - strings = listOf("menu_item_video_quality"), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt deleted file mode 100644 index d5a03e33b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt +++ /dev/null @@ -1,185 +0,0 @@ -package app.revanced.patches.youtube.misc.video.quality.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultError -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.ListPreference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.youtube.misc.video.quality.annotations.RememberVideoQualityCompatibility -import app.revanced.patches.youtube.misc.video.quality.fingerprints.SetQualityByIndexMethodClassFieldReferenceFingerprint -import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualityItemOnClickParentFingerprint -import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualitySetterFingerprint -import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.FieldReference - -@Patch -@DependsOn([IntegrationsPatch::class, VideoIdPatch::class, SettingsPatch::class]) -@Name("remember-video-quality") -@Description("Adds the ability to remember the video quality you chose in the video quality flyout.") -@RememberVideoQualityCompatibility -@Version("0.0.1") -class RememberVideoQualityPatch : BytecodePatch( - listOf( - VideoQualitySetterFingerprint, - VideoQualityItemOnClickParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - SwitchPreference( - "revanced_remember_video_quality_last_selected", - StringResource( - "revanced_remember_video_quality_last_selected_title", - "Remember video quality changes" - ), - true, - StringResource( - "revanced_remember_video_quality_last_selected_summary_on", - "Quality changes apply to all videos" - ), - StringResource( - "revanced_remember_video_quality_last_selected_summary_off", - "Quality changes only apply to the current video" - ) - ) - ) - - // This is bloated as each value has it's own String key/value - // ideally the entries would be raw values (and not a key to a String resource) - val entries = listOf( - StringResource("revanced_default_quality_entry_1", "Automatic quality"), - StringResource("revanced_default_quality_entry_2", "2160p"), - StringResource("revanced_default_quality_entry_3", "1440p"), - StringResource("revanced_default_quality_entry_4", "1080p"), - StringResource("revanced_default_quality_entry_5", "720p"), - StringResource("revanced_default_quality_entry_6", "480p"), - StringResource("revanced_default_quality_entry_7", "360p"), - StringResource("revanced_default_quality_entry_8", "280p"), - StringResource("revanced_default_quality_entry_9", "144p"), - ) - val entryValues = listOf( - StringResource("revanced_default_quality_entry_value_1", "-2"), - StringResource("revanced_default_quality_entry_value_2", "2160"), - StringResource("revanced_default_quality_entry_value_3", "1440"), - StringResource("revanced_default_quality_entry_value_4", "1080"), - StringResource("revanced_default_quality_entry_value_5", "720"), - StringResource("revanced_default_quality_entry_value_6", "480"), - StringResource("revanced_default_quality_entry_value_7", "360"), - StringResource("revanced_default_quality_entry_value_8", "280"), - StringResource("revanced_default_quality_entry_value_9", "144"), - ) - SettingsPatch.PreferenceScreen.MISC.addPreferences( - ListPreference( - "revanced_default_video_quality_wifi", - StringResource( - "revanced_default_video_quality_wifi_title", - "Default video quality on Wi-Fi network" - ), - ArrayResource("revanced_video_quality_wifi_entry", entries), - ArrayResource("revanced_video_quality_wifi_entry_values", entryValues) - // default value and summary are set by integrations after loading - ), - ListPreference( - "revanced_default_video_quality_mobile", - StringResource( - "revanced_default_video_quality_mobile_title", - "Default video quality on mobile network" - ), - ArrayResource("revanced_video_quality_mobile_entries", entries), - ArrayResource("revanced_video_quality_mobile_entry_values", entryValues) - ) - ) - - /* - * The following code works by hooking the method which is called when the user selects a video quality - * to remember the last selected video quality. - * - * It also hooks the method which is called when the video quality to set is determined. - * Conveniently, at this point the video quality is overridden to the remembered playback speed. - */ - - VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") - - // Inject a call to set the remembered quality once a video loads. - VideoQualitySetterFingerprint.result?.also { - if (!SetQualityByIndexMethodClassFieldReferenceFingerprint.resolve(context, it.classDef)) - return PatchResultError("Could not resolve fingerprint to find setQualityByIndex method") - }?.let { - // This instruction refers to the field with the type that contains the setQualityByIndex method. - val instructions = SetQualityByIndexMethodClassFieldReferenceFingerprint.result!! - .method.implementation!!.instructions - - val getOnItemClickListenerClassReference = - (instructions.elementAt(0) as ReferenceInstruction).reference - val getSetQualityByIndexMethodClassFieldReference = - (instructions.elementAt(1) as ReferenceInstruction).reference - - val setQualityByIndexMethodClassFieldReference = - getSetQualityByIndexMethodClassFieldReference as FieldReference - - val setQualityByIndexMethodClass = context.classes - .find { classDef -> classDef.type == setQualityByIndexMethodClassFieldReference.type }!! - - // Get the name of the setQualityByIndex method. - val setQualityByIndexMethod = setQualityByIndexMethodClass.methods - .find { method -> method.parameterTypes.first() == "I" } - ?: return PatchResultError("Could not find setQualityByIndex method") - - it.mutableMethod.addInstructions( - 0, - """ - # Get the object instance to invoke the setQualityByIndex method on. - iget-object v0, p0, $getOnItemClickListenerClassReference - iget-object v0, v0, $getSetQualityByIndexMethodClassFieldReference - - # Get the method name. - const-string v1, "${setQualityByIndexMethod.name}" - - # Set the quality. - # The first parameter is the array list of video qualities. - # The second parameter is the index of the selected quality. - # The register v0 stores the object instance to invoke the setQualityByIndex method on. - # The register v1 stores the name of the setQualityByIndex method. - invoke-static {p1, p2, v0, v1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I - move-result p2 - """, - ) - } ?: return VideoQualitySetterFingerprint.toErrorResult() - - // Inject a call to remember the selected quality. - VideoQualityItemOnClickParentFingerprint.result?.let { - val onItemClickMethod = it.mutableClass.methods.find { method -> method.name == "onItemClick" } - - onItemClickMethod?.apply { - val listItemIndexParameter = 3 - - addInstruction( - 0, - "invoke-static {p$listItemIndexParameter}, $INTEGRATIONS_CLASS_DESCRIPTOR->userChangedQuality(I)V" - ) - } ?: return PatchResultError("Failed to find onItemClick method") - } ?: return VideoQualityItemOnClickParentFingerprint.toErrorResult() - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch;" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/annotations/CustomPlaybackSpeedCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/annotations/CustomPlaybackSpeedCompatibility.kt deleted file mode 100644 index c03162b63..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/annotations/CustomPlaybackSpeedCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.custom.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class CustomPlaybackSpeedCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/SpeedArrayGeneratorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/SpeedArrayGeneratorFingerprint.kt deleted file mode 100644 index e4e336880..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/SpeedArrayGeneratorFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.custom.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) -object SpeedArrayGeneratorFingerprint : MethodFingerprint( - "[L", - AccessFlags.PUBLIC or AccessFlags.STATIC, - opcodes = listOf( - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.GOTO, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - ), - strings = listOf("0.0#") -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/SpeedLimiterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/SpeedLimiterFingerprint.kt deleted file mode 100644 index 4cb98cd4d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/SpeedLimiterFingerprint.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.custom.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object SpeedLimiterFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("F"), - listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.CONST_HIGH16, - Opcode.GOTO, - Opcode.CONST_HIGH16, - Opcode.CONST_HIGH16, - Opcode.INVOKE_STATIC, - ), -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/VideoSpeedPatchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/VideoSpeedPatchFingerprint.kt deleted file mode 100644 index 541601fd1..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/fingerprints/VideoSpeedPatchFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.custom.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object VideoSpeedPatchFingerprint : MethodFingerprint( - opcodes = listOf(Opcode.FILL_ARRAY_DATA), - customFingerprint = { methodDef -> - methodDef.definingClass.endsWith("CustomVideoSpeedPatch;") && methodDef.name == "" - } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/patch/CustomVideoSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/patch/CustomVideoSpeedPatch.kt deleted file mode 100644 index c038ba497..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/patch/CustomVideoSpeedPatch.kt +++ /dev/null @@ -1,195 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.custom.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.video.speed.custom.annotations.CustomPlaybackSpeedCompatibility -import app.revanced.patches.youtube.misc.video.speed.custom.fingerprints.SpeedArrayGeneratorFingerprint -import app.revanced.patches.youtube.misc.video.speed.custom.fingerprints.SpeedLimiterFingerprint -import app.revanced.patches.youtube.misc.video.speed.custom.fingerprints.VideoSpeedPatchFingerprint -import org.jf.dexlib2.builder.instruction.BuilderArrayPayload -import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.reference.FieldReference -import org.jf.dexlib2.iface.reference.MethodReference -import java.util.stream.DoubleStream -import kotlin.math.roundToInt - -@Patch -@Name("custom-video-speed") -@Description("Adds more video speed options.") -@DependsOn([IntegrationsPatch::class]) -@CustomPlaybackSpeedCompatibility -@Version("0.0.1") -class CustomVideoSpeedPatch : BytecodePatch( - listOf( - SpeedArrayGeneratorFingerprint, SpeedLimiterFingerprint, VideoSpeedPatchFingerprint - ) -) { - - override fun execute(context: BytecodeContext): PatchResult { - val speedLimitMin = minVideoSpeed!!.toFloat() - val speedLimitMax = maxVideoSpeed!!.toFloat().coerceAtLeast(speedLimitMin) - val speedsGranularity = videoSpeedsGranularity!!.toFloat() - - val arrayGenMethod = SpeedArrayGeneratorFingerprint.result?.mutableMethod!! - val arrayGenMethodImpl = arrayGenMethod.implementation!! - - val sizeCallIndex = arrayGenMethodImpl.instructions - .indexOfFirst { ((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "size" } - - if (sizeCallIndex == -1) return PatchResultError("Couldn't find call to size()") - - val sizeCallResultRegister = - (arrayGenMethodImpl.instructions.elementAt(sizeCallIndex + 1) as OneRegisterInstruction).registerA - - arrayGenMethod.replaceInstruction( - sizeCallIndex + 1, - "const/4 v$sizeCallResultRegister, 0x0" - ) - - val (arrayLengthConstIndex, arrayLengthConst) = arrayGenMethodImpl.instructions.withIndex() - .first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 7 } - - val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA - - val videoSpeedsArrayType = "Lapp/revanced/integrations/patches/playback/speed/CustomVideoSpeedPatch;->videoSpeeds:[F" - - arrayGenMethod.addInstructions( - arrayLengthConstIndex + 1, - """ - sget-object v$arrayLengthConstDestination, $videoSpeedsArrayType - array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination - """ - ) - - val (originalArrayFetchIndex, originalArrayFetch) = arrayGenMethodImpl.instructions.withIndex() - .first { - val reference = ((it.value as? ReferenceInstruction)?.reference as? FieldReference) - reference?.definingClass?.contains("PlayerConfigModel") ?: false && - reference?.type == "[F" - } - - val originalArrayFetchDestination = (originalArrayFetch as OneRegisterInstruction).registerA - - arrayGenMethod.replaceInstruction( - originalArrayFetchIndex, - "sget-object v$originalArrayFetchDestination, $videoSpeedsArrayType" - ) - - val limiterMethod = SpeedLimiterFingerprint.result?.mutableMethod!! - val limiterMethodImpl = limiterMethod.implementation!! - - val (limiterMinConstIndex, limiterMinConst) = limiterMethodImpl.instructions.withIndex() - .first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() } - val (limiterMaxConstIndex, limiterMaxConst) = limiterMethodImpl.instructions.withIndex() - .first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() } - - val limiterMinConstDestination = (limiterMinConst as OneRegisterInstruction).registerA - val limiterMaxConstDestination = (limiterMaxConst as OneRegisterInstruction).registerA - - fun hexFloat(float: Float): String = "0x%08x".format(float.toRawBits()) - - limiterMethod.replaceInstruction( - limiterMinConstIndex, - "const/high16 v$limiterMinConstDestination, ${hexFloat(speedLimitMin)}" - ) - limiterMethod.replaceInstruction( - limiterMaxConstIndex, - "const/high16 v$limiterMaxConstDestination, ${hexFloat(speedLimitMax)}" - ) - - val constructorResult = VideoSpeedPatchFingerprint.result!! - val constructor = constructorResult.mutableMethod - val implementation = constructor.implementation!! - - val stepsGranularity = 8F - val step = speedLimitMax - .minus(speedLimitMin) // calculate the range of the speeds - .div(speedsGranularity) - .times(stepsGranularity) - .roundToInt() - .div(stepsGranularity)// round to nearest multiple of stepsGranularity - .coerceAtLeast(1 / stepsGranularity) // ensure steps are at least 1/8th of the step granularity - - val videoSpeedsArray = buildList { - DoubleStream - .iterate(speedLimitMin.toDouble()) { it + step } // create a stream of speeds - .let { speedStream -> - for (speed in speedStream) { - if (speed > speedLimitMax) break - add(speed.toFloat().toRawBits()) - } - } - } - - // adjust the new array of speeds size - constructor.replaceInstruction( - 0, - "const/16 v0, ${videoSpeedsArray.size}" - ) - - // create the payload with the new speeds - val arrayPayloadIndex = implementation.instructions.size - 1 - implementation.replaceInstruction( - arrayPayloadIndex, - BuilderArrayPayload( - 4, - videoSpeedsArray - ) - ) - - return PatchResultSuccess() - } - - companion object : OptionsContainer() { - private fun String?.validate(max: Int? = null) = this?.toFloatOrNull() != null && - toFloat().let { float -> - float > 0 && max?.let { max -> float <= max } ?: true - } - - val videoSpeedsGranularity by option( - PatchOption.StringOption( - "granularity", - "16", - "Video speed granularity", - "The granularity of the video speeds. The higher the value, the more speeds will be available.", - true - ) { - it.validate() - } - ) - - val minVideoSpeed by option( - PatchOption.StringOption( - "min", - "0.25", - "Minimum video speed", - "The minimum video speed.", - true - ) { - it.validate() - } - ) - - val maxVideoSpeed by option( - PatchOption.StringOption( - "max", - "5.0", - "Maximum video speed", - "The maximum video speed. Must be greater than the minimum video speed and smaller than 5.", - true - ) { - it.validate(5) - } - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/annotation/RememberPlaybackSpeedCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/annotation/RememberPlaybackSpeedCompatibility.kt deleted file mode 100644 index 11e62479c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/annotation/RememberPlaybackSpeedCompatibility.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.remember.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package("com.google.android.youtube", arrayOf("18.08.37", "18.15.40"))] -) -@Target(AnnotationTarget.CLASS) -internal annotation class RememberPlaybackSpeedCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt deleted file mode 100644 index e244a298e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.remember.fingerprint - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object InitializePlaybackSpeedValuesFingerprint : MethodFingerprint( - parameters = listOf("[L", "I"), - strings = listOf("menu_item_playback_speed") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt deleted file mode 100644 index 4895e665a..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt +++ /dev/null @@ -1,125 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.remember.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.* -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.shared.settings.preference.impl.ArrayResource -import app.revanced.patches.shared.settings.preference.impl.ListPreference -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch -import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch.Companion.reference -import app.revanced.patches.youtube.misc.video.speed.remember.annotation.RememberPlaybackSpeedCompatibility -import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint -import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch - -@Patch -@Name("remember-playback-speed") -@Description("Adds the ability to remember the playback speed you chose in the video playback speed flyout.") -@DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoIdPatch::class, VideoInformationPatch::class]) -@RememberPlaybackSpeedCompatibility -@Version("0.0.1") -class RememberPlaybackSpeedPatch : BytecodePatch( - listOf( - InitializePlaybackSpeedValuesFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - SwitchPreference( - "revanced_remember_playback_speed_last_selected", - StringResource( - "revanced_remember_playback_speed_last_selected_title", - "Remember playback speed changes" - ), - true, - StringResource( - "revanced_remember_playback_speed_last_selected_summary_on", - "Playback speed changes apply to all videos" - ), - StringResource( - "revanced_remember_playback_speed_last_selected_summary_off", - "Playback speed changes only apply to the current video" - ) - ) - ) - - SettingsPatch.PreferenceScreen.MISC.addPreferences( - ListPreference( - "revanced_default_playback_speed", - StringResource( - "revanced_default_playback_speed_title", - "Default playback speed" - ), - // Dummy data: - // Entries and values are set by Integrations code based on the actual speeds available, - // and the values set here are ignored and do nothing. - ArrayResource( - "revanced_default_playback_speed_entries", - listOf(StringResource("revanced_default_playback_speed_entry", "1.0x")) - ), - ArrayResource( - "revanced_default_playback_speed_entry_values", - listOf(StringResource("revanced_default_playback_speed_entry_value", "1.0")) - ) - ) - ) - - VideoIdPatch.injectCall("${INTEGRATIONS_CLASS_DESCRIPTOR}->newVideoLoaded(Ljava/lang/String;)V") - - VideoInformationPatch.userSelectedPlaybackSpeedHook( - INTEGRATIONS_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed") - - /* - * Hook the code that is called when the playback speeds are initialized, and sets the playback speed - */ - InitializePlaybackSpeedValuesFingerprint.result?.apply { - // Infer everything necessary for calling the method setPlaybackSpeed(). - val onItemClickListenerClassFieldReference = mutableMethod.instruction(0).reference - - // Registers are not used at index 0, so they can be freely used. - mutableMethod.addInstructions( - 0, - """ - invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->getPlaybackSpeedOverride()F - move-result v0 - - # Check if the playback speed is not 1.0x. - const/high16 v1, 0x3f800000 # 1.0f - cmpg-float v1, v0, v1 - if-eqz v1, :do_not_override - - # Get the instance of the class which has the container class field below. - iget-object v1, p0, $onItemClickListenerClassFieldReference - - # Get the container class field. - iget-object v1, v1, ${VideoInformationPatch.setPlaybackSpeedContainerClassFieldReference} - - # Get the field from its class. - iget-object v2, v1, ${VideoInformationPatch.setPlaybackSpeedClassFieldReference} - - # Invoke setPlaybackSpeed on that class. - invoke-virtual {v2, v0}, ${VideoInformationPatch.setPlaybackSpeedMethodReference} - """.trimIndent(), - listOf(ExternalLabel("do_not_override", mutableMethod.instruction(0))) - ) - } ?: return InitializePlaybackSpeedValuesFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch;" - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/annotation/VideoIdCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/annotation/VideoIdCompatibility.kt deleted file mode 100644 index 89e6ab114..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/annotation/VideoIdCompatibility.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.youtube.misc.video.videoid.annotation - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class VideoIdCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/fingerprint/VideoIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/fingerprint/VideoIdFingerprint.kt deleted file mode 100644 index bed9e90d3..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/fingerprint/VideoIdFingerprint.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.youtube.misc.video.videoid.fingerprint - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) -object VideoIdFingerprint : MethodFingerprint( - returnType = "V", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("L"), - opcodes = listOf( - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT - ), - null, - { it.definingClass.endsWith("SubtitlesOverlayPresenter;") } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/fingerprint/VideoIdFingerprintBackgroundPlay.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/fingerprint/VideoIdFingerprintBackgroundPlay.kt deleted file mode 100644 index 44c14a2c2..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/fingerprint/VideoIdFingerprintBackgroundPlay.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.youtube.misc.video.videoid.fingerprint - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object VideoIdFingerprintBackgroundPlay : MethodFingerprint( - returnType = "V", - access = AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC, - parameters = listOf("L"), - opcodes = listOf(Opcode.INVOKE_INTERFACE), - customFingerprint = { - it.definingClass.endsWith("PlaybackLifecycleMonitor;") - } -) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/patch/VideoIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/patch/VideoIdPatch.kt deleted file mode 100644 index bf961de7b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/patch/VideoIdPatch.kt +++ /dev/null @@ -1,102 +0,0 @@ -package app.revanced.patches.youtube.misc.video.videoid.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.video.videoid.annotation.VideoIdCompatibility -import app.revanced.patches.youtube.misc.video.videoid.fingerprint.VideoIdFingerprint -import app.revanced.patches.youtube.misc.video.videoid.fingerprint.VideoIdFingerprintBackgroundPlay -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Name("video-id-hook") -@Description("Hooks to detect when the video id changes") -@VideoIdCompatibility -@Version("0.0.1") -@DependsOn([IntegrationsPatch::class]) -class VideoIdPatch : BytecodePatch( - listOf(VideoIdFingerprint, VideoIdFingerprintBackgroundPlay) -) { - override fun execute(context: BytecodeContext): PatchResult { - VideoIdFingerprint.result?.let { result -> - val videoIdRegisterInstructionIndex = result.scanResult.patternScanResult!!.endIndex - - result.mutableMethod.also { - insertMethod = it - }.apply { - videoIdRegister = (instruction(videoIdRegisterInstructionIndex) as OneRegisterInstruction).registerA - insertIndex = videoIdRegisterInstructionIndex + 1 - } - } ?: return VideoIdFingerprint.toErrorResult() - - VideoIdFingerprintBackgroundPlay.result?.let { result -> - val endIndex = result.scanResult.patternScanResult!!.endIndex - - result.mutableMethod.also { - backgroundPlaybackMethod = it - }.apply { - backgroundPlaybackVideoIdRegister = (instruction(endIndex + 1) as OneRegisterInstruction).registerA - backgroundPlaybackInsertIndex = endIndex + 2 - } - } ?: return VideoIdFingerprintBackgroundPlay.toErrorResult() - - return PatchResultSuccess() - } - - companion object { - private var videoIdRegister = 0 - private var insertIndex = 0 - private lateinit var insertMethod: MutableMethod - - private var backgroundPlaybackVideoIdRegister = 0 - private var backgroundPlaybackInsertIndex = 0 - private lateinit var backgroundPlaybackMethod: MutableMethod - - /** - * Adds an invoke-static instruction, called with the new id when the video changes. - * - * Supports all videos (regular videos, Shorts and Stories). - * - * _Does not function if playing in the background with no video visible_. - * - * Be aware, this can be called multiple times for the same video id. - * - * @param methodDescriptor which method to call. Params have to be `Ljava/lang/String;` - */ - fun injectCall( - methodDescriptor: String - ) = insertMethod.addInstructions( - // Keep injection calls in the order they're added: - // Increment index. So if additional injection calls are added, those calls run after this injection call. - insertIndex++, - "invoke-static {v$videoIdRegister}, $methodDescriptor" - ) - - /** - * Alternate hook that supports only regular videos, but hook supports changing to new video - * during background play when no video is visible. - * - * _Does not support Shorts or Stories_. - * - * Be aware, the hook can be called multiple times for the same video id. - * - * @param methodDescriptor which method to call. Params have to be `Ljava/lang/String;` - */ - fun injectCallBackgroundPlay( - methodDescriptor: String - ) = backgroundPlaybackMethod.addInstructions( - backgroundPlaybackInsertIndex++, // move-result-object offset - "invoke-static {v$backgroundPlaybackVideoIdRegister}, $methodDescriptor" - ) - } -} - diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt deleted file mode 100644 index aac6db67f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.youtube.misc.videobuffer.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -// TODO: delete this -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37", - "18.15.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class CustomVideoBufferCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/patch/CustomVideoBufferPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/patch/CustomVideoBufferPatch.kt deleted file mode 100644 index b8b7a4da7..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/patch/CustomVideoBufferPatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.youtube.misc.videobuffer.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.settings.preference.impl.* -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.youtube.misc.videobuffer.annotations.CustomVideoBufferCompatibility - -// TODO: delete this patch -@Patch(include = false) -@Name("custom-video-buffer") -@Description("Lets you change the buffers of videos.") -@DependsOn([SettingsPatch::class]) -@CustomVideoBufferCompatibility -@Version("0.0.1") -class CustomVideoBufferPatch : BytecodePatch() { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - NonInteractivePreference( - StringResource("revanced_custom_video_buffer_disclaimer_title", "Custom video buffer"), - StringResource("revanced_custom_video_buffer_disclaimer_title_summary", - "These settings have been removed, because they were not functional for the duration of their existence"), - ) - ) - - return PatchResultSuccess() - } -} - diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/annotations/ZoomHapticsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/annotations/ZoomHapticsCompatibility.kt deleted file mode 100644 index 9b6a02306..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/annotations/ZoomHapticsCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.zoomhaptics.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.google.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class ZoomHapticsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/fingerprints/ZoomHapticsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/fingerprints/ZoomHapticsFingerprint.kt deleted file mode 100644 index 493db9c4e..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/fingerprints/ZoomHapticsFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.zoomhaptics.fingerprints -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object ZoomHapticsFingerprint : MethodFingerprint( - strings = listOf( - "Failed to haptics vibrate for video zoom" - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/patch/ZoomHapticsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/patch/ZoomHapticsPatch.kt deleted file mode 100644 index 89cccda3c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/zoomhaptics/patch/ZoomHapticsPatch.kt +++ /dev/null @@ -1,54 +0,0 @@ -package app.revanced.patches.youtube.misc.zoomhaptics.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.misc.zoomhaptics.annotations.ZoomHapticsCompatibility -import app.revanced.patches.youtube.misc.zoomhaptics.fingerprints.ZoomHapticsFingerprint - -@Patch -@Name("disable-zoom-haptics") -@Description("Disables haptics when zooming.") -@DependsOn([SettingsPatch::class]) -@ZoomHapticsCompatibility -@Version("0.0.1") -class ZoomHapticsPatch : BytecodePatch( - listOf(ZoomHapticsFingerprint) -) { - override fun execute(context: BytecodeContext): PatchResult { - SettingsPatch.PreferenceScreen.MISC.addPreferences( - SwitchPreference( - "revanced_disable_zoom_haptics", - StringResource("revanced_disable_zoom_haptics_title", "Disable zoom haptics"), - true, - StringResource("revanced_disable_zoom_haptics_summary_on", "Haptics are disabled"), - StringResource("revanced_disable_zoom_haptics_summary_off", "Haptics are enabled") - ) - ) - - val zoomHapticsFingerprintMethod = ZoomHapticsFingerprint.result!!.mutableMethod - - zoomHapticsFingerprintMethod.addInstructions( - 0, """ - invoke-static { }, Lapp/revanced/integrations/patches/ZoomHapticsPatch;->shouldVibrate()Z - move-result v0 - if-nez v0, :vibrate - return-void - """, listOf(ExternalLabel("vibrate", zoomHapticsFingerprintMethod.instruction(0))) - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/annotations/HideAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/annotations/HideAdsCompatibility.kt deleted file mode 100644 index e7c85c582..000000000 --- a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/annotations/HideAdsCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtubevanced.ad.general.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("com.vanced.android.youtube")]) -@Target(AnnotationTarget.CLASS) -internal annotation class HideAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/fingerprints/ContainsAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/fingerprints/ContainsAdFingerprint.kt deleted file mode 100644 index ed26fa039..000000000 --- a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/fingerprints/ContainsAdFingerprint.kt +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.patches.youtubevanced.ad.general.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object ContainsAdFingerprint:MethodFingerprint( - returnType = "Z", - parameters = listOf("L", "L"), - access = AccessFlags.STATIC or AccessFlags.PUBLIC, - opcodes = listOf( - Opcode.CONST_STRING, - Opcode.INVOKE_INTERFACE, - Opcode.CONST_STRING, - Opcode.INVOKE_INTERFACE, - Opcode.CONST_STRING, - Opcode.INVOKE_INTERFACE - ), - strings = listOf("ads_video_with_context"), - customFingerprint = { methodDef -> - methodDef.name == "containsAd" && methodDef.definingClass.endsWith("LithoAdRemoval;") - } -) { -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt deleted file mode 100644 index 09fd98117..000000000 --- a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt +++ /dev/null @@ -1,64 +0,0 @@ -package app.revanced.patches.youtubevanced.ad.general.patch - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.shared.misc.fix.verticalscroll.patch.VerticalScrollPatch -import app.revanced.patches.youtubevanced.ad.general.annotations.HideAdsCompatibility -import app.revanced.patches.youtubevanced.ad.general.fingerprints.ContainsAdFingerprint -import org.jf.dexlib2.iface.instruction.formats.Instruction21c - -@Patch -@Name("hide-ads") -@Description("Removes general ads.") -@DependsOn([VerticalScrollPatch::class]) -@HideAdsCompatibility -@Version("0.0.1") -class HideAdsPatch : BytecodePatch( - listOf( - ContainsAdFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - ContainsAdFingerprint.result?.let { result -> - result.mutableMethod.apply { - val insertIndex = result.scanResult.patternScanResult!!.endIndex + 1 - val adsListRegister = (instruction(insertIndex - 2) as Instruction21c).registerA - - listOf( - "_buttoned_layout", - "full_width_square_image_layout", - "_ad_with", - "landscape_image_wide_button_layout", - "banner_text_icon", - "cell_divider", - "square_image_layout", - "watch_metadata_app_promo", - "video_display_full_layout", - "hero_promo_image", - "statement_banner", - "primetime_promo", - "carousel_footered_layout" - ).forEach { component -> - addInstructions( - insertIndex, """ - const-string v$adsListRegister, "$component" - invoke-interface {v0, v$adsListRegister}, Ljava/util/List;->add(Ljava/lang/Object;)Z - """ - ) - } - } - } ?: return ContainsAdFingerprint.toErrorResult() - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/annotations/UnlockPremiumCompatibility.kt b/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/annotations/UnlockPremiumCompatibility.kt deleted file mode 100644 index caa0db41f..000000000 --- a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/annotations/UnlockPremiumCompatibility.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.yuka.misc.unlockpremium.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility([Package("io.yuka.android")]) -@Target(AnnotationTarget.CLASS) -internal annotation class UnlockPremiumCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/fingerprints/IsPremiumFingerprint.kt b/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/fingerprints/IsPremiumFingerprint.kt deleted file mode 100644 index 0a7f01a25..000000000 --- a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/fingerprints/IsPremiumFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.yuka.misc.unlockpremium.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object IsPremiumFingerprint : MethodFingerprint( - returnType = "Z", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.IGET_BOOLEAN, - Opcode.RETURN, - ) -) diff --git a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/fingerprints/YukaUserConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/fingerprints/YukaUserConstructorFingerprint.kt deleted file mode 100644 index 85351e471..000000000 --- a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/fingerprints/YukaUserConstructorFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.yuka.misc.unlockpremium.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object YukaUserConstructorFingerprint : MethodFingerprint( - returnType = "V", - access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - strings = listOf( - "premiumProvider" - ) -) diff --git a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/patch/UnlockPremiunPatch.kt b/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/patch/UnlockPremiunPatch.kt deleted file mode 100644 index afdcdd2f7..000000000 --- a/src/main/kotlin/app/revanced/patches/yuka/misc/unlockpremium/patch/UnlockPremiunPatch.kt +++ /dev/null @@ -1,41 +0,0 @@ -package app.revanced.patches.yuka.misc.unlockpremium.patch - -import app.revanced.patcher.annotation.Description -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.yuka.misc.unlockpremium.annotations.UnlockPremiumCompatibility -import app.revanced.patches.yuka.misc.unlockpremium.fingerprints.IsPremiumFingerprint -import app.revanced.patches.yuka.misc.unlockpremium.fingerprints.YukaUserConstructorFingerprint - -@Patch -@Name("unlock-premium") -@Description("Unlocks premium features.") -@UnlockPremiumCompatibility -@Version("0.0.1") -class UnlockPremiunPatch : BytecodePatch( - listOf( - YukaUserConstructorFingerprint - ) -) { - - override fun execute(context: BytecodeContext): PatchResult { - IsPremiumFingerprint.resolve(context,YukaUserConstructorFingerprint.result!!.classDef) - val method = IsPremiumFingerprint.result!!.mutableMethod - method.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """ - ) - return PatchResultSuccess() - } - -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt new file mode 100644 index 000000000..6b00c9043 --- /dev/null +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -0,0 +1,235 @@ +package app.revanced.util + +import app.revanced.patcher.BytecodeContext +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.builder.BuilderInstruction +import org.jf.dexlib2.builder.MutableMethodImplementation +import org.jf.dexlib2.builder.instruction.BuilderInstruction21c +import org.jf.dexlib2.iface.Method +import org.jf.dexlib2.iface.instruction.Instruction +import org.jf.dexlib2.iface.instruction.ReferenceInstruction +import org.jf.dexlib2.iface.instruction.WideLiteralInstruction +import org.jf.dexlib2.iface.reference.FieldReference +import org.jf.dexlib2.iface.reference.MethodReference +import org.jf.dexlib2.iface.reference.Reference + +fun MethodFingerprint.resultOrThrow() = result ?: throw exception + +/** + * The [PatchException] of failing to resolve a [MethodFingerprint]. + * + * @return The [PatchException]. + */ +val MethodFingerprint.exception + get() = PatchException("Failed to resolve ${this.javaClass.simpleName}") + +fun MutableMethodImplementation.getInstruction(index: Int): BuilderInstruction = + instructions[index] + +@Suppress("UNCHECKED_CAST") +fun MutableMethodImplementation.getInstruction(index: Int): T = + getInstruction(index) as T + +fun MutableMethod.getInstruction(index: Int): BuilderInstruction = + implementation!!.getInstruction(index) + +fun MutableMethod.getInstruction(index: Int): T = + implementation!!.getInstruction(index) + +/** + * Find the index of the first wide literal instruction with the given value. + * + * @return the first literal instruction with the value, or -1 if not found. + */ +fun Method.getWideLiteralInstructionIndex(literal: Long) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + (instruction as? WideLiteralInstruction)?.wideLiteral == literal + } +} ?: -1 + +fun MutableMethod.getStringInstructionIndex(value: String) = indexOfFirstInstruction { + opcode == Opcode.CONST_STRING + && (this as? BuilderInstruction21c)?.reference.toString() == value +} + +/** + * Check if the method contains a literal with the given value. + * + * @return if the method contains a literal with the given value. + */ +fun Method.containsWideLiteralInstructionIndex(literal: Long) = + getWideLiteralInstructionIndex(literal) >= 0 + +fun Method.containsMethodReferenceNameInstructionIndex(methodName: String) = + getTargetIndexWithMethodReferenceName(methodName) >= 0 + +fun Method.containsReferenceInstructionIndex(reference: String) = + getTargetIndexWithReference(reference) >= 0 + + +/** + * Get the [Reference] of an [Instruction] as [T]. + * + * @param T The type of [Reference] to cast to. + * @return The [Reference] as [T] or null + * if the [Instruction] is not a [ReferenceInstruction] or the [Reference] is not of type [T]. + * @see ReferenceInstruction + */ +inline fun Instruction.getReference() = + (this as? ReferenceInstruction)?.reference as? T + +/** + * Get the index of the first [Instruction] that matches the predicate. + * + * @param predicate The predicate to match. + * @return The index of the first [Instruction] that matches the predicate. + */ +fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = + this.implementation!!.instructions.indexOfFirst(predicate) + +fun MutableMethod.getTargetIndex(opcode: Opcode) = getTargetIndex(0, opcode) + +fun MutableMethod.getTargetIndexReversed(opcode: Opcode) = + getTargetIndexReversed(implementation!!.instructions.size - 1, opcode) + +fun MutableMethod.getTargetIndex(startIndex: Int, opcode: Opcode) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + instruction.opcode == opcode + } + } + +fun MutableMethod.getTargetIndexReversed(startIndex: Int, opcode: Opcode): Int { + for (index in startIndex downTo 0) { + if (getInstruction(index).opcode != opcode) + continue + + return index + } + return -1 +} + +fun Method.getTargetIndexWithFieldReferenceName(filedName: String) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + instruction.getReference()?.name == filedName + } +} ?: -1 + +fun MutableMethod.getTargetIndexWithFieldReferenceNameReversed(returnType: String) + = getTargetIndexWithFieldReferenceTypeReversed(implementation!!.instructions.size - 1, returnType) + +fun MutableMethod.getTargetIndexWithFieldReferenceName(startIndex: Int, filedName: String) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + instruction.getReference()?.name == filedName + } + } + +fun MutableMethod.getTargetIndexWithFieldReferenceNameReversed(startIndex: Int, filedName: String): Int { + for (index in startIndex downTo 0) { + val instruction = getInstruction(index) + if (instruction.getReference()?.name != filedName) + continue + + return index + } + return -1 +} + +fun Method.getTargetIndexWithFieldReferenceType(returnType: String) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + instruction.getReference()?.type == returnType + } +} ?: -1 + +fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(returnType: String) += getTargetIndexWithFieldReferenceTypeReversed(implementation!!.instructions.size - 1, returnType) + +fun MutableMethod.getTargetIndexWithFieldReferenceType(startIndex: Int, returnType: String) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + instruction.getReference()?.type == returnType + } + } + +fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(startIndex: Int, returnType: String): Int { + for (index in startIndex downTo 0) { + val instruction = getInstruction(index) + if (instruction.getReference()?.type != returnType) + continue + + return index + } + return -1 +} + +fun Method.getTargetIndexWithMethodReferenceName(methodName: String) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + instruction.getReference()?.name == methodName + } +} ?: -1 + +fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(methodName: String) += getTargetIndexWithMethodReferenceNameReversed(implementation!!.instructions.size - 1, methodName) + + +fun MutableMethod.getTargetIndexWithMethodReferenceName(startIndex: Int, methodName: String) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + instruction.getReference()?.name == methodName + } + } + +fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(startIndex: Int, methodName: String): Int { + for (index in startIndex downTo 0) { + val instruction = getInstruction(index) + if (instruction.getReference()?.name != methodName) + continue + + return index + } + return -1 +} + +fun Method.getTargetIndexWithReference(reference: String) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + (instruction as? ReferenceInstruction)?.reference.toString().contains(reference) + } +} ?: -1 + +fun MutableMethod.getTargetIndexWithReference(reference: String) = + getTargetIndexWithReference(0, reference) + +fun MutableMethod.getTargetIndexWithReferenceReversed(reference: String) = + getTargetIndexWithReferenceReversed(implementation!!.instructions.size - 1, reference) + +fun MutableMethod.getTargetIndexWithReference(startIndex: Int, reference: String) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + (instruction as? ReferenceInstruction)?.reference.toString().contains(reference) + } + } + +fun MutableMethod.getTargetIndexWithReferenceReversed(startIndex: Int, reference: String): Int { + for (index in startIndex downTo 0) { + val instruction = getInstruction(index) + if (!(instruction as? ReferenceInstruction)?.reference.toString().contains(reference)) + continue + + return index + } + return -1 +} + +fun MethodFingerprintResult.getWalkerMethod(context: BytecodeContext, index: Int) = + mutableMethod.getWalkerMethod(context, index) + +fun MutableMethod.getWalkerMethod(context: BytecodeContext, index: Int) = + context + .traceMethodCalls(this) + .nextMethod(index, true) + .getMethod() as MutableMethod diff --git a/src/main/kotlin/app/revanced/util/ResourceUtils.kt b/src/main/kotlin/app/revanced/util/ResourceUtils.kt new file mode 100644 index 000000000..bfc028298 --- /dev/null +++ b/src/main/kotlin/app/revanced/util/ResourceUtils.kt @@ -0,0 +1,128 @@ +package app.revanced.util + +import app.revanced.patcher.DomFileEditor +import app.revanced.patcher.ResourceContext +import app.revanced.patcher.apk.Apk +import app.revanced.patcher.apk.ResourceFile +import app.revanced.patcher.resource.Resource +import app.revanced.patcher.resource.StringResource +import app.revanced.patcher.resource.color +import app.revanced.patcher.resource.reference +import java.io.File +import java.nio.file.Paths + +internal object ResourceUtils { + internal fun ResourceContext.mergeStrings(resources: Map) = + base.setGroup("string", resources.mapValues { + StringResource( + it.value + ) + }) + + internal fun ResourceFile.editText(block: (String) -> String) = use { + it.contents = block(String(it.contents)).toByteArray() + } + + internal fun String.toColorResource(resources: Apk.ResourceContainer) = + if (startsWith('@')) reference(resources, this) else color(this) + + internal fun Apk.ResourceContainer.setMultiple( + type: String, + names: List, + value: Resource, + configuration: String? = null + ) = setGroup( + type, + names.associateWith { value }, configuration + ) + + internal fun Apk.ResourceContainer.setString(name: String, value: String) = set("string", name, StringResource(value)) + + internal fun Apk.ResourceContainer.setStrings(resources: Map) = setGroup("string", resources.mapValues { + StringResource( + it.value + ) + }) + + /** + * Copy resources from the current class loader to the resource directory. + * @param sourceResourceDirectory The source resource directory name. + * @param resources The resources to copy. + */ + internal fun ResourceContext.copyResources(sourceResourceDirectory: String, vararg resources: ResourceGroup) { + val classLoader = ResourceUtils.javaClass.classLoader + + for (resourceGroup in resources) { + resourceGroup.resources.forEach { resource -> + val resourceFile = "${resourceGroup.resourceDirectoryName}/$resource" + base.openFile("res/$resourceFile").use { file -> + file.outputStream().use { + classLoader.getResourceAsStream("$sourceResourceDirectory/$resourceFile")!!.copyTo(it) + } + } + } + } + } + + internal fun ResourceFile.takeIfExists() = if (!exists) { + close() + null + } else this + + internal fun ResourceContext.resourceIdOf(type: String, name: String) = + apkBundle.resources.resolve(type, name).toLong() + + internal val ResourceContext.base get() = apkBundle.base.resources + + internal fun ResourceContext.manifestEditor() = base.openXmlFile(Apk.manifest) + + internal fun getResourcePath() = File(Paths.get("").toAbsolutePath().toString()).resolve("revanced-cache").resolve("res") + + /** + * Resource names mapped to their corresponding resource data. + * @param resourceDirectoryName The name of the directory of the resource. + * @param resources A list of resource names. + */ + internal class ResourceGroup(val resourceDirectoryName: String, vararg val resources: String) + + /** + * Copy resources from the current class loader to the resource directory. + * @param resourceDirectory The directory of the resource. + * @param targetResource The target resource. + * @param elementTag The element to copy. + */ + internal fun ResourceContext.copyXmlNode(resourceDirectory: String, targetResource: String, elementTag: String) { + val stringsResourceInputStream = ResourceUtils.javaClass.classLoader.getResourceAsStream("$resourceDirectory/$targetResource")!! + + // Copy nodes from the resources node to the real resource node + elementTag.copyXmlNode( + this.base.openXmlFile(stringsResourceInputStream.toString()), + this.base.openXmlFile("res/$targetResource") + ).close() + } + + /** + * Copies the specified node of the source [DomFileEditor] to the target [DomFileEditor]. + * @param source the source [DomFileEditor]. + * @param target the target [DomFileEditor]- + * @return AutoCloseable that closes the target [DomFileEditor]s. + */ + fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoCloseable { + val hostNodes = source.file.getElementsByTagName(this).item(0).childNodes + + val destinationResourceFile = target.file + val destinationNode = destinationResourceFile.getElementsByTagName(this).item(0) + + for (index in 0 until hostNodes.length) { + val node = hostNodes.item(index).cloneNode(true) + destinationResourceFile.adoptNode(node) + destinationNode.appendChild(node) + } + + return AutoCloseable { + source.close() + target.close() + } + } +} + diff --git a/src/main/kotlin/app/revanced/util/microg/Constants.kt b/src/main/kotlin/app/revanced/util/microg/Constants.kt deleted file mode 100644 index 912b97561..000000000 --- a/src/main/kotlin/app/revanced/util/microg/Constants.kt +++ /dev/null @@ -1,130 +0,0 @@ -package app.revanced.util.microg - -/** - * constants for microG builds with signature spoofing - */ -internal object Constants { - /** - * microG vendor name - * aka. package prefix / package base - */ - const val MICROG_VENDOR = "com.mgoogle" - - /** - * meta-data for microG package name spoofing on patched builds - */ - const val META_SPOOFED_PACKAGE_NAME = "$MICROG_VENDOR.android.gms.SPOOFED_PACKAGE_NAME" - - /** - * meta-data for microG package signature spoofing on patched builds - */ - const val META_SPOOFED_PACKAGE_SIGNATURE = "$MICROG_VENDOR.android.gms.SPOOFED_PACKAGE_SIGNATURE" - - /** - * meta-data for microG package detection - */ - const val META_GMS_PACKAGE_NAME = "app.revanced.MICROG_PACKAGE_NAME" - - /** - * a list of all permissions in microG - */ - val PERMISSIONS = listOf( - // C2DM / GCM - "com.google.android.c2dm.permission.RECEIVE", - "com.google.android.c2dm.permission.SEND", - "com.google.android.gtalkservice.permission.GTALK_SERVICE", - - // GAuth - "com.google.android.googleapps.permission.GOOGLE_AUTH", - "com.google.android.googleapps.permission.GOOGLE_AUTH.cp", - "com.google.android.googleapps.permission.GOOGLE_AUTH.local", - "com.google.android.googleapps.permission.GOOGLE_AUTH.mail", - "com.google.android.googleapps.permission.GOOGLE_AUTH.writely", - ) - - /** - * a list of all (intent) actions in microG - */ - val ACTIONS = listOf( - // location - "com.google.android.gms.location.places.ui.PICK_PLACE", - "com.google.android.gms.location.places.GeoDataApi", - "com.google.android.gms.location.places.PlacesApi", - "com.google.android.gms.location.places.PlaceDetectionApi", - "com.google.android.gms.wearable.MESSAGE_RECEIVED", - - // C2DM / GCM - "com.google.android.c2dm.intent.REGISTER", - "com.google.android.c2dm.intent.REGISTRATION", - "com.google.android.c2dm.intent.UNREGISTER", - "com.google.android.c2dm.intent.RECEIVE", - "com.google.iid.TOKEN_REQUEST", - "com.google.android.gcm.intent.SEND", - - // car - "com.google.android.gms.car.service.START", - - // people - "com.google.android.gms.people.service.START", - - // wearable - "com.google.android.gms.wearable.BIND", - - // auth - "com.google.android.gsf.login", - "com.google.android.gsf.action.GET_GLS", - "com.google.android.gms.common.account.CHOOSE_ACCOUNT", - "com.google.android.gms.auth.login.LOGIN", - "com.google.android.gms.auth.api.credentials.PICKER", - "com.google.android.gms.auth.api.credentials.service.START", - "com.google.android.gms.auth.service.START", - "com.google.firebase.auth.api.gms.service.START", - "com.google.android.gms.auth.be.appcert.AppCertService", - - // fido - "com.google.android.gms.fido.fido2.privileged.START", - - // games - "com.google.android.gms.games.service.START", - "com.google.android.gms.games.PLAY_GAMES_UPGRADE", - - // chimera - "com.google.android.gms.chimera", - - // fonts - "com.google.android.gms.fonts", - - // phenotype - "com.google.android.gms.phenotype.service.START", - - // location - "com.google.android.gms.location.reporting.service.START", - - // misc - "com.google.android.gms.gmscompliance.service.START", - "com.google.android.gms.oss.licenses.service.START", - "com.google.android.gms.safetynet.service.START", - "com.google.android.gms.tapandpay.service.BIND" - ) - - /** - * a list of all content provider authorities in microG - */ - val AUTHORITIES = listOf( - // gsf - "com.google.android.gsf.gservices", - "com.google.settings", - - // auth - "com.google.android.gms.auth.accounts", - - // chimera - "com.google.android.gms.chimera", - - // fonts - "com.google.android.gms.fonts", - - // phenotype - "com.google.android.gms.phenotype" - ) -} diff --git a/src/main/kotlin/app/revanced/util/microg/MicroGBytecodeHelper.kt b/src/main/kotlin/app/revanced/util/microg/MicroGBytecodeHelper.kt deleted file mode 100644 index b4b4038cb..000000000 --- a/src/main/kotlin/app/revanced/util/microg/MicroGBytecodeHelper.kt +++ /dev/null @@ -1,241 +0,0 @@ -package app.revanced.util.microg - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.util.proxy.mutableTypes.MutableClass -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.util.microg.Constants.ACTIONS -import app.revanced.util.microg.Constants.AUTHORITIES -import app.revanced.util.microg.Constants.MICROG_VENDOR -import app.revanced.util.microg.Constants.PERMISSIONS -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction21c -import org.jf.dexlib2.iface.instruction.formats.Instruction21c -import org.jf.dexlib2.iface.reference.StringReference -import org.jf.dexlib2.immutable.reference.ImmutableStringReference - -/** - * Helper class for applying bytecode patches needed for the microg-support patches. - */ -internal object MicroGBytecodeHelper { - /** - * Hook a method to check the availability of MicroG. - * - * @param fingerprint The fingerprint of the method to add the call for the notice in. - */ - fun injectNotice(fingerprint: MethodFingerprint) { - fingerprint.result!!.mutableMethod.addInstruction( - 0, - "invoke-static {}, Lapp/revanced/integrations/patches/MicroGSupport;->checkAvailability()V" - ) - } - - /** - * Transform strings with package name out of [fromPackageName] and [toPackageName]. - * - * @param fromPackageName Original package name. - * @param toPackageName The package name to accept. - **/ - fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? { - return { referencedString -> - when (referencedString) { - "$fromPackageName.SuggestionsProvider", - "$fromPackageName.fileprovider" -> referencedString.replace(fromPackageName, toPackageName) - else -> null - } - } - } - - /** - * Prime method data class for the [MicroGBytecodeHelper] class. - * - * @param primeMethodFingerprint The prime methods [MethodFingerprint]. - * @param fromPackageName Original package name. - * @param toPackageName The package name to accept. - **/ - data class PrimeMethodTransformationData( - val primeMethodFingerprint: MethodFingerprint, - val fromPackageName: String, - val toPackageName: String - ) { - /** - * Patch the prime method to accept the new package name. - */ - fun transformPrimeMethodPackageName() { - val primeMethod = primeMethodFingerprint.result!!.mutableMethod - val implementation = primeMethod.implementation!! - - var register = 2 - val index = implementation.instructions.indexOfFirst { - if (it.opcode != Opcode.CONST_STRING) return@indexOfFirst false - - val instructionString = ((it as Instruction21c).reference as StringReference).string - if (instructionString != fromPackageName) return@indexOfFirst false - - register = it.registerA - return@indexOfFirst true - } - - primeMethod.replaceInstruction( - index, "const-string v$register, \"$toPackageName\"" - ) - } - } - - /** - * Patch the bytecode to work with MicroG. - * Note: this only handles string constants to gms (intent actions, authorities, ...). - * If the app employs additional checks to validate the installed gms package, you'll have to handle those in the app- specific patch - * - * @param context The context. - * @param additionalStringTransforms Additional transformations applied to all const-string references. - * @param primeMethodTransformationData Data to patch the prime method. - * @param earlyReturns List of [MethodFingerprint] to return the resolved methods early. - */ - fun patchBytecode( - context: BytecodeContext, - additionalStringTransforms: Array<(str: String) -> String?>, - primeMethodTransformationData: PrimeMethodTransformationData, - earlyReturns: List - ) { - earlyReturns.returnEarly() - primeMethodTransformationData.transformPrimeMethodPackageName() - - val allTransforms = arrayOf( - MicroGBytecodeHelper::commonTransform, - MicroGBytecodeHelper::contentUrisTransform, - *additionalStringTransforms - ) - - // transform all strings using all provided transforms, first match wins - context.transformStringReferences transform@{ - for (transformFn in allTransforms) { - val s = transformFn(it) - if (s != null) return@transform s - } - - return@transform null - } - } - - /** - * const-string transform function for common gms string references. - * - * @param referencedString The string to transform. - */ - private fun commonTransform(referencedString: String): String? = - when (referencedString) { - "com.google", - "com.google.android.gms", - in PERMISSIONS, - in ACTIONS, - in AUTHORITIES -> referencedString.replace("com.google", MICROG_VENDOR) - - // subscribedfeeds has no vendor prefix for whatever reason... - "subscribedfeeds" -> "${MICROG_VENDOR}.subscribedfeeds" - else -> null - } - - - /** - * const-string transform function for strings containing gms content uris / authorities. - */ - private fun contentUrisTransform(str: String): String? { - // only when content:// uri - if (str.startsWith("content://")) { - // check if matches any authority - for (authority in AUTHORITIES) { - val uriPrefix = "content://$authority" - if (str.startsWith(uriPrefix)) { - return str.replace( - uriPrefix, - "content://${authority.replace("com.google", MICROG_VENDOR)}" - ) - } - } - - // gms also has a 'subscribedfeeds' authority, check for that one too - val subFeedsUriPrefix = "content://subscribedfeeds" - if (str.startsWith(subFeedsUriPrefix)) { - return str.replace(subFeedsUriPrefix, "content://${MICROG_VENDOR}.subscribedfeeds") - } - } - - return null - } - - /** - * Transform all constant string references using a transformation function. - * - * @param transformFn string transformation function. if null, string is not changed. - */ - private fun BytecodeContext.transformStringReferences(transformFn: (str: String) -> String?) { - classes.forEach { classDef -> - var mutableClass: MutableClass? = null - - // enumerate all methods - classDef.methods.forEach classLoop@{ methodDef -> - var mutableMethod: MutableMethod? = null - val implementation = methodDef.implementation ?: return@classLoop - - // enumerate all instructions and find const-string - implementation.instructions.forEachIndexed implLoop@{ index, instruction -> - // skip all that are not const-string - if (instruction.opcode != Opcode.CONST_STRING) return@implLoop - val str = ((instruction as Instruction21c).reference as StringReference).string - - // call transform function - val transformedStr = transformFn(str) - if (transformedStr != null) { - // make class and method mutable, if not already - mutableClass = mutableClass ?: proxy(classDef).mutableClass - mutableMethod = mutableMethod ?: mutableClass!!.methods.first { - it.name == methodDef.name && it.parameterTypes.containsAll(methodDef.parameterTypes) - } - - // replace instruction with updated string - mutableMethod!!.implementation!!.replaceInstruction( - index, - BuilderInstruction21c( - Opcode.CONST_STRING, - instruction.registerA, - ImmutableStringReference( - transformedStr - ) - ) - ) - } - } - } - } - } - - /** - * Return the resolved methods of a list of [MethodFingerprint] early. - */ - private fun List.returnEarly() { - this.forEach { fingerprint -> - val result = fingerprint.result!! - val stringInstructions = when (result.method.returnType.first()) { - 'L' -> """ - const/4 v0, 0x0 - return-object v0 - """ - - 'V' -> "return-void" - 'I' -> """ - const/4 v0, 0x0 - return v0 - """ - - else -> throw Exception("This case should never happen.") - } - result.mutableMethod.addInstructions( - 0, stringInstructions - ) - } - } -} diff --git a/src/main/kotlin/app/revanced/util/microg/MicroGManifestHelper.kt b/src/main/kotlin/app/revanced/util/microg/MicroGManifestHelper.kt deleted file mode 100644 index 003fa00e3..000000000 --- a/src/main/kotlin/app/revanced/util/microg/MicroGManifestHelper.kt +++ /dev/null @@ -1,58 +0,0 @@ -package app.revanced.util.microg - -import app.revanced.patcher.data.ResourceContext -import app.revanced.util.microg.Constants.META_GMS_PACKAGE_NAME -import app.revanced.util.microg.Constants.META_SPOOFED_PACKAGE_NAME -import app.revanced.util.microg.Constants.META_SPOOFED_PACKAGE_SIGNATURE -import app.revanced.util.microg.Constants.MICROG_VENDOR -import org.w3c.dom.Element -import org.w3c.dom.Node - -/** - * helper class for adding manifest metadata needed for microG builds with signature spoofing - */ -internal object MicroGManifestHelper { - - /** - * Add manifest entries needed for package and signature spoofing when using MicroG. - * Note: this only adds metadata entries for signature spoofing, other changes may still be required to make a microG patch work. - * - * @param context Resource context. - * @param spoofedPackage The package to spoof. - * @param spoofedSignature The signature to spoof. - */ - fun addSpoofingMetadata( - context: ResourceContext, - spoofedPackage: String, - spoofedSignature: String - ) { - context.xmlEditor["AndroidManifest.xml"].use { - val applicationNode = it - .file - .getElementsByTagName("application") - .item(0) - - // package spoofing - applicationNode.adoptChild("meta-data") { - setAttribute("android:name", META_SPOOFED_PACKAGE_NAME) - setAttribute("android:value", spoofedPackage) - } - applicationNode.adoptChild("meta-data") { - setAttribute("android:name", META_SPOOFED_PACKAGE_SIGNATURE) - setAttribute("android:value", spoofedSignature) - } - - // microG presence detection in integrations - applicationNode.adoptChild("meta-data") { - setAttribute("android:name", META_GMS_PACKAGE_NAME) - setAttribute("android:value", "${MICROG_VENDOR}.android.gms") - } - } - } - - private fun Node.adoptChild(tagName: String, block: Element.() -> Unit) { - val child = ownerDocument.createElement(tagName) - child.block() - appendChild(child) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/util/microg/MicroGResourceHelper.kt b/src/main/kotlin/app/revanced/util/microg/MicroGResourceHelper.kt deleted file mode 100644 index 5bf530967..000000000 --- a/src/main/kotlin/app/revanced/util/microg/MicroGResourceHelper.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.util.microg - -import app.revanced.patcher.data.ResourceContext -import app.revanced.util.resources.ResourceUtils.mergeStrings - -/** - * Helper class for applying resource patches needed for the microg-support patches. - */ -internal object MicroGResourceHelper { - - /** - * Add necessary strings to the strings.xml file. - * - * @param context The resource context. - * @param stringsHost The file which hosts the strings. - */ - fun addStrings(context: ResourceContext, stringsHost: String = "microg/host/values/strings.xml") = - context.mergeStrings(stringsHost) - - /** - * Patch the manifest to work with MicroG. - * - * @param context The resource context. - * @param fromPackageName The original package name. - * @param toPackageName The package name to accept. - * @param toName The new name of the app. - */ - fun patchManifest( - context: ResourceContext, - fromPackageName: String, - toPackageName: String, - toName: String - ) { - val manifest = context["AndroidManifest.xml"].readText() - context["AndroidManifest.xml"].writeText( - manifest.replace( - "package=\"$fromPackageName", - "package=\"$toPackageName" - ).replace( - "android:label=\"@string/app_name", - "android:label=\"$toName" - ).replace( - "android:label=\"@string/app_launcher_name", - "android:label=\"$toName" - ).replace( - "android:authorities=\"$fromPackageName", - "android:authorities=\"$toPackageName" - ).replace( - "$fromPackageName.permission.C2D_MESSAGE", - "$toPackageName.permission.C2D_MESSAGE" - ).replace( - "$fromPackageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION", - "$toPackageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" - ).replace( - "com.google.android.c2dm", - "${Constants.MICROG_VENDOR}.android.c2dm" - ).replace( - "", - "" - ) - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/util/patch/AbstractTransformInstructionsPatch.kt b/src/main/kotlin/app/revanced/util/patch/AbstractTransformInstructionsPatch.kt deleted file mode 100644 index 3a1b8f23b..000000000 --- a/src/main/kotlin/app/revanced/util/patch/AbstractTransformInstructionsPatch.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.util.patch - -import app.revanced.extensions.findMutableMethodOf -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import org.jf.dexlib2.iface.ClassDef -import org.jf.dexlib2.iface.Method -import org.jf.dexlib2.iface.instruction.Instruction - -internal abstract class AbstractTransformInstructionsPatch : BytecodePatch() { - - abstract fun filterMap( - classDef: ClassDef, - method: Method, - instruction: Instruction, - instructionIndex: Int - ): T? - - abstract fun transform(mutableMethod: MutableMethod, entry: T) - - override fun execute(context: BytecodeContext): PatchResult { - // Find all instructions - buildMap { - context.classes.forEach { classDef -> - classDef.methods.let { methods -> - buildMap methodList@{ - methods.forEach methods@{ method -> - with(method.implementation?.instructions ?: return@methods) { - ArrayDeque().also { patchIndices -> - this.forEachIndexed { index, instruction -> - val result = filterMap(classDef, method, instruction, index) - if (result != null) { - patchIndices.add(result) - } - } - }.also { if (it.isEmpty()) return@methods }.let { patches -> - put(method, patches) - } - } - } - } - }.also { if (it.isEmpty()) return@forEach }.let { methodPatches -> - put(classDef, methodPatches) - } - } - }.forEach { (classDef, methods) -> - // And finally transform the instructions... - with(context.proxy(classDef).mutableClass) { - methods.forEach { (method, patches) -> - val mutableMethod = findMutableMethodOf(method) - while (!patches.isEmpty()) { - transform(mutableMethod, patches.removeLast()) - } - } - } - } - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/util/patch/MethodCall.kt b/src/main/kotlin/app/revanced/util/patch/MethodCall.kt deleted file mode 100644 index fe21f4fc1..000000000 --- a/src/main/kotlin/app/revanced/util/patch/MethodCall.kt +++ /dev/null @@ -1,92 +0,0 @@ -package app.revanced.util.patch - -import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.ClassDef -import org.jf.dexlib2.iface.instruction.Instruction -import org.jf.dexlib2.iface.instruction.formats.Instruction35c -import org.jf.dexlib2.iface.reference.MethodReference - -internal typealias Instruction35cInfo = Triple - -internal interface IMethodCall { - val definedClassName: String - val methodName: String - val methodParams: Array - val returnType: String - - /** - * Replaces an invoke-virtual instruction with an invoke-static instruction, - * which calls a static replacement method in the respective integrations class. - * The method definition in the integrations class is expected to be the same, - * except that the method should be static and take as a first parameter - * an instance of the class, in which the original method was defined in. - * - * Example: - * - * original method: Window#setFlags(int, int) - * - * replacement method: Integrations#setFlags(Window, int, int) - */ - fun replaceInvokeVirtualWithIntegrations( - definingClassDescriptor: String, - method: MutableMethod, - instruction: Instruction35c, - instructionIndex: Int - ) { - val registers = arrayOf( - instruction.registerC, - instruction.registerD, - instruction.registerE, - instruction.registerF, - instruction.registerG - ) - val argsNum = methodParams.size + 1 // + 1 for instance of definedClassName - if (argsNum > registers.size) { - // should never happen, but just to be sure (also for the future) a safety check - throw RuntimeException( - "Not enough registers for ${definedClassName}#${methodName}: " + - "Required $argsNum registers, but only got ${registers.size}." - ) - } - - val args = registers.take(argsNum).joinToString(separator = ", ") { reg -> "v${reg}" } - val replacementMethodDefinition = - "${methodName}(${definedClassName}${methodParams.joinToString(separator = "")})${returnType}" - - method.replaceInstruction( - instructionIndex, - "invoke-static { $args }, ${definingClassDescriptor}->${replacementMethodDefinition}" - ) - } -} - -internal inline fun fromMethodReference(methodReference: MethodReference) - where E : Enum, E : IMethodCall = enumValues().firstOrNull { search -> - search.definedClassName == methodReference.definingClass - && search.methodName == methodReference.name - && methodReference.parameterTypes.toTypedArray().contentEquals(search.methodParams) -} - -internal inline fun filterMapInstruction35c( - integrationsClassDescriptorPrefix: String, - classDef: ClassDef, - instruction: Instruction, - instructionIndex: Int -): Instruction35cInfo? where E : Enum, E : IMethodCall { - if (classDef.type.startsWith(integrationsClassDescriptorPrefix)) { - // avoid infinite recursion - return null - } - - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) { - return null - } - - val invokeInstruction = instruction as Instruction35c - val methodRef = invokeInstruction.reference as MethodReference - val methodCall = fromMethodReference(methodRef) ?: return null - - return Instruction35cInfo(methodCall, invokeInstruction, instructionIndex) -} diff --git a/src/main/kotlin/app/revanced/util/resources/ResourceUtils.kt b/src/main/kotlin/app/revanced/util/resources/ResourceUtils.kt deleted file mode 100644 index be6a77486..000000000 --- a/src/main/kotlin/app/revanced/util/resources/ResourceUtils.kt +++ /dev/null @@ -1,99 +0,0 @@ -package app.revanced.util.resources - -import app.revanced.patcher.data.DomFileEditor -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.shared.settings.preference.impl.StringResource -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -import org.w3c.dom.Node -import java.nio.file.Files -import java.nio.file.StandardCopyOption - -internal object ResourceUtils { - - /** - * Merge strings. This manages [StringResource]s automatically. - * @param host The hosting xml resource. Needs to be a valid strings.xml resource. - */ - internal fun ResourceContext.mergeStrings(host: String) { - this.iterateXmlNodeChildren(host, "resources") { - // TODO: figure out why this is needed - if (!it.hasAttributes()) return@iterateXmlNodeChildren - - val attributes = it.attributes - val key = attributes.getNamedItem("name")!!.nodeValue!! - val value = it.textContent!! - - val formatted = attributes.getNamedItem("formatted") == null - - SettingsPatch.addString(key, value, formatted) - } - } - - /** - * Copy resources from the current class loader to the resource directory. - * @param sourceResourceDirectory The source resource directory name. - * @param resources The resources to copy. - */ - internal fun ResourceContext.copyResources(sourceResourceDirectory: String, vararg resources: ResourceGroup) { - val classLoader = ResourceUtils.javaClass.classLoader - val targetResourceDirectory = this["res"] - - for (resourceGroup in resources) { - resourceGroup.resources.forEach { resource -> - val resourceFile = "${resourceGroup.resourceDirectoryName}/$resource" - Files.copy( - classLoader.getResourceAsStream("$sourceResourceDirectory/$resourceFile")!!, - targetResourceDirectory.resolve(resourceFile).toPath(), StandardCopyOption.REPLACE_EXISTING - ) - } - } - } - - /** - * Resource names mapped to their corresponding resource data. - * @param resourceDirectoryName The name of the directory of the resource. - * @param resources A list of resource names. - */ - internal class ResourceGroup(val resourceDirectoryName: String, vararg val resources: String) - - /** - * Iterate through the children of a node by its tag. - * @param resource The xml resource. - * @param targetTag The target xml node. - * @param callback The callback to call when iterating over the nodes. - */ - internal fun ResourceContext.iterateXmlNodeChildren( - resource: String, - targetTag: String, - callback: (node: Node) -> Unit - ) = - xmlEditor[ResourceUtils.javaClass.classLoader.getResourceAsStream(resource)!!].use { - val stringsNode = it.file.getElementsByTagName(targetTag).item(0).childNodes - for (i in 1 until stringsNode.length - 1) callback(stringsNode.item(i)) - } - - - /** - * Copies the specified node of the source [DomFileEditor] to the target [DomFileEditor]. - * @param source the source [DomFileEditor]. - * @param target the target [DomFileEditor]- - * @return AutoCloseable that closes the target [DomFileEditor]s. - */ - fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoCloseable { - val hostNodes = source.file.getElementsByTagName(this).item(0).childNodes - - val destinationResourceFile = target.file - val destinationNode = destinationResourceFile.getElementsByTagName(this).item(0) - - for (index in 0 until hostNodes.length) { - val node = hostNodes.item(index).cloneNode(true) - destinationResourceFile.adoptNode(node) - destinationNode.appendChild(node) - } - - return AutoCloseable { - source.close() - target.close() - } - } -} \ No newline at end of file diff --git a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index 473330fee..000000000 Binary files a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index 0616301e7..000000000 Binary files a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-hdpi/ic_launcher.png b/src/main/resources/branding/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 333f5c3f8..000000000 Binary files a/src/main/resources/branding/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-hdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 333f5c3f8..000000000 Binary files a/src/main/resources/branding/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index f2e714894..000000000 Binary files a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index 4a454727f..000000000 Binary files a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-mdpi/ic_launcher.png b/src/main/resources/branding/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 947dca925..000000000 Binary files a/src/main/resources/branding/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-mdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 947dca925..000000000 Binary files a/src/main/resources/branding/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index 5ebd9b9b0..000000000 Binary files a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index af465feb9..000000000 Binary files a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xhdpi/ic_launcher.png b/src/main/resources/branding/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 811c31f28..000000000 Binary files a/src/main/resources/branding/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xhdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 811c31f28..000000000 Binary files a/src/main/resources/branding/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index fbeb03fcb..000000000 Binary files a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index 0c8936281..000000000 Binary files a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher.png b/src/main/resources/branding/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 7eca70426..000000000 Binary files a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 7eca70426..000000000 Binary files a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index b7b84772f..000000000 Binary files a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index bc688ad36..000000000 Binary files a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher.png b/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index e0fd48914..000000000 Binary files a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index e0fd48914..000000000 Binary files a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml b/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml deleted file mode 100644 index e97458c26..000000000 --- a/src/main/resources/copyvideourl/drawable/revanced_yt_copy.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml b/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml deleted file mode 100644 index f1c2e819d..000000000 --- a/src/main/resources/copyvideourl/drawable/revanced_yt_copy_timestamp.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/src/main/resources/copyvideourl/host/layout/youtube_controls_bottom_ui_container.xml b/src/main/resources/copyvideourl/host/layout/youtube_controls_bottom_ui_container.xml deleted file mode 100644 index 97ec1740f..000000000 --- a/src/main/resources/copyvideourl/host/layout/youtube_controls_bottom_ui_container.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/main/resources/downloads/drawable/revanced_yt_download_button.xml b/src/main/resources/downloads/drawable/revanced_yt_download_button.xml deleted file mode 100644 index 69ab6992b..000000000 --- a/src/main/resources/downloads/drawable/revanced_yt_download_button.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/main/resources/downloads/host/layout/youtube_controls_bottom_ui_container.xml b/src/main/resources/downloads/host/layout/youtube_controls_bottom_ui_container.xml deleted file mode 100644 index 23254785a..000000000 --- a/src/main/resources/downloads/host/layout/youtube_controls_bottom_ui_container.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/main/resources/downloads/host/values/strings.xml b/src/main/resources/downloads/host/values/strings.xml deleted file mode 100644 index 957d490fe..000000000 --- a/src/main/resources/downloads/host/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - is not installed. Please install it. - diff --git a/src/main/resources/microg/host/values/strings.xml b/src/main/resources/microg/host/values/strings.xml deleted file mode 100644 index 6d4c07436..000000000 --- a/src/main/resources/microg/host/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - Vanced MicroG is not installed. Please install it. - Vanced MicroG is failing to run. Please follow the "Don't kill my app" guide for Vanced MicroG. - diff --git a/src/main/resources/returnyoutubedislike/host/values/strings.xml b/src/main/resources/returnyoutubedislike/host/values/strings.xml deleted file mode 100644 index 31ca93597..000000000 --- a/src/main/resources/returnyoutubedislike/host/values/strings.xml +++ /dev/null @@ -1,51 +0,0 @@ - - Hidden - - Dislikes temporarily not available (API timed out) - Dislikes not available (status %d) - Dislikes not available (client API limit reached) - Dislikes not available (%s) - - - Reload video to vote using ReturnYouTubeDislike - - Return YouTube Dislike - Dislikes are shown - Dislikes are not shown - - Dislikes as percentage - Dislikes shown as percentage - Dislikes shown as number - - Compact like button - Like button styled for minimum width - Like button styled for best appearance - - About - ReturnYouTubeDislike.com - Dislike data is provided by the Return YouTube Dislike API. Tap here to learn more. - - - ReturnYouTubeDislike API statistics of this device - - API response time, average - API response time, minimum - API response time, maximum - - API response time, last video - Dislikes temporarily not available - Client API rate limit in effect - - API fetch votes, number of calls - No network calls made - %d network calls made - - API fetch votes, number of timeouts - No network calls timed out - %d network calls timed out - - API client rate limits - No client rate limits encountered - Client rate limit encountered %d times - - %d milliseconds - diff --git a/src/main/resources/settings/drawable-ldrtl-xxxhdpi/quantum_ic_arrow_back_white_24.png b/src/main/resources/settings/drawable-ldrtl-xxxhdpi/quantum_ic_arrow_back_white_24.png deleted file mode 100644 index d409b544b..000000000 Binary files a/src/main/resources/settings/drawable-ldrtl-xxxhdpi/quantum_ic_arrow_back_white_24.png and /dev/null differ diff --git a/src/main/resources/settings/drawable-xxxhdpi/quantum_ic_arrow_back_white_24.png b/src/main/resources/settings/drawable-xxxhdpi/quantum_ic_arrow_back_white_24.png deleted file mode 100644 index e27034d67..000000000 Binary files a/src/main/resources/settings/drawable-xxxhdpi/quantum_ic_arrow_back_white_24.png and /dev/null differ diff --git a/src/main/resources/settings/host/values/strings.xml b/src/main/resources/settings/host/values/strings.xml deleted file mode 100644 index c0740672f..000000000 --- a/src/main/resources/settings/host/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Do you wish to proceed? - diff --git a/src/main/resources/settings/layout/revanced_settings_toolbar.xml b/src/main/resources/settings/layout/revanced_settings_toolbar.xml deleted file mode 100644 index 86c717712..000000000 --- a/src/main/resources/settings/layout/revanced_settings_toolbar.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/main/resources/settings/layout/revanced_settings_with_toolbar.xml b/src/main/resources/settings/layout/revanced_settings_with_toolbar.xml deleted file mode 100644 index 21ff59780..000000000 --- a/src/main/resources/settings/layout/revanced_settings_with_toolbar.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/main/resources/settings/layout/revanced_settings_with_toolbar_layout.xml b/src/main/resources/settings/layout/revanced_settings_with_toolbar_layout.xml deleted file mode 100644 index 31b20d945..000000000 --- a/src/main/resources/settings/layout/revanced_settings_with_toolbar_layout.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main/resources/settings/xml/revanced_prefs.xml b/src/main/resources/settings/xml/revanced_prefs.xml deleted file mode 100644 index 9562c0097..000000000 --- a/src/main/resources/settings/xml/revanced_prefs.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/src/main/resources/sponsorblock/drawable-xxxhdpi/quantum_ic_skip_next_white_24.png b/src/main/resources/sponsorblock/drawable-xxxhdpi/quantum_ic_skip_next_white_24.png deleted file mode 100644 index 19c4929cc..000000000 Binary files a/src/main/resources/sponsorblock/drawable-xxxhdpi/quantum_ic_skip_next_white_24.png and /dev/null differ diff --git a/src/main/resources/sponsorblock/drawable/ic_sb_adjust.xml b/src/main/resources/sponsorblock/drawable/ic_sb_adjust.xml deleted file mode 100644 index 76a4b8bc9..000000000 --- a/src/main/resources/sponsorblock/drawable/ic_sb_adjust.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/main/resources/sponsorblock/drawable/ic_sb_compare.xml b/src/main/resources/sponsorblock/drawable/ic_sb_compare.xml deleted file mode 100644 index 04cc65e40..000000000 --- a/src/main/resources/sponsorblock/drawable/ic_sb_compare.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/main/resources/sponsorblock/drawable/ic_sb_edit.xml b/src/main/resources/sponsorblock/drawable/ic_sb_edit.xml deleted file mode 100644 index e93574bd9..000000000 --- a/src/main/resources/sponsorblock/drawable/ic_sb_edit.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/main/resources/sponsorblock/drawable/ic_sb_logo.xml b/src/main/resources/sponsorblock/drawable/ic_sb_logo.xml deleted file mode 100644 index c39b9e0b8..000000000 --- a/src/main/resources/sponsorblock/drawable/ic_sb_logo.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - diff --git a/src/main/resources/sponsorblock/drawable/ic_sb_publish.xml b/src/main/resources/sponsorblock/drawable/ic_sb_publish.xml deleted file mode 100644 index de4e58d3a..000000000 --- a/src/main/resources/sponsorblock/drawable/ic_sb_publish.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/main/resources/sponsorblock/drawable/ic_sb_voting.xml b/src/main/resources/sponsorblock/drawable/ic_sb_voting.xml deleted file mode 100644 index 30224f149..000000000 --- a/src/main/resources/sponsorblock/drawable/ic_sb_voting.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/main/resources/sponsorblock/host/layout/youtube_controls_layout.xml b/src/main/resources/sponsorblock/host/layout/youtube_controls_layout.xml deleted file mode 100644 index 33a11b83b..000000000 --- a/src/main/resources/sponsorblock/host/layout/youtube_controls_layout.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - diff --git a/src/main/resources/sponsorblock/host/values/strings.xml b/src/main/resources/sponsorblock/host/values/strings.xml deleted file mode 100644 index c8f014afc..000000000 --- a/src/main/resources/sponsorblock/host/values/strings.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - Enable SponsorBlock - SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos - - Appearance - Show voting button - Segment voting button is shown - Segment voting button is not shown - Use compact skip button - Skip button styled for minimum width - Skip button styled for best appearance - Automatically hide skip button - Skip button hides after a few seconds - Skip button displayed for entire segment - Show a toast when skipping automatically - Toast shown when a segment is automatically skipped. Tap here to see an example - Toast not shown. Tap here to see an example - Show video length without segments - Video length minus all segments, shown in parentheses next to the full video length - Full video length shown - - Creating new segments - Show create new segment button - Create new segment button is shown - Create new segment button is not shown - Adjust new segment step - Number of milliseconds the time adjustment buttons move when creating new segments - Value must be a positive number - View guidelines - Guidelines contain rules and tips for creating new segments - Follow the guidelines - Read the SponsorBlock guidelines before creating new segments - Already read - Show me - - General - Enable skip count tracking - Lets the SponsorBlock leaderboard know how much time is saved. A message is sent to the leaderboard each time a segment is skipped - Skip count tracking is not enabled - Minimum segment duration - Segments shorter than this value (in seconds) will not be shown or skipped - Your private user id - This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you - User id cannot be blank - Change API URL - The address SponsorBlock uses to make calls to the server. Do not change this unless you know what you\'re doing - API URL reset - API URL is invalid - API URL changed - Import/Export settings - Your SponsorBlock JSON configuration that can be imported/exported to ReVanced and other SponsorBlock platforms. This includes your private user id. Be sure to share this wisely - Settings imported successfully - Failed to import: %s - Failed to export settings (try clearing app data) - - Change segment behavior - Sponsor - Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shout-outs to causes/creators/websites/products they like - Unpaid/Self Promotion - Similar to \'Sponsor\' except for unpaid or self promotion. Includes sections about merchandise, donations, or information about who they collaborated with - Interaction Reminder (Subscribe) - A short reminder to like, subscribe or follow them in the middle of content. If it is long or about something specific, it should instead be under self promotion - Highlight - The part of the video that most people are looking for - Intermission/Intro Animation - An interval without actual content. Could be a pause, static frame, or repeating animation. Does not include transitions containing information - Endcards/Credits - Credits or when the YouTube endcards appear. Not for conclusions with information - Preview/Recap - Collection of clips that show what is coming up or what happened in the video or in other videos of a series, where all information is repeated elsewhere - Filler Tangent/Jokes - Tangential scenes added only for filler or humor that are not required to understand the main content of the video. Does not include segments providing context or background details - Music: Non-Music Section - Only for use in music videos. Sections of music videos without music, that aren\'t already covered by another category - - Skip - Highlight - Skip sponsor - Skip promo - Skip interact - Skip to highlight - Skip intro - Skip intermission - Skip intermission - Skip outro - Skip preview - Skip preview - Skip recap - Skip filler - Skip non-music - Skip segment - - Skipped sponsor - Skipped self promotion - Skipped annoying reminder - Skipped to highlight - Skipped intro - Skipped intermission - Skipped intermission - Skipped outro - Skipped preview - Skipped preview - Skipped recap - Skipped filler - Skipped a non-music section - Skipped unsubmitted segment - Skipped multiple segments - - Skip automatically - Skip automatically once - Show a skip button - Show in seek bar - Disable - - Can\'t submit the segment: %s - Unable to submit segments (API timed out) - Unable to submit segments (status: %d %s) - Can\'t submit the segment.\nRate Limited (too many from the same user or IP) - Can\'t submit the segment: %s - Can\'t submit the segment.\nAlready exists - Segment submitted successfully - - SponsorBlock temporarily not available - SponsorBlock temporarily not available (status %d) - SponsorBlock temporarily not available (API timed out) - - Unable to vote for segment (API timed out) - Unable to vote for segment (status: %d %s) - Unable to vote for segment: %s - Upvote - Downvote - Change category - There are no segments to vote for - - Choose the segment category - Category is disabled in settings. Enable category to submit. - New SponsorBlock segment - Set %02d:%02d:%03d as the start or end of a new segment? - start - end - now - Time the segment begins at - Time the segment ends at - Are the times correct? - The segment lasts from %02d:%02d to %02d:%02d (%d minutes %02d seconds)\nIs it ready to submit? - Start must be before the end - Mark two locations on the time bar first - Preview the segment, and ensure it skips smoothly - Edit timing of segment manually - Do you want to edit the timing for the start or end of the segment? - Invalid time given - - Stats - Stats temporarily not available (API is down) - Loading... - SponsorBlock is disabled - Your username: <b>%s</b> - Tap here to change your username - Unable to change username: Status: %d %s - Username successfully changed - Your reputation is <b>%.2f</b> - You\'ve created <b>%s</b> segments - SponsorBlock leaderboard - You\'ve saved people from <b>%s</b> segments - Tap here to see the global stats and top contributors - That\'s <b>%s</b> of their lives.<br>Tap here to see the leaderboard - You\'ve skipped <b>%s</b> segments - That\'s <b>%s</b> - Reset skipped segments counter? - %d hours %d minutes - %d minutes %d seconds - %d seconds - - Color: - Color changed - Color reset - Invalid color code - Reset color - - Reset - - About - sponsor.ajay.app - Data is provided by the SponsorBlock API. Tap here to learn more and see downloads for other platforms - ReVanced integration by JakubWeg,\nrecoded by oSumAtrIX - diff --git a/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml b/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml deleted file mode 100644 index 2c0385549..000000000 --- a/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/sponsorblock/layout/new_segment.xml b/src/main/resources/sponsorblock/layout/new_segment.xml deleted file mode 100644 index be5020be2..000000000 --- a/src/main/resources/sponsorblock/layout/new_segment.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml b/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml deleted file mode 100644 index 185960ec9..000000000 --- a/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/swipecontrols/drawable/ic_sc_brightness_auto.xml b/src/main/resources/swipecontrols/drawable/ic_sc_brightness_auto.xml deleted file mode 100644 index 469b33596..000000000 --- a/src/main/resources/swipecontrols/drawable/ic_sc_brightness_auto.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/main/resources/swipecontrols/drawable/ic_sc_brightness_manual.xml b/src/main/resources/swipecontrols/drawable/ic_sc_brightness_manual.xml deleted file mode 100644 index 2f6c7072d..000000000 --- a/src/main/resources/swipecontrols/drawable/ic_sc_brightness_manual.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/main/resources/swipecontrols/drawable/ic_sc_volume_mute.xml b/src/main/resources/swipecontrols/drawable/ic_sc_volume_mute.xml deleted file mode 100644 index 73dc595f4..000000000 --- a/src/main/resources/swipecontrols/drawable/ic_sc_volume_mute.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/main/resources/swipecontrols/drawable/ic_sc_volume_normal.xml b/src/main/resources/swipecontrols/drawable/ic_sc_volume_normal.xml deleted file mode 100644 index 30dff4be1..000000000 --- a/src/main/resources/swipecontrols/drawable/ic_sc_volume_normal.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/src/main/resources/theme/values-night-v31/styles.xml b/src/main/resources/theme/values-night-v31/styles.xml deleted file mode 100644 index 53da895f8..000000000 --- a/src/main/resources/theme/values-night-v31/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/src/main/resources/twitch/settings/xml/revanced_prefs.xml b/src/main/resources/twitch/settings/xml/revanced_prefs.xml deleted file mode 100644 index 14e1c85de..000000000 --- a/src/main/resources/twitch/settings/xml/revanced_prefs.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file