Compare commits

...

47 Commits

Author SHA1 Message Date
semantic-release-bot
23b182ccbb chore(release): 2.40.2 [skip ci]
## [2.40.2](https://github.com/revanced/revanced-patches/compare/v2.40.1...v2.40.2) (2022-08-22)

### Bug Fixes

* correct title for `tablet-miniplayer` setting switch ([6af6c02](4a784ecd6e))
2022-08-22 02:42:29 +00:00
oSumAtrIX
4a784ecd6e fix: correct title for tablet-miniplayer setting switch 2022-08-22 04:40:49 +02:00
semantic-release-bot
0165b53c6d chore(release): 2.40.1 [skip ci]
## [2.40.1](https://github.com/revanced/revanced-patches/compare/v2.40.0...v2.40.1) (2022-08-22)

### Bug Fixes

* add missing switch for `tablet-mini-player` patch ([244a1b2](17a0e16087))
2022-08-22 02:00:11 +00:00
oSumAtrIX
17a0e16087 fix: add missing switch for tablet-mini-player patch 2022-08-22 03:58:15 +02:00
semantic-release-bot
8cf91f39a5 chore(release): 2.40.0 [skip ci]
# [2.40.0](https://github.com/revanced/revanced-patches/compare/v2.39.1...v2.40.0) (2022-08-22)

### Features

* `settings` patch framework ([#266](https://github.com/revanced/revanced-patches/issues/266)) ([084a99b](9ef93f6618))
2022-08-22 00:02:00 +00:00
oSumAtrIX
9ef93f6618 feat: settings patch framework (#266) 2022-08-22 01:59:43 +02:00
semantic-release-bot
8c3866f5e3 chore(release): 2.39.1 [skip ci]
## [2.39.1](https://github.com/revanced/revanced-patches/compare/v2.39.0...v2.39.1) (2022-08-21)

### Bug Fixes

* make `custom-branding` cross-platform ([#366](https://github.com/revanced/revanced-patches/issues/366)) ([02ac62b](d115d649f4))
2022-08-21 00:35:21 +00:00
Alberto Ponces
d115d649f4 fix: make custom-branding cross-platform (#366) 2022-08-21 02:33:04 +02:00
semantic-release-bot
ddc789395e chore(release): 2.39.0 [skip ci]
# [2.39.0](https://github.com/revanced/revanced-patches/compare/v2.38.0...v2.39.0) (2022-08-19)

### Features

* bundle `dex` file into `jar` file ([#359](https://github.com/revanced/revanced-patches/issues/359)) ([f419252](e1200d4e3f))
2022-08-19 23:29:17 +00:00
Alberto Ponces
e1200d4e3f feat: bundle dex file into jar file (#359) 2022-08-20 01:26:59 +02:00
semantic-release-bot
8276340d2b chore(release): 2.38.0 [skip ci]
# [2.38.0](https://github.com/revanced/revanced-patches/compare/v2.37.0...v2.38.0) (2022-08-17)

### Features

* bump YouTube patches to `v17.32.35` ([#347](https://github.com/revanced/revanced-patches/issues/347)) ([5292a0e](8f32af4de1))
2022-08-17 17:13:42 +00:00
inotia00
8f32af4de1 feat: bump YouTube patches to v17.32.35 (#347) 2022-08-17 19:11:53 +02:00
semantic-release-bot
a2bc9f0722 chore(release): 2.37.0 [skip ci]
# [2.37.0](https://github.com/revanced/revanced-patches/compare/v2.36.2...v2.37.0) (2022-08-15)

### Features

* ˋpflotsh-ecmwf-subscription-unlockˋ patch ([#332](https://github.com/revanced/revanced-patches/issues/332)) ([ae2a1d8](f94bb06996))
2022-08-15 18:56:22 +00:00
Technikte
f94bb06996 feat: ˋpflotsh-ecmwf-subscription-unlockˋ patch (#332) 2022-08-15 20:54:22 +02:00
semantic-release-bot
1023936a26 chore(release): 2.36.2 [skip ci]
## [2.36.2](https://github.com/revanced/revanced-patches/compare/v2.36.1...v2.36.2) (2022-08-14)

### Bug Fixes

* disable cast modules in YouTube Music ([#337](https://github.com/revanced/revanced-patches/issues/337)) ([98e5dbc](98e5dbcc73))
2022-08-14 21:15:11 +00:00
Canny
98e5dbcc73 fix: disable cast modules in YouTube Music (#337) 2022-08-14 23:13:16 +02:00
semantic-release-bot
353806828b chore(release): 2.36.1 [skip ci]
## [2.36.1](https://github.com/revanced/revanced-patches/compare/v2.36.0...v2.36.1) (2022-08-14)

### Bug Fixes

* add missing switch for tablet mini-player ([1ad69e3](1ad69e350c))
2022-08-14 20:36:40 +00:00
oSumAtrIX
1ad69e350c fix: add missing switch for tablet mini-player 2022-08-14 22:34:44 +02:00
semantic-release-bot
42c562cff7 chore(release): 2.36.0 [skip ci]
# [2.36.0](https://github.com/revanced/revanced-patches/compare/v2.35.0...v2.36.0) (2022-08-14)

### Features

* `swipe-controls` override volume button behaviour ([#285](https://github.com/revanced/revanced-patches/issues/285)) ([155121f](155121f891))
2022-08-14 20:22:07 +00:00
Chris
155121f891 feat: swipe-controls override volume button behaviour (#285) 2022-08-14 22:19:54 +02:00
semantic-release-bot
c684a1c846 chore(release): 2.35.0 [skip ci]
# [2.35.0](https://github.com/revanced/revanced-patches/compare/v2.34.0...v2.35.0) (2022-08-14)

### Features

* `tiktok-ads` patch ([#335](https://github.com/revanced/revanced-patches/issues/335)) ([49ddc0a](49ddc0a2ed))
2022-08-14 20:18:06 +00:00
oSumAtrIX
49ddc0a2ed feat: tiktok-ads patch (#335) 2022-08-14 22:16:25 +02:00
semantic-release-bot
221b61acc7 chore(release): 2.34.0 [skip ci]
# [2.34.0](https://github.com/revanced/revanced-patches/compare/v2.33.2...v2.34.0) (2022-08-14)

### Features

* `tablet-mini-player` patch ([aab39cb](aab39cbe93))
2022-08-14 15:35:33 +00:00
oSumAtrIX
c133d495c3 build: bump patcher dependency version 2022-08-14 17:33:13 +02:00
oSumAtrIX
aab39cbe93 feat: tablet-mini-player patch 2022-08-14 17:32:32 +02:00
semantic-release-bot
bdab92faf2 chore(release): 2.33.2 [skip ci]
## [2.33.2](https://github.com/revanced/revanced-patches/compare/v2.33.1...v2.33.2) (2022-08-07)
2022-08-07 20:42:34 +00:00
oSumAtrIX
50acd3d3b5 refactor: remove unused parameter 2022-08-07 22:40:07 +02:00
oSumAtrIX
49a369a340 refactor: un-shadow variable name 2022-08-07 22:39:53 +02:00
oSumAtrIX
be8620bf91 build: bump patcher dependency version 2022-08-07 22:36:02 +02:00
semantic-release-bot
32ed4c9f04 chore(release): 2.33.1 [skip ci]
## [2.33.1](https://github.com/revanced/revanced-patches/compare/v2.33.0...v2.33.1) (2022-08-07)

### Bug Fixes

* spoof `X-Android-Cert` of Firebase `authToken` api request ([#315](https://github.com/revanced/revanced-patches/issues/315)) ([9c44497](9c44497d40))
2022-08-07 10:44:47 +00:00
Itroublve
9c44497d40 fix: spoof X-Android-Cert of Firebase authToken api request (#315) 2022-08-07 12:42:39 +02:00
semantic-release-bot
8e604139e3 chore(release): 2.33.0 [skip ci]
# [2.33.0](https://github.com/revanced/revanced-patches/compare/v2.32.1...v2.33.0) (2022-08-06)

### Features

* bump music patches to 5.17.51 ([#307](https://github.com/revanced/revanced-patches/issues/307)) ([3de3a82](3de3a82afb))
2022-08-06 23:04:00 +00:00
epicsampler
3de3a82afb feat: bump music patches to 5.17.51 (#307) 2022-08-07 01:02:08 +02:00
oSumAtrIX
d39fb7ca03 refactor: use approriate description 2022-08-05 03:48:03 +02:00
semantic-release-bot
2d995d3757 chore(release): 2.32.1 [skip ci]
## [2.32.1](https://github.com/revanced/revanced-patches/compare/v2.32.0...v2.32.1) (2022-08-04)

### Bug Fixes

* incorrect compatibilty attribute ([#296](https://github.com/revanced/revanced-patches/issues/296)) ([464c980](464c98093a))
2022-08-04 19:55:13 +00:00
Itroublve
464c98093a fix: incorrect compatibilty attribute (#296) 2022-08-04 21:53:29 +02:00
semantic-release-bot
6ac5ed441f chore(release): 2.32.0 [skip ci]
# [2.32.0](https://github.com/revanced/revanced-patches/compare/v2.31.0...v2.32.0) (2022-08-04)

### Features

* `promo-code-unlock` patch ([#292](https://github.com/revanced/revanced-patches/issues/292)) ([7925ca9](7925ca97c4))
2022-08-04 17:05:39 +00:00
Technikte
7925ca97c4 feat: promo-code-unlock patch (#292) 2022-08-04 19:03:56 +02:00
semantic-release-bot
0c5f117d5d chore(release): 2.31.0 [skip ci]
# [2.31.0](https://github.com/revanced/revanced-patches/compare/v2.30.1...v2.31.0) (2022-08-03)

### Features

* remove `force-vp9-codec` patch ([#287](https://github.com/revanced/revanced-patches/issues/287)) ([6ab475c](6ab475c284))
2022-08-03 18:30:49 +00:00
epicsampler
6ab475c284 feat: remove force-vp9-codec patch (#287) 2022-08-03 20:28:39 +02:00
semantic-release-bot
75ac69455b chore(release): 2.30.1 [skip ci]
## [2.30.1](https://github.com/revanced/revanced-patches/compare/v2.30.0...v2.30.1) (2022-08-03)

### Bug Fixes

* migrate to new patcher api ([e42043b](e42043b939))
2022-08-03 01:56:55 +00:00
oSumAtrIX
e42043b939 fix: migrate to new patcher api 2022-08-03 03:53:35 +02:00
semantic-release-bot
5237c3a1a6 chore(release): 2.30.0 [skip ci]
# [2.30.0](https://github.com/revanced/revanced-patches/compare/v2.29.0...v2.30.0) (2022-08-03)

### Bug Fixes

* incorrect fingerprint version [skip ci] ([a9abab9](a9abab97d7))
* rollback to `Dependencies` annotation ([f82aae9](f82aae930b))

### Features

* set the correct theme of the settings screen ([7d6f205](7d6f205fd9))
2022-08-03 01:11:48 +00:00
oSumAtrIX
7d6f205fd9 feat: set the correct theme of the settings screen 2022-08-03 03:09:52 +02:00
oSumAtrIX
f82aae930b fix: rollback to Dependencies annotation 2022-08-03 03:09:39 +02:00
oSumAtrIX
83b11c92af refactor: remove unused annotation [skip ci] 2022-08-03 02:23:27 +02:00
oSumAtrIX
a9abab97d7 fix: incorrect fingerprint version [skip ci] 2022-08-03 02:01:56 +02:00
147 changed files with 2292 additions and 1210 deletions

View File

@@ -31,9 +31,6 @@
"assets": [ "assets": [
{ {
"path": "build/libs/*.jar" "path": "build/libs/*.jar"
},
{
"path": "build/libs/*.dex"
} }
] ]
} }

View File

@@ -1,3 +1,144 @@
## [2.40.2](https://github.com/revanced/revanced-patches/compare/v2.40.1...v2.40.2) (2022-08-22)
### Bug Fixes
* correct title for `tablet-miniplayer` setting switch ([6af6c02](https://github.com/revanced/revanced-patches/commit/6af6c02154d170153093bd846dfcb7a6205dd6fa))
## [2.40.1](https://github.com/revanced/revanced-patches/compare/v2.40.0...v2.40.1) (2022-08-22)
### Bug Fixes
* add missing switch for `tablet-mini-player` patch ([244a1b2](https://github.com/revanced/revanced-patches/commit/244a1b2cb9f77272dc62287a4a34a487b0289295))
# [2.40.0](https://github.com/revanced/revanced-patches/compare/v2.39.1...v2.40.0) (2022-08-22)
### Features
* `settings` patch framework ([#266](https://github.com/revanced/revanced-patches/issues/266)) ([084a99b](https://github.com/revanced/revanced-patches/commit/084a99bc6f5ed67c0b270e219c2dd75a30f302f1))
## [2.39.1](https://github.com/revanced/revanced-patches/compare/v2.39.0...v2.39.1) (2022-08-21)
### Bug Fixes
* make `custom-branding` cross-platform ([#366](https://github.com/revanced/revanced-patches/issues/366)) ([02ac62b](https://github.com/revanced/revanced-patches/commit/02ac62b0ea7e47ff3aa5078ce4645421f410b154))
# [2.39.0](https://github.com/revanced/revanced-patches/compare/v2.38.0...v2.39.0) (2022-08-19)
### Features
* bundle `dex` file into `jar` file ([#359](https://github.com/revanced/revanced-patches/issues/359)) ([f419252](https://github.com/revanced/revanced-patches/commit/f4192526eab1e3e0208e7460847b892e077fcf5a))
# [2.38.0](https://github.com/revanced/revanced-patches/compare/v2.37.0...v2.38.0) (2022-08-17)
### Features
* bump YouTube patches to `v17.32.35` ([#347](https://github.com/revanced/revanced-patches/issues/347)) ([5292a0e](https://github.com/revanced/revanced-patches/commit/5292a0e973953225f94eed887a5d8f1ead17bb97))
# [2.37.0](https://github.com/revanced/revanced-patches/compare/v2.36.2...v2.37.0) (2022-08-15)
### Features
* ˋpflotsh-ecmwf-subscription-unlockˋ patch ([#332](https://github.com/revanced/revanced-patches/issues/332)) ([ae2a1d8](https://github.com/revanced/revanced-patches/commit/ae2a1d8362e388032c3521101ff60698c4af1583))
## [2.36.2](https://github.com/revanced/revanced-patches/compare/v2.36.1...v2.36.2) (2022-08-14)
### Bug Fixes
* disable cast modules in YouTube Music ([#337](https://github.com/revanced/revanced-patches/issues/337)) ([86eaba8](https://github.com/revanced/revanced-patches/commit/86eaba8248100987f46540a224956099bcf9da2c))
## [2.36.1](https://github.com/revanced/revanced-patches/compare/v2.36.0...v2.36.1) (2022-08-14)
### Bug Fixes
* add missing switch for tablet mini-player ([b824d35](https://github.com/revanced/revanced-patches/commit/b824d35960df9e99c2a2d248356c3c9342cfe130))
# [2.36.0](https://github.com/revanced/revanced-patches/compare/v2.35.0...v2.36.0) (2022-08-14)
### Features
* `swipe-controls` override volume button behaviour ([#285](https://github.com/revanced/revanced-patches/issues/285)) ([69465f3](https://github.com/revanced/revanced-patches/commit/69465f3a9934973a2449605a248a462510e10ff6))
# [2.35.0](https://github.com/revanced/revanced-patches/compare/v2.34.0...v2.35.0) (2022-08-14)
### Features
* `tiktok-ads` patch ([#335](https://github.com/revanced/revanced-patches/issues/335)) ([81bef57](https://github.com/revanced/revanced-patches/commit/81bef57742bfaefcdfe02fd290cca6923341149a))
# [2.34.0](https://github.com/revanced/revanced-patches/compare/v2.33.2...v2.34.0) (2022-08-14)
### Features
* `tablet-mini-player` patch ([dae41f1](https://github.com/revanced/revanced-patches/commit/dae41f1c59d26d00b1ba821dbe1521e68226f47c))
## [2.33.2](https://github.com/revanced/revanced-patches/compare/v2.33.1...v2.33.2) (2022-08-07)
## [2.33.1](https://github.com/revanced/revanced-patches/compare/v2.33.0...v2.33.1) (2022-08-07)
### Bug Fixes
* spoof `X-Android-Cert` of Firebase `authToken` api request ([#315](https://github.com/revanced/revanced-patches/issues/315)) ([c81d61f](https://github.com/revanced/revanced-patches/commit/c81d61f685449590473fa5205e7709f81872a9b9))
# [2.33.0](https://github.com/revanced/revanced-patches/compare/v2.32.1...v2.33.0) (2022-08-06)
### Features
* bump music patches to 5.17.51 ([#307](https://github.com/revanced/revanced-patches/issues/307)) ([c303589](https://github.com/revanced/revanced-patches/commit/c303589bd8d1956ce2e3c4c285d45a648b5db30f))
## [2.32.1](https://github.com/revanced/revanced-patches/compare/v2.32.0...v2.32.1) (2022-08-04)
### Bug Fixes
* incorrect compatibilty attribute ([#296](https://github.com/revanced/revanced-patches/issues/296)) ([0ab3e97](https://github.com/revanced/revanced-patches/commit/0ab3e9724157c628555964273c6b65f9f48f9664))
# [2.32.0](https://github.com/revanced/revanced-patches/compare/v2.31.0...v2.32.0) (2022-08-04)
### Features
* `promo-code-unlock` patch ([#292](https://github.com/revanced/revanced-patches/issues/292)) ([d5df2e6](https://github.com/revanced/revanced-patches/commit/d5df2e68f47cbb3d374b8ce24769872959014051))
# [2.31.0](https://github.com/revanced/revanced-patches/compare/v2.30.1...v2.31.0) (2022-08-03)
### Features
* remove `force-vp9-codec` patch ([#287](https://github.com/revanced/revanced-patches/issues/287)) ([e428978](https://github.com/revanced/revanced-patches/commit/e42897801b20e7439969954753e2c15c85eb41b5))
## [2.30.1](https://github.com/revanced/revanced-patches/compare/v2.30.0...v2.30.1) (2022-08-03)
### Bug Fixes
* migrate to new patcher api ([f43446e](https://github.com/revanced/revanced-patches/commit/f43446ed189e583302fcd899f5eb7517f2a77144))
# [2.30.0](https://github.com/revanced/revanced-patches/compare/v2.29.0...v2.30.0) (2022-08-03)
### Bug Fixes
* incorrect fingerprint version [skip ci] ([f8c62ae](https://github.com/revanced/revanced-patches/commit/f8c62ae16b088ff6d0e96a4ef62dc707cd83beb9))
* rollback to `Dependencies` annotation ([36a2ae8](https://github.com/revanced/revanced-patches/commit/36a2ae886c63f1d22bb1cca9e7110af6c3f6f2d3))
### Features
* set the correct theme of the settings screen ([70d850c](https://github.com/revanced/revanced-patches/commit/70d850cf295d306b0de9419efe6a4bbf3857d3a0))
# [2.29.0](https://github.com/revanced/revanced-patches/compare/v2.28.2...v2.29.0) (2022-08-02) # [2.29.0](https://github.com/revanced/revanced-patches/compare/v2.28.2...v2.29.0) (2022-08-02)

View File

@@ -20,21 +20,45 @@ Official patches by ReVanced
| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | all | | `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | all |
</details> </details>
### 📦 `com.garzotto.pflotsh.ecmwf_a`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `pflotsh-ecmwf-subscription-unlock` | Unlocks all subscription features. | 3.5.4 |
</details>
### 📦 `com.google.android.apps.youtube.music` ### 📦 `com.google.android.apps.youtube.music`
<details> <details>
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:| |:--------:|:--------------:|:-----------------:|
| `minimized-playback-music` | Enables minimized playback on Kids music. | 5.16.51 | | `minimized-playback-music` | Enables minimized playback on Kids music. | 5.17.51 |
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | 5.16.51 | | `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | 5.16.51 |
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.16.51 | | `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.17.51 |
| `compact-header` | Hides the music category bar at the top of the homepage. | 5.16.51 | | `compact-header` | Hides the music category bar at the top of the homepage. | 5.16.51 |
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.16.51 | | `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.17.51 |
| `background-play` | Enables playing music in the background. | 5.16.51 | | `background-play` | Enables playing music in the background. | 5.17.51 |
| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.16.51 | | `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.17.51 |
| `music-video-ads` | Removes ads in the music player. | 5.16.51 | | `music-video-ads` | Removes ads in the music player. | 5.17.51 |
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.16.51 | | `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.17.51 |
| `exclusive-audio-playback` | Enables the option to play music without video. | 5.16.51 | | `exclusive-audio-playback` | Enables the option to play music without video. | 5.17.51 |
</details>
### 📦 `de.dwd.warnapp`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all |
</details>
### 📦 `com.ss.android.ugc.trill`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `tiktok-ads` | Removes ads from TikTok. | all |
</details> </details>
### 📦 `com.google.android.youtube` ### 📦 `com.google.android.youtube`
@@ -42,34 +66,34 @@ Official patches by ReVanced
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:| |:--------:|:--------------:|:-----------------:|
| `swipe-controls` | Adds volume and brightness swipe controls. | 17.29.34 | | `swipe-controls` | Adds volume and brightness swipe controls. | 17.32.35 |
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.29.34 | | `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.32.35 |
| `minimized-playback` | Enables minimized and background playback. | 17.29.34 | | `amoled` | Enables pure black theme. | 17.32.35 |
| `amoled` | Enables pure black theme. | 17.29.34 | | `disable-create-button` | Hides the create button in the navigation bar. | 17.32.35 |
| `disable-create-button` | Hides the create button in the navigation bar. | 17.29.34 |
| `hide-cast-button` | Hides the cast button in the video player. | all | | `hide-cast-button` | Hides the cast button in the video player. | all |
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 17.29.34 | | `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 17.32.35 |
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.29.34 | | `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.32.35 |
| `premium-heading` | Shows premium branding on the home screen. | all | | `premium-heading` | Shows premium branding on the home screen. | all |
| `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all | | `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all |
| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 17.29.34 | | `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 17.32.35 |
| `old-quality-layout` | Enables the original quality flyout menu. | 17.29.34 | | `old-quality-layout` | Enables the original quality flyout menu. | 17.32.35 |
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.29.34 | | `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.32.35 |
| `hide-watermark` | Hides creator's watermarks on videos. | 17.29.34 | | `hide-watermark` | Hides creator's watermarks on videos. | 17.32.35 |
| `sponsorblock` | Integrate SponsorBlock. | 17.29.34 | | `sponsorblock` | Integrate SponsorBlock. | 17.32.35 |
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.29.34 | | `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.32.35 |
| `force-vp9-codec` | Forces the VP9 codec for videos. | 17.29.34 | | `tablet-mini-player` | Enables the tablet mini player layout. | 17.32.35 |
| `custom-video-buffer` | Lets you change the buffers of videos. Has no use without settings yet. | 17.29.34 | | `minimized-playback` | Enables minimized and background playback. | 17.32.35 |
| `always-autorepeat` | Always repeats the playing video again. | 17.29.34 | | `custom-video-buffer` | Lets you change the buffers of videos. | 17.32.35 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG | 17.29.34 | | `always-autorepeat` | Always repeats the playing video again. | 17.32.35 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG | 17.32.35 |
| `settings` | Adds settings for ReVanced to YouTube. | all | | `settings` | Adds settings for ReVanced to YouTube. | all |
| `enable-debugging` | Enables app debugging by patching the manifest file. | all | | `enable-debugging` | Enables app debugging by patching the manifest file. | all |
| `custom-playback-speed` | Adds more video playback speed options. | 17.29.34 | | `custom-playback-speed` | Adds more video playback speed options. | 17.32.35 |
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 17.29.34 | | `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 17.32.35 |
| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.29.34 | | `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.32.35 |
| `video-ads` | Removes ads in the video player. | 17.29.34 | | `video-ads` | Removes ads in the video player. | 17.32.35 |
| `general-ads` | Removes general ads. | 17.29.34 | | `general-ads` | Removes general ads. | 17.32.35 |
| `hide-infocard-suggestions` | Hides infocards in videos. | 17.29.34 | | `hide-infocard-suggestions` | Hides infocards in videos. | 17.32.35 |
</details> </details>

View File

@@ -22,20 +22,19 @@ repositories {
dependencies { dependencies {
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
implementation("app.revanced:revanced-patcher:3.3.0") implementation("app.revanced:revanced-patcher:3.3.3")
implementation("app.revanced:multidexlib2:2.5.2.r2") implementation("app.revanced:multidexlib2:2.5.2.r2")
} }
tasks { tasks {
register<DefaultTask>("generateDex") { register<DefaultTask>("generateBundle") {
description = "Generate dex files from build" description = "Generate dex files from build and bundle them in the jar file"
dependsOn(build) dependsOn(build)
doLast { doLast {
val androidHome = System.getenv("ANDROID_HOME") ?: throw GradleException("ANDROID_HOME not found") val androidHome = System.getenv("ANDROID_HOME") ?: throw GradleException("ANDROID_HOME not found")
val d8 = "${androidHome}/build-tools/32.0.0/d8" val d8 = "${androidHome}/build-tools/32.0.0/d8"
val input = configurations.archives.get().allArtifacts.files.files.first().absolutePath val input = configurations.archives.get().allArtifacts.files.files.first().absolutePath
val output = input.replace(".jar", ".dex")
val work = File("${buildDir}/libs") val work = File("${buildDir}/libs")
exec { exec {
@@ -45,7 +44,7 @@ tasks {
exec { exec {
workingDir = work workingDir = work
commandLine = listOf("mv", "classes.dex", output) commandLine = listOf("zip", "-u", input, "classes.dex")
} }
} }
} }
@@ -62,6 +61,6 @@ tasks {
register<DefaultTask>("publish") { register<DefaultTask>("publish") {
group = "publish" group = "publish"
description = "Dummy task" description = "Dummy task"
dependsOn(named("generateDex"), named("generateReadme")) dependsOn(named("generateBundle"), named("generateReadme"))
} }
} }

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.29.0 version = 2.40.2

View File

@@ -1,8 +1,10 @@
package app.revanced.extensions package app.revanced.extensions
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.toInstruction import app.revanced.patcher.util.smali.toInstruction
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
@@ -27,6 +29,30 @@ internal fun MutableMethodImplementation.injectHideCall(
) )
} }
/**
* traverse the class hierarchy starting from the given root class
*
* @param targetClass the class to start traversing the class hierarchy from
* @param callback function that is called for every class in the hierarchy
*/
fun BytecodeData.traverseClassHierarchy(targetClass: MutableClass, callback: MutableClass.() -> Unit) {
callback(targetClass)
this.findClass(targetClass.superclass ?: return)?.resolve()?.let {
traverseClassHierarchy(it, callback)
}
}
/**
* 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)
}
/** /**
* Insert an event hook at the top of the method. If the hook returns true, the event is consumed and the method will return with true * Insert an event hook at the top of the method. If the hook returns true, the event is consumed and the method will return with true
* *

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.description import app.revanced.patcher.extensions.PatchExtensions.description
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.patch.implementation.JarPatchBundle import app.revanced.patcher.util.patch.impl.JarPatchBundle
import java.io.File import java.io.File
object Generator { object Generator {

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class CodecsUnlockCompatibility internal annotation class CodecsUnlockCompatibility

View File

@@ -12,17 +12,14 @@ import org.jf.dexlib2.Opcode
@Name("codec-lock-fingerprint") @Name("codec-lock-fingerprint")
@MatchingMethod( @MatchingMethod(
"Labwj;", "Lacfr;",
"a", "a",
) )
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@CodecsUnlockCompatibility @CodecsUnlockCompatibility
@Version("0.0.1") @Version("0.0.1")
object CodecsLockFingerprint : MethodFingerprint( object CodecsLockFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf( "L", AccessFlags.PUBLIC or AccessFlags.STATIC, null, listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
@@ -37,5 +34,6 @@ object CodecsLockFingerprint : MethodFingerprint(
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.RETURN_OBJECT Opcode.RETURN_OBJECT
) ),
listOf("eac3_supported")
) )

View File

@@ -13,6 +13,7 @@ import app.revanced.patcher.util.smali.toInstruction
import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility 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.AllCodecsReferenceFingerprint
import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprint import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprint
import org.jf.dexlib2.Opcode
@Patch @Patch
@Name("codecs-unlock") @Name("codecs-unlock")
@@ -25,19 +26,29 @@ class CodecsUnlockPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
var result = CodecsLockFingerprint.result!! val codecsLockResult = CodecsLockFingerprint.result!!
val implementation = result.mutableMethod.implementation!! val implementation = codecsLockResult.mutableMethod.implementation!!
val instructionIndex = result.patternScanResult!!.startIndex val scanResultStartIndex = codecsLockResult.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
}
result = AllCodecsReferenceFingerprint.result!! val allCodecsResult = AllCodecsReferenceFingerprint.result!!
val codecMethod = val allCodecsMethod =
data.toMethodWalker(result.method).nextMethod(result.patternScanResult!!.startIndex).getMethod() data.toMethodWalker(allCodecsResult.method)
.nextMethod(allCodecsResult.patternScanResult!!.startIndex)
.getMethod()
implementation.replaceInstruction( implementation.replaceInstruction(
instructionIndex, instructionIndex,
"invoke-static {}, ${codecMethod.definingClass}->${codecMethod.name}()Ljava/util/Set;".toInstruction() "invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction()
) )
return PatchResultSuccess() return PatchResultSuccess()

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class ExclusiveAudioCompatibility internal annotation class ExclusiveAudioCompatibility

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class HideGetPremiumCompatibility internal annotation class HideGetPremiumCompatibility

View File

@@ -3,6 +3,11 @@ package app.revanced.patches.music.layout.tastebuilder.annotations
import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package 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( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
@@ -11,4 +16,3 @@ import app.revanced.patcher.annotation.Package
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class RemoveTasteBuilderCompatibility internal annotation class RemoveTasteBuilderCompatibility

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class RemoveUpgradeButtonCompatibility internal annotation class RemoveUpgradeButtonCompatibility

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.misc.microg.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
@Name("cast-context-fetch-fingerprint")
@MatchingMethod(
"Lvvz;", "a"
)
@DirectPatternScanMethod
@MicroGPatchCompatibility
@Version("0.0.1")
object CastContextFetchFingerprint : MethodFingerprint(
null, null, null, null,
listOf("Error fetching CastContext.")
)

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.misc.microg.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
@Name("cast-module-fingerprint")
@MatchingMethod(
"Llqh;", "c"
)
@DirectPatternScanMethod
@MicroGPatchCompatibility
@Version("0.0.1")
object CastDynamiteModuleFingerprint : MethodFingerprint(
null, null, null, null,
listOf("com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl")
)

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.misc.microg.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
@Name("cast-context-fetch-fingerprint")
@MatchingMethod(
"Lmcf;", "c"
)
@DirectPatternScanMethod
@MicroGPatchCompatibility
@Version("0.0.1")
object CastDynamiteModuleV2Fingerprint : MethodFingerprint(
null, null, null, null,
listOf("Failed to load module via V2: ")
)

View File

@@ -7,7 +7,7 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
@@ -27,7 +27,7 @@ import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableStringReference import org.jf.dexlib2.immutable.reference.ImmutableStringReference
@Patch @Patch
@Dependencies([MusicMicroGResourcePatch::class]) @DependsOn([MusicMicroGResourcePatch::class])
@Name("music-microg-support") @Name("music-microg-support")
@Description("Allows YouTube Music ReVanced to run without root and under a different package name.") @Description("Allows YouTube Music ReVanced to run without root and under a different package name.")
@MusicMicroGPatchCompatibility @MusicMicroGPatchCompatibility
@@ -36,6 +36,9 @@ class MusicMicroGBytecodePatch : BytecodePatch(
listOf( listOf(
ServiceCheckFingerprint, ServiceCheckFingerprint,
GooglePlayUtilityFingerprint, GooglePlayUtilityFingerprint,
CastDynamiteModuleFingerprint,
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
PrimeFingerprint, PrimeFingerprint,
) )
) { ) {
@@ -122,9 +125,17 @@ class MusicMicroGBytecodePatch : BytecodePatch(
listOf( listOf(
ServiceCheckFingerprint, ServiceCheckFingerprint,
GooglePlayUtilityFingerprint, GooglePlayUtilityFingerprint,
CastDynamiteModuleFingerprint,
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
).forEach { fingerprint -> ).forEach { fingerprint ->
val result = fingerprint.result!! val result = fingerprint.result!!
val stringInstructions = when (result.method.returnType.first()) { val stringInstructions = when (result.method.returnType.first()) {
'L' -> """
const/4 v0, 0x0
return-object v0
"""
'V' -> "return-void" 'V' -> "return-void"
'I' -> """ 'I' -> """
const/4 v0, 0x0 const/4 v0, 0x0

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51") "com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class BackgroundPlayCompatibility internal annotation class BackgroundPlayCompatibility

View File

@@ -0,0 +1,14 @@
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", arrayOf()),
Package("com.zhiliaoapp.musically", arrayOf())
]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class TiktokAdsCompatibility

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.tiktok.ad.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.ad.annotations.TiktokAdsCompatibility
@Name("feed-item-clone-fingerprint")
@MatchingMethod(
"Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;",
"clone",
)
@TiktokAdsCompatibility
@Version("0.0.1")
object FeedItemListCloneFingerprint : MethodFingerprint(
null, null, null, null,null, { methodDef ->
methodDef.definingClass.endsWith("/FeedItemList;") && methodDef.name == "clone"
}
)

View File

@@ -0,0 +1,48 @@
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.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction
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.patcher.patch.impl.BytecodePatch
import app.revanced.patches.tiktok.ad.annotations.TiktokAdsCompatibility
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("tiktok-ads")
@Description("Removes ads from TikTok.")
@TiktokAdsCompatibility
@Version("0.0.1")
class TiktokAdsPatch : BytecodePatch(
listOf(FeedItemListCloneFingerprint)
) {
override fun execute(data: BytecodeData): PatchResult {
val method = FeedItemListCloneFingerprint.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 clonePreloadAdsFieldInstruction = (instruction as? ReferenceInstruction)
if ((clonePreloadAdsFieldInstruction?.reference as? FieldReference)?.name != "preloadAds") continue
// set null instead of the field "preloadAds"
val overrideRegister = (clonePreloadAdsFieldInstruction as TwoRegisterInstruction).registerA
method.addInstruction(
index,
"const/4 v$overrideRegister, 0x0"
)
return PatchResultSuccess()
}
return PatchResultError("Could not find required instruction.")
}
}

View File

@@ -1,13 +1,13 @@
package app.revanced.patches.youtube.misc.forcevp9.annotations package app.revanced.patches.warnwetter.misc.firebasegetcert.annotations
import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.26.35", "17.27.39", "17.28.34", "17.29.34") "de.dwd.warnapp", arrayOf()
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class ForceVP9Compatibility internal annotation class FirebaseGetCertPatchCompatibility

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.warnwetter.misc.firebasegetcert.annotations.FirebaseGetCertPatchCompatibility
@Name("messaging-app-certificate-fingerprint")
@MatchingMethod(
"Lcom/google/firebase/installations/remote/c;", "f"
)
@FirebaseGetCertPatchCompatibility
@Version("0.0.1")
object GetMessagingCertFingerprint : MethodFingerprint(
"Ljava/lang/String;",
null,
null,
null,
listOf(
"ContentValues",
"Could not get fingerprint hash for package: ",
"No such package: "
)
)

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.warnwetter.misc.firebasegetcert.annotations.FirebaseGetCertPatchCompatibility
@Name("registration-app-certificate-fingerprint")
@MatchingMethod(
"Lcom/google/firebase/remoteconfig/internal/ConfigFetchHttpClient;", "f"
)
@FirebaseGetCertPatchCompatibility
@Version("0.0.1")
object GetReqistrationCertFingerprint : MethodFingerprint(
"Ljava/lang/String;",
null,
null,
null,
listOf(
"FirebaseRemoteConfig",
"Could not get fingerprint hash for package: ",
"No such package: "
)
)

View File

@@ -0,0 +1,45 @@
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.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints.*
import app.revanced.patches.warnwetter.misc.firebasegetcert.annotations.FirebaseGetCertPatchCompatibility
@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(data: BytecodeData): 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()
}
}

View File

@@ -0,0 +1,13 @@
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", arrayOf()
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class PromoCodeUnlockCompatibility

View File

@@ -0,0 +1,24 @@
package app.revanced.patches.warnwetter.misc.promocode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.warnwetter.misc.promocode.annotations.PromoCodeUnlockCompatibility
@Name("promo-code-unlock-fingerprint")
@MatchingMethod(
"Lde/dwd/warnapp/model/PromoTokenVerification;", "isValid"
)
@PromoCodeUnlockCompatibility
@Version("0.0.1")
object PromoCodeUnlockFingerprint : MethodFingerprint(
null,
null,
null,
null,
null,
{ methodDef ->
methodDef.definingClass.endsWith("PromoTokenVerification;") && methodDef.name == "isValid"
}
)

View File

@@ -0,0 +1,47 @@
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.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
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(data: BytecodeData): PatchResult {
val method = PromoCodeUnlockFingerprint.result!!.mutableMethod
method.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
@@ -23,6 +23,9 @@ import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensi
import app.revanced.patches.youtube.ad.general.bytecode.utils.MethodUtils.createMutableMethod import app.revanced.patches.youtube.ad.general.bytecode.utils.MethodUtils.createMutableMethod
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.MutableMethodImplementation import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.builder.instruction.* import org.jf.dexlib2.builder.instruction.*
@@ -38,7 +41,7 @@ import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
@Patch @Patch
@Dependencies([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class]) @DependsOn([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class, SettingsPatch::class])
@Name("general-ads") @Name("general-ads")
@Description("Removes general ads.") @Description("Removes general ads.")
@GeneralAdsCompatibility @GeneralAdsCompatibility
@@ -68,6 +71,135 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
) )
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference(
"revanced_home_ads_enabled",
StringResource("revanced_home_ads_enabled_title", "Hide home ads"),
true,
StringResource("revanced_home_ads_enabled_summary_on", "Home ads are shown"),
StringResource("revanced_home_ads_enabled_summary_off", "Home ads are hidden")
),
SwitchPreference(
"revanced_adremover_ad_removal",
StringResource("revanced_adremover_ad_removal_enabled_title", "Remove 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_merchandise",
StringResource("revanced_adremover_merchandise_enabled_title", "Remove 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", "Remove community posts"),
true,
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", "Remove 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_comments_removal",
StringResource("revanced_adremover_comments_enabled_title", "Remove comments section"),
false,
StringResource("revanced_adremover_comments_enabled_summary_on", "Comment section is hidden"),
StringResource("revanced_adremover_comments_enabled_summary_off", "Comment section is shown")
),
SwitchPreference(
"revanced_adremover_movie",
StringResource("revanced_adremover_movie_enabled_title", "Remove 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", "Remove 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_shelf",
StringResource("revanced_adremover_shorts_shelf_enabled_title", "Remove shorts shelf"),
true,
StringResource("revanced_adremover_shorts_shelf_enabled_summary_on", "Shorts shelves are hidden"),
StringResource("revanced_adremover_shorts_shelf_enabled_summary_off", "Shorts shelves are shown")
),
SwitchPreference(
"revanced_adremover_community_guidelines",
StringResource("revanced_adremover_community_guidelines_enabled_title", "Remove 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_emergency_box_removal",
StringResource("revanced_adremover_emergency_box_enabled_title", "Remove 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", "Remove info panels"),
true,
StringResource("revanced_adremover_info_panel_enabled_summary_on", "Merchandise banners are hidden"),
StringResource("revanced_adremover_info_panel_enabled_summary_off", "Merchandise banners are shown")
),
SwitchPreference(
"revanced_adremover_medical_panel",
StringResource("revanced_adremover_medical_panel_enabled_title", "Remove 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_adremover_paid_content",
StringResource("revanced_adremover_paid_content_enabled_title", "Remove 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_suggested",
StringResource("revanced_adremover_suggested_enabled_title", "Remove personal suggestions"),
true,
StringResource("revanced_adremover_suggested_enabled_summary_on", "Personal suggestions are hidden"),
StringResource("revanced_adremover_suggested_enabled_summary_off", "Personal suggestions are shown")
),
SwitchPreference(
"revanced_adremover_hide_suggestions",
StringResource("revanced_adremover_hide_suggestions_enabled_title", "Hide suggestions"),
true,
StringResource("revanced_adremover_hide_suggestions_enabled_summary_on", "Suggestions are hidden"),
StringResource("revanced_adremover_hide_suggestions_enabled_summary_off", "Suggestions are 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_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")
),
)
// iterating through all classes is expensive // iterating through all classes is expensive
for (classDef in data.classes) { for (classDef in data.classes) {
var mutableClass: MutableClass? = null var mutableClass: MutableClass? = null
@@ -174,7 +306,6 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
} }
Opcode.CONST_STRING -> { Opcode.CONST_STRING -> {
when (((instruction as Instruction21c).reference as StringReference).string) { when (((instruction as Instruction21c).reference as StringReference).string) {
stringReferences[0] -> { stringReferences[0] -> {
val stringInstruction = instructions.elementAt(3) val stringInstruction = instructions.elementAt(3)
@@ -200,23 +331,23 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
stringReferences[2] -> { // Litho ads stringReferences[2] -> { // Litho ads
// create proxied method. // create proxied method.
val proxy = data.proxy(classDef) val proxy = data.proxy(classDef)
val mutableClass = proxy.resolve() val proxiedClass = proxy.resolve()
// add getIsEmpty method // add getIsEmpty method
mutableClass.addGetIsEmptyMethod() proxiedClass.addGetIsEmptyMethod()
// get required method to patch and get references from // get required method to patch and get references from
val lithoMethod = getLithoMethod(mutableClass) val lithoMethod = getLithoMethod(proxiedClass)
?: return PatchResultError("Could not find required litho method to patch.") ?: return PatchResultError("Could not find required litho method to patch.")
val lithoMethodImplementation = lithoMethod.implementation!! val lithoMethodImplementation = lithoMethod.implementation!!
// create and add getTemplateName method // create and add getTemplateName method
val getTemplateMethod = val getTemplateMethod =
mutableClass.createGetTemplateNameMethod(lithoMethodImplementation) proxiedClass.createGetTemplateNameMethod(lithoMethodImplementation)
mutableClass.addMethod(getTemplateMethod) proxiedClass.addMethod(getTemplateMethod)
val lithoInstructions = lithoMethodImplementation.instructions val lithoInstructions = lithoMethodImplementation.instructions
val thisType = mutableClass.type val thisType = proxiedClass.type
val templateNameParameterType = getTemplateMethod.parameterTypes.first() val templateNameParameterType = getTemplateMethod.parameterTypes.first()
// get reference descriptors // get reference descriptors

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -9,17 +9,20 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsFingerprint import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsFingerprint
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsParentFingerprint import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("hide-infocard-suggestions") @Name("hide-infocard-suggestions")
@Description("Hides infocards in videos.") @Description("Hides infocards in videos.")
@HideInfocardSuggestionsCompatibility @HideInfocardSuggestionsCompatibility
@@ -30,6 +33,16 @@ class HideInfocardSuggestionsPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference(
"revanced_info_cards_enabled",
StringResource("revanced_info_cards_enabled_title", "Show info-cards"),
false,
StringResource("revanced_info_cards_enabled_summary_on", "Info-cards are shown"),
StringResource("revanced_info_cards_enabled_summary_off", "Info-cards are hidden")
)
)
val parentResult = HideInfocardSuggestionsParentFingerprint.result val parentResult = HideInfocardSuggestionsParentFingerprint.result
?: return PatchResultError("Parent fingerprint not resolved!") ?: return PatchResultError("Parent fingerprint not resolved!")

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,16 +8,19 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsConstructorFingerprint import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsConstructorFingerprint
import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsFingerprint import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("video-ads") @Name("video-ads")
@Description("Removes ads in the video player.") @Description("Removes ads in the video player.")
@VideoAdsCompatibility @VideoAdsCompatibility
@@ -28,7 +31,19 @@ class VideoAdsPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
ShowVideoAdsFingerprint.resolve(data, ShowVideoAdsConstructorFingerprint.result!!.classDef) SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference(
"revanced_video_ads_enabled",
StringResource("revanced_video_ads_enabled_title", "Hide video ads"),
true,
StringResource("revanced_video_ads_enabled_summary_on", "Video ads are hidden"),
StringResource("revanced_video_ads_enabled_summary_off", "Video ads are shown")
)
)
ShowVideoAdsFingerprint.resolve(
data, ShowVideoAdsConstructorFingerprint.result!!.classDef
)
// Override the parameter by calling shouldShowAds and setting the parameter to the result // Override the parameter by calling shouldShowAds and setting the parameter to the result
ShowVideoAdsFingerprint.result!!.mutableMethod.addInstructions( ShowVideoAdsFingerprint.result!!.mutableMethod.addInstructions(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,13 +8,16 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility 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.SeekbarTappingFingerprint
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingParentFingerprint import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
import org.jf.dexlib2.iface.Method import org.jf.dexlib2.iface.Method
@@ -22,7 +25,7 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction11n
import org.jf.dexlib2.iface.instruction.formats.Instruction35c import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("seekbar-tapping") @Name("seekbar-tapping")
@Description("Enables tap-to-seek on the seekbar of the video player.") @Description("Enables tap-to-seek on the seekbar of the video player.")
@SeekbarTappingCompatibility @SeekbarTappingCompatibility
@@ -33,6 +36,16 @@ class EnableSeekbarTappingPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): 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!! var result = SeekbarTappingParentFingerprint.result!!
val tapSeekMethods = mutableMapOf<String, Method>() val tapSeekMethods = mutableMapOf<String, Method>()
@@ -42,7 +55,7 @@ class EnableSeekbarTappingPatch : BytecodePatch(
if (it.implementation == null) continue if (it.implementation == null) continue
val instructions = it.implementation!!.instructions val instructions = it.implementation!!.instructions
// here we make sure we actually find the method because it has more then 7 instructions // here we make sure we actually find the method because it has more than 7 instructions
if (instructions.count() < 7) continue if (instructions.count() < 7) continue
// we know that the 7th instruction has the opcode CONST_4 // we know that the 7th instruction has the opcode CONST_4

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.24.34", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.youtube.interaction.swipecontrols.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
@Name("swipe-controls-host-activity-fingerprint")
@MatchingMethod(
"Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;", "<init>"
)
@DirectPatternScanMethod
@SwipeControlsCompatibility
@Version("0.0.1")
object SwipeControlsHostActivityFingerprint : MethodFingerprint(
null, null, null, null, null, { methodDef ->
methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;" && methodDef.name == "<init>"
}
)

View File

@@ -7,15 +7,15 @@ import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
@Name("watch-while-onStart-fingerprint") @Name("watch-while-activity-fingerprint")
@MatchingMethod( @MatchingMethod(
"LWatchWhileActivity;", "onCreate" "LWatchWhileActivity;", "<init>"
) )
@DirectPatternScanMethod @DirectPatternScanMethod
@SwipeControlsCompatibility @SwipeControlsCompatibility
@Version("0.0.1") @Version("0.0.1")
object WatchWhileOnStartFingerprint : MethodFingerprint( object WatchWhileActivityFingerprint : MethodFingerprint(
null, null, null, null, null, { methodDef -> null, null, null, null, null, { methodDef ->
methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "onStart" methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "<init>"
} }
) )

View File

@@ -1,45 +1,68 @@
package app.revanced.patches.youtube.interaction.swipecontrols.patch.bytecode package app.revanced.patches.youtube.interaction.swipecontrols.patch.bytecode
import app.revanced.extensions.transformMethods
import app.revanced.extensions.traverseClassHierarchy
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.WatchWhileOnStartFingerprint import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.SwipeControlsHostActivityFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.WatchWhileActivityFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.patch.resource.SwipeControlsResourcePatch 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.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playeroverlay.patch.PlayerOverlaysHookPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.immutable.ImmutableMethod
@Patch @Patch
@Name("swipe-controls") @Name("swipe-controls")
@Description("Adds volume and brightness swipe controls.") @Description("Adds volume and brightness swipe controls.")
@SwipeControlsCompatibility @SwipeControlsCompatibility
@Version("0.0.2") @Version("0.0.3")
@Dependencies( @DependsOn(
[ [
IntegrationsPatch::class, IntegrationsPatch::class,
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
PlayerOverlaysHookPatch::class,
SwipeControlsResourcePatch::class SwipeControlsResourcePatch::class
] ]
) )
class SwipeControlsBytecodePatch : BytecodePatch( class SwipeControlsBytecodePatch : BytecodePatch(
listOf( listOf(
WatchWhileOnStartFingerprint WatchWhileActivityFingerprint,
SwipeControlsHostActivityFingerprint
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
WatchWhileOnStartFingerprint.result!!.mutableMethod.addInstruction( val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
0, val targetClass = WatchWhileActivityFingerprint.result!!.mutableClass
"invoke-static { p0 }, Lapp/revanced/integrations/patches/SwipeControlsPatch;->WatchWhileActivity_onStartHookEX(Ljava/lang/Object;)V"
) // 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
data.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() return PatchResultSuccess()
} }
} }

View File

@@ -6,14 +6,91 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.*
@Name("swipe-controls-resource-patch") @Name("swipe-controls-resource-patch")
@DependsOn([SettingsPatch::class])
@SwipeControlsCompatibility @SwipeControlsCompatibility
@Version("0.0.1") @Version("0.0.1")
class SwipeControlsResourcePatch : ResourcePatch() { class SwipeControlsResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult { override fun execute(data: ResourceData): 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")
)
)
val resourcesDir = "swipecontrols" val resourcesDir = "swipecontrols"
data.injectResources( data.injectResources(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -6,7 +6,7 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility
@@ -15,7 +15,7 @@ import org.w3c.dom.Element
import java.io.File import java.io.File
@Patch @Patch
@Dependencies([FixLocaleConfigErrorPatch::class]) @DependsOn([FixLocaleConfigErrorPatch::class])
@Name("amoled") @Name("amoled")
@Description("Enables pure black theme.") @Description("Enables pure black theme.")
@AmoledCompatibility @AmoledCompatibility

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -14,10 +14,9 @@ import org.jf.dexlib2.Opcode
@MatchingMethod( @MatchingMethod(
"LWillAutonavInformer;", "k" "LWillAutonavInformer;", "k"
) )
@FuzzyPatternScanMethod(2)
@AutoplayButtonCompatibility @AutoplayButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
object AutonavInformerFingerprint : MethodFingerprint( object AutoNavInformerFingerprint : MethodFingerprint(
"Z", "Z",
AccessFlags.PUBLIC or AccessFlags.FINAL, AccessFlags.PUBLIC or AccessFlags.FINAL,
null, null,

View File

@@ -2,31 +2,19 @@ package app.revanced.patches.youtube.layout.autoplaybutton.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("layout-constructor-fingerprint") @Name("layout-constructor-fingerprint")
@MatchingMethod( @MatchingMethod(
"LYouTubeControlsOverlay;", "F" "LYouTubeControlsOverlay;", "F"
) )
@FuzzyPatternScanMethod(2)
@AutoplayButtonCompatibility @AutoplayButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
object LayoutConstructorFingerprint : MethodFingerprint( object LayoutConstructorFingerprint : MethodFingerprint(
"V", null, null, null, null, listOf("1.0x"),
AccessFlags.PUBLIC or AccessFlags.FINAL, { methodDef ->
null, methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
listOf( }
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
),
listOf("1.0x")
) )

View File

@@ -1,88 +0,0 @@
package app.revanced.patches.youtube.layout.autoplaybutton.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.AutonavInformerFingerprint
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch
@Dependencies([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class])
@Name("hide-autoplay-button")
@Description("Hides the autoplay button in the video player.")
@AutoplayButtonCompatibility
@Version("0.0.1")
class HideAutoplayButton : BytecodePatch(
listOf(
LayoutConstructorFingerprint, AutonavInformerFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val layoutGenMethod = LayoutConstructorFingerprint.result!!.mutableMethod
val autonavToggle =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "autonav_toggle" }
val autonavPreviewStub =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "autonav_preview_stub" }
val instructions = layoutGenMethod.implementation!!.instructions
val autonavToggleConstIndex =
instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavToggle.id } + 4
val autonavPreviewStubConstIndex =
instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavPreviewStub.id } + 4
injectIfBranch(layoutGenMethod, autonavToggleConstIndex)
injectIfBranch(layoutGenMethod, autonavPreviewStubConstIndex)
val autonavInformerMethod = AutonavInformerFingerprint.result!!.mutableMethod
//force disable autoplay since it's hard to do without the button
autonavInformerMethod.addInstructions(
0, """
invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z
move-result v0
if-nez v0, :hidden
const/4 v0, 0x0
return v0
:hidden
nop
"""
)
return PatchResultSuccess()
}
private fun injectIfBranch(method: MutableMethod, index: Int) {
val instructions = method.implementation!!.instructions
val insn = (instructions.get(index) as? Instruction35c)!!
val methodToCall = insn.reference.toString()
//remove the invoke-virtual because we want to put it in an if-statement
method.removeInstruction(index)
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z
move-result v11
if-eqz v11, :hidebutton
invoke-virtual {v${insn.registerC}, v${insn.registerD}, v${insn.registerE}}, $methodToCall
:hidebutton
nop
"""
)
}
}

View File

@@ -0,0 +1,92 @@
package app.revanced.patches.youtube.layout.autoplaybutton.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
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.patch.impl.BytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.AutoNavInformerFingerprint
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
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.MethodReference
@Patch
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, ResourceIdMappingProviderResourcePatch::class])
@Name("hide-autoplay-button")
@Description("Hides the autoplay button in the video player.")
@AutoplayButtonCompatibility
@Version("0.0.1")
class HideAutoplayButtonPatch : BytecodePatch(
listOf(
LayoutConstructorFingerprint, AutoNavInformerFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_autoplay_button_enabled",
StringResource("revanced_autoplay_button_enabled_title", "Show autoplay button"),
false,
StringResource("revanced_autoplay_button_summary_on", "Autoplay button is shown"),
StringResource("revanced_autoplay_button_summary_off", "Autoplay button is hidden")
)
)
val autoNavInformerMethod = AutoNavInformerFingerprint.result!!.mutableMethod
val layoutGenMethodResult = LayoutConstructorFingerprint.result!!
val layoutGenMethod = layoutGenMethodResult.mutableMethod
val layoutGenMethodInstructions = layoutGenMethod.implementation!!.instructions
// resolve the offsets such as ...
val autoNavPreviewStubId = ResourceIdMappingProviderResourcePatch.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
layoutGenMethod.addInstructions(
insertIndex, """
invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z
move-result v11
if-eqz v11, :hidden
""", listOf(ExternalLabel("hidden", jumpInstruction))
)
//force disable autoplay since it's hard to do without the button
autoNavInformerMethod.addInstructions(
0, """
invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z
move-result v0
if-nez v0, :hidden
const/4 v0, 0x0
return v0
:hidden
nop
"""
)
return PatchResultSuccess()
}
}

View File

@@ -7,7 +7,7 @@ import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility
@@ -17,7 +17,7 @@ import java.nio.file.StandardCopyOption
import kotlin.io.path.exists import kotlin.io.path.exists
@Patch @Patch
@Dependencies([FixLocaleConfigErrorPatch::class]) @DependsOn([FixLocaleConfigErrorPatch::class])
@Name("premium-heading") @Name("premium-heading")
@Description("Shows premium branding on the home screen.") @Description("Shows premium branding on the home screen.")
@PremiumHeadingCompatibility @PremiumHeadingCompatibility

View File

@@ -10,13 +10,14 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.InputStream import java.io.InputStream
import java.nio.file.Files import java.nio.file.Files
@Patch @Patch
@DependsOn(FixLocaleConfigErrorPatch::class) @DependsOn([FixLocaleConfigErrorPatch::class])
@Name("custom-branding") @Name("custom-branding")
@Description("Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).") @Description("Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).")
@CustomBrandingCompatibility @CustomBrandingCompatibility
@@ -45,9 +46,16 @@ class CustomBrandingPatch : ResourcePatch() {
val iconFile = getIconStream("branding/$size/$iconName.png") val iconFile = getIconStream("branding/$size/$iconName.png")
?: return PatchResultError("The icon $iconName can not be found.") ?: return PatchResultError("The icon $iconName can not be found.")
val outputStream = ByteArrayOutputStream()
iconFile.use { input ->
outputStream.use { output ->
input.copyTo(output)
}
}
Files.write( Files.write(
resDirectory.resolve("mipmap-$iconDirectory").resolve("$iconName.png").toPath(), resDirectory.resolve("mipmap-$iconDirectory").resolve("$iconName.png").toPath(),
iconFile.readAllBytes() outputStream.toByteArray()
) )
} }
} }

View File

@@ -5,22 +5,35 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.youtube.layout.castbutton.annotations.CastButtonCompatibility import app.revanced.patches.youtube.layout.castbutton.annotations.CastButtonCompatibility
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("hide-cast-button") @Name("hide-cast-button")
@Description("Hides the cast button in the video player.") @Description("Hides the cast button in the video player.")
@CastButtonCompatibility @CastButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideCastButtonPatch : BytecodePatch() { class HideCastButtonPatch : BytecodePatch() {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_cast_button_enabled",
StringResource("revanced_cast_button_enabled_title", "Show cast button"),
false,
StringResource("revanced_cast_button_summary_on", "Cast button is shown"),
StringResource("revanced_cast_button_summary_off", "Cast button is hidden")
)
)
data.classes.forEach { classDef -> data.classes.forEach { classDef ->
classDef.methods.forEach { method -> classDef.methods.forEach { method ->
if (classDef.type.endsWith("MediaRouteButton;") && method.name == "setVisibility") { if (classDef.type.endsWith("MediaRouteButton;") && method.name == "setVisibility") {

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -50,8 +50,5 @@ object CreateButtonFingerprint : MethodFingerprint(
Opcode.MOVE_OBJECT, Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT, Opcode.MOVE_OBJECT,
Opcode.INVOKE_DIRECT_RANGE, Opcode.INVOKE_DIRECT_RANGE,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
) )
) )

View File

@@ -8,13 +8,16 @@ import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.createbutton.annotations.CreateButtonCompatibility import app.revanced.patches.youtube.layout.createbutton.annotations.CreateButtonCompatibility
import app.revanced.patches.youtube.layout.createbutton.fingerprints.CreateButtonFingerprint import app.revanced.patches.youtube.layout.createbutton.fingerprints.CreateButtonFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@@ -22,7 +25,7 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Dependencies([IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class]) @DependsOn([IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class, SettingsPatch::class])
@Name("disable-create-button") @Name("disable-create-button")
@Description("Hides the create button in the navigation bar.") @Description("Hides the create button in the navigation bar.")
@CreateButtonCompatibility @CreateButtonCompatibility
@@ -33,6 +36,16 @@ class CreateButtonRemoverPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_create_button_enabled",
StringResource("revanced_create_button_enabled_title", "Show create button"),
false,
StringResource("revanced_create_button_summary_on", "Create button is shown."),
StringResource("revanced_create_button_summary_off", "Create button is hidden.")
)
)
val result = CreateButtonFingerprint.result!! val result = CreateButtonFingerprint.result!!
// Get the required register which holds the view object we need to pass to the method hideCreateButton // Get the required register which holds the view object we need to pass to the method hideCreateButton

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -10,17 +10,20 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.fullscreenpanels.annotations.FullscreenPanelsCompatibility import app.revanced.patches.youtube.layout.fullscreenpanels.annotations.FullscreenPanelsCompatibility
import app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints.FullscreenViewAdderFingerprint import app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints.FullscreenViewAdderFingerprint
import app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints.FullscreenViewAdderParentFingerprint import app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints.FullscreenViewAdderParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@Name("disable-fullscreen-panels") @Name("disable-fullscreen-panels")
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Description("Disables video description and comments panel in fullscreen view.") @Description("Disables video description and comments panel in fullscreen view.")
@FullscreenPanelsCompatibility @FullscreenPanelsCompatibility
@Version("0.0.1") @Version("0.0.1")
@@ -30,6 +33,16 @@ class FullscreenPanelsRemoverPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_fullscreen_panels_enabled",
StringResource("revanced_fullscreen_panels_enabled_title", "Show fullscreen panels"),
false,
StringResource("revanced_fullscreen_panels_summary_on", "Fullscreen panels are shown"),
StringResource("revanced_fullscreen_panels_summary_off", "Fullscreen panels are hidden")
)
)
val parentResult = FullscreenViewAdderParentFingerprint.result!! val parentResult = FullscreenViewAdderParentFingerprint.result!!
FullscreenViewAdderFingerprint.resolve(data, parentResult.method, parentResult.classDef) FullscreenViewAdderFingerprint.resolve(data, parentResult.method, parentResult.classDef)
val result = FullscreenViewAdderParentFingerprint.result val result = FullscreenViewAdderParentFingerprint.result

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -7,16 +7,19 @@ import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.QualityMenuViewInflateFingerprint import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.QualityMenuViewInflateFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("old-quality-layout") @Name("old-quality-layout")
@Description("Enables the original quality flyout menu.") @Description("Enables the original quality flyout menu.")
@OldQualityLayoutCompatibility @OldQualityLayoutCompatibility
@@ -25,6 +28,16 @@ class OldQualityLayoutPatch : BytecodePatch(
listOf(QualityMenuViewInflateFingerprint) listOf(QualityMenuViewInflateFingerprint)
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_use_old_style_quality_settings",
StringResource("revanced_old_style_quality_settings_enabled_title", "Use old quality layout"),
true,
StringResource("revanced_old_style_quality_settings_summary_on", "Old quality settings are shown"),
StringResource("revanced_old_style_quality_settings_summary_off", "New quality settings are shown")
)
)
val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!! val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!!
val method = inflateFingerprintResult.mutableMethod val method = inflateFingerprintResult.mutableMethod
val instructions = method.implementation!!.instructions val instructions = method.implementation!!.instructions

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -7,13 +7,18 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.reels.fingerprints.HideReelsFingerprint import app.revanced.patches.youtube.layout.reels.fingerprints.HideReelsFingerprint
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
//@Patch TODO: this is currently in the general-bytecode-ads patch due to the integrations having a preference for including reels or not. Move it here. //@Patch TODO: this is currently in the general-bytecode-ads patch due to the integrations having a preference for including reels or not. Move it here.
@Name("hide-reels") @Name("hide-reels")
@Description("Hides reels on the home page.") @Description("Hides reels on the home page.")
@DependsOn([SettingsPatch::class])
@HideReelsCompatibility @HideReelsCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideReelsPatch : BytecodePatch( class HideReelsPatch : BytecodePatch(
@@ -22,6 +27,16 @@ class HideReelsPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_reel_button_enabled",
StringResource("revanced_reel_button_enabled_title", "Show reels button"),
false,
StringResource("revanced_reel_button_summary_on", "Reels button is shown"),
StringResource("revanced_reel_button_summary_off", "Reels button is hidden")
)
)
val result = HideReelsFingerprint.result!! val result = HideReelsFingerprint.result!!
// HideReel will hide the reel view before it is being used, // HideReel will hide the reel view before it is being used,

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.14.35", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,19 +8,20 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.TextComponentSpecParentFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.DislikeFingerprint import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.DislikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.LikeFingerprint import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.LikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RemoveLikeFingerprint import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RemoveLikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.TextComponentSpecParentFingerprint
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.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
@Patch @Patch
@Dependencies([IntegrationsPatch::class, VideoIdPatch::class]) @DependsOn([IntegrationsPatch::class, VideoIdPatch::class, ReturnYouTubeDislikeResourcePatch::class])
@Name("return-youtube-dislike") @Name("return-youtube-dislike")
@Description("Shows the dislike count of videos using the Return YouTube Dislike API.") @Description("Shows the dislike count of videos using the Return YouTube Dislike API.")
@ReturnYouTubeDislikeCompatibility @ReturnYouTubeDislikeCompatibility
@@ -57,9 +58,9 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
val parentResult = TextComponentSpecParentFingerprint.result!! val parentResult = TextComponentSpecParentFingerprint.result!!
val createComponentMethod = parentResult.mutableClass.methods.find { method -> val createComponentMethod = parentResult.mutableClass.methods.find { method ->
method.parameters.size >= 19 && method.parameterTypes.takeLast(4) method.parameters.size >= 19 && method.parameterTypes.takeLast(4)
.all { param -> param == "Ljava/util/concurrent/atomic/AtomicReference;" } .all { param -> param == "Ljava/util/concurrent/atomic/AtomicReference;" }
} }
?: return PatchResultError("TextComponentSpec.createComponent not found") ?: return PatchResultError("TextComponentSpec.createComponent not found")
val conversionContextParam = 5 val conversionContextParam = 5

View File

@@ -0,0 +1,47 @@
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.impl.ResourceData
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.Preference
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.util.resources.ResourceUtils.iterateXmlNodeChildren
@DependsOn([FixLocaleConfigErrorPatch::class, SettingsPatch::class])
@Name("return-youtube-dislike-resource-patch")
@Description("Adds the preferences for Return YouTube Dislike.")
@ReturnYouTubeDislikeCompatibility
@Version("0.0.1")
class ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): 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
data.iterateXmlNodeChildren("returnyoutubedislike/host/values/strings.xml", "resources") {
// TODO: figure out why this is needed
if (!it.hasAttributes()) return@iterateXmlNodeChildren
val attributes = it.attributes
SettingsPatch.addString(attributes.getNamedItem("name")!!.nodeValue!!, it.textContent!!)
}
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -22,9 +22,6 @@ object PivotBarButtonTabEnumFingerprint : MethodFingerprint(
AccessFlags.PUBLIC or AccessFlags.FINAL, AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("Z"), listOf("Z"),
listOf( listOf(
Opcode.CHECK_CAST,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT, Opcode.SGET_OBJECT,
Opcode.IGET, Opcode.IGET,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
@@ -35,11 +32,5 @@ object PivotBarButtonTabEnumFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.INVOKE_STATIC, // SomeEnum.fromValue(tabOrdinal)
Opcode.MOVE_RESULT_OBJECT
) )
) )

View File

@@ -20,11 +20,6 @@ object PivotBarButtonsViewFingerprint : MethodFingerprint(
AccessFlags.PUBLIC or AccessFlags.FINAL, AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("Z"), listOf("Z"),
listOf( listOf(
Opcode.INVOKE_VIRTUAL_RANGE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.GOTO,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT, Opcode.SGET_OBJECT,
Opcode.IGET, Opcode.IGET,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,

View File

@@ -7,17 +7,21 @@ import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility
import app.revanced.patches.youtube.layout.shorts.button.fingerprints.PivotBarButtonTabEnumFingerprint import app.revanced.patches.youtube.layout.shorts.button.fingerprints.PivotBarButtonTabEnumFingerprint
import app.revanced.patches.youtube.layout.shorts.button.fingerprints.PivotBarButtonsViewFingerprint import app.revanced.patches.youtube.layout.shorts.button.fingerprints.PivotBarButtonsViewFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.Opcode
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("hide-shorts-button") @Name("hide-shorts-button")
@Description("Hides the shorts button on the navigation bar.") @Description("Hides the shorts button on the navigation bar.")
@ShortsButtonCompatibility @ShortsButtonCompatibility
@@ -28,27 +32,55 @@ class ShortsButtonRemoverPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_shorts_button_enabled",
StringResource("revanced_shorts_button_enabled_title", "Show shorts button"),
false,
StringResource("revanced_shorts_button_summary_on", "Shorts button is shown"),
StringResource("revanced_shorts_button_summary_off", "Shorts button is hidden")
)
)
val tabEnumResult = PivotBarButtonTabEnumFingerprint.result!! val tabEnumResult = PivotBarButtonTabEnumFingerprint.result!!
val tabEnumImplementation = tabEnumResult.mutableMethod.implementation!! val tabEnumImplementation = tabEnumResult.mutableMethod.implementation!!
val moveEnumInstruction = tabEnumImplementation.instructions[tabEnumResult.patternScanResult!!.endIndex] val scanResultEndIndex = tabEnumResult.patternScanResult!!.endIndex
val tabEnumIndex = scanResultEndIndex +
if (tabEnumImplementation.instructions[scanResultEndIndex + 1].opcode == Opcode.IGET_OBJECT) {
// for 17.31.xx and lower
7
} else {
// since 17.32.xx
10
}
val moveEnumInstruction = tabEnumImplementation.instructions[tabEnumIndex]
val enumRegister = (moveEnumInstruction as OneRegisterInstruction).registerA val enumRegister = (moveEnumInstruction as OneRegisterInstruction).registerA
val buttonsViewResult = PivotBarButtonsViewFingerprint.result!! val buttonsViewResult = PivotBarButtonsViewFingerprint.result!!
val buttonsViewImplementation = buttonsViewResult.mutableMethod.implementation!! val buttonsViewImplementation = buttonsViewResult.mutableMethod.implementation!!
val moveViewInstruction = buttonsViewImplementation.instructions[buttonsViewResult.patternScanResult!!.startIndex + 1] val scanResultStartIndex = buttonsViewResult.patternScanResult!!.startIndex
val buttonsViewIndex = scanResultStartIndex +
if (buttonsViewImplementation.instructions[scanResultStartIndex - 1].opcode == Opcode.IF_NEZ) {
// for 17.31.xx and lower
-3
} else {
// since 17.32.xx
-6
}
val moveViewInstruction = buttonsViewImplementation.instructions[buttonsViewIndex - 1]
val viewRegister = (moveViewInstruction as OneRegisterInstruction).registerA val viewRegister = (moveViewInstruction as OneRegisterInstruction).registerA
// Save the tab enum in XGlobals to avoid smali/register workarounds // Save the tab enum in XGlobals to avoid smali/register workarounds
tabEnumResult.mutableMethod.addInstruction( tabEnumResult.mutableMethod.addInstruction(
tabEnumResult.patternScanResult!!.endIndex + 1, tabEnumIndex,
"sput-object v$enumRegister, Lapp/revanced/integrations/patches/HideShortsButtonPatch;->lastPivotTab:Ljava/lang/Enum;" "sput-object v$enumRegister, Lapp/revanced/integrations/patches/HideShortsButtonPatch;->lastPivotTab:Ljava/lang/Enum;"
) )
// Hide the button view via proxy by passing it to the hideShortsButton method // Hide the button view via proxy by passing it to the hideShortsButton method
// It only hides it if the last tab name is "TAB_SHORTS" // It only hides it if the last tab name is "TAB_SHORTS"
buttonsViewResult.mutableMethod.addInstruction( buttonsViewResult.mutableMethod.addInstruction(
buttonsViewResult.patternScanResult!!.startIndex + 3, buttonsViewIndex + 1,
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideShortsButtonPatch;->hideShortsButton(Landroid/view/View;)V" "invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideShortsButtonPatch;->hideShortsButton(Landroid/view/View;)V"
) )

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.22.36", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.22.36", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -13,7 +13,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -37,7 +37,7 @@ import org.jf.dexlib2.immutable.ImmutableMethodParameter
import org.jf.dexlib2.util.MethodUtil import org.jf.dexlib2.util.MethodUtil
@Patch @Patch
@Dependencies( @DependsOn(
dependencies = [IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class, SponsorBlockResourcePatch::class, VideoIdPatch::class] dependencies = [IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class, SponsorBlockResourcePatch::class, VideoIdPatch::class]
) )
@Name("sponsorblock") @Name("sponsorblock")
@@ -147,7 +147,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
it.registerC to it.registerE it.registerC to it.registerE
} }
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
drawSegmentInstructionInsertIndex - 1, drawSegmentInstructionInsertIndex,
"invoke-static {v$canvasInstance, v$centerY}, Lapp/revanced/integrations/sponsorblock/PlayerController;->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V" "invoke-static {v$canvasInstance, v$centerY}, Lapp/revanced/integrations/sponsorblock/PlayerController;->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
) )

View File

@@ -5,100 +5,116 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.Preference
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
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.copyXmlNode
import java.nio.file.Files import app.revanced.util.resources.ResourceUtils.iterateXmlNodeChildren
@Name("sponsorblock-resource-patch") @Name("sponsorblock-resource-patch")
@SponsorBlockCompatibility @SponsorBlockCompatibility
@Dependencies([FixLocaleConfigErrorPatch::class]) @DependsOn([FixLocaleConfigErrorPatch::class, SettingsPatch::class])
@Version("0.0.1") @Version("0.0.1")
class SponsorBlockResourcePatch : ResourcePatch() { class SponsorBlockResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult { override fun execute(data: ResourceData): 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 val classLoader = this.javaClass.classLoader
/* /*
merge SponsorBlock strings to main strings merge SponsorBlock strings to main strings
*/ */
val stringsResourcePath = "values/strings.xml" data.iterateXmlNodeChildren("sponsorblock/host/values/strings.xml", "resources") {
val stringsResourceInputStream = classLoader.getResourceAsStream("sponsorblock/$stringsResourcePath")!! // TODO: figure out why this is needed
if (!it.hasAttributes()) return@iterateXmlNodeChildren
// copy nodes from the resources node to the real resource node val attributes = it.attributes
"resources".copyXmlNode( val key = attributes.getNamedItem("name")!!.nodeValue!!
data.xmlEditor[stringsResourceInputStream], val value = it.textContent!!
data.xmlEditor["res/$stringsResourcePath"]
).close() // close afterwards // all strings of SponsorBlock which have this attribute have the attribute value false,
// hence a null check suffices
val formatted = attributes.getNamedItem("formatted") == null
SettingsPatch.addString(key, value, formatted)
}
/* /*
merge SponsorBlock drawables to main drawables merge SponsorBlock drawables to main drawables
*/ */
val drawables = "drawable" to arrayOf(
"ic_sb_adjust",
"ic_sb_compare",
"ic_sb_edit",
"ic_sb_logo",
"ic_sb_publish",
"ic_sb_voting"
)
val layouts = "layout" to arrayOf( arrayOf(
"inline_sponsor_overlay", "new_segment", "skip_sponsor_button" ResourceUtils.ResourceGroup(
) "layout",
"inline_sponsor_overlay.xml",
// collect resources "new_segment.xml",
val xmlResources = arrayOf(drawables, layouts) "skip_sponsor_button.xml"
),
// write resources ResourceUtils.ResourceGroup(
xmlResources.forEach { (path, resourceNames) -> // required resource for back button, because when the base APK is used, this resource will not exist
resourceNames.forEach { name -> "drawable",
val relativePath = "$path/$name.xml" "ic_sb_adjust.xml",
"ic_sb_compare.xml",
Files.copy( "ic_sb_edit.xml",
classLoader.getResourceAsStream("sponsorblock/$relativePath")!!, "ic_sb_logo.xml",
data["res"].resolve(relativePath).toPath() "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 ->
data.copyResources("sponsorblock", resourceGroup)
} }
/* /*
merge xml nodes from the host to their real xml files merge xml nodes from the host to their real xml files
*/ */
// collect all host resources
val hostingXmlResources = mapOf("layout" to arrayOf("youtube_controls_layout"))
// copy nodes from host resources to their real xml files // copy nodes from host resources to their real xml files
hostingXmlResources.forEach { (path, resources) -> val hostingResourceStream =
resources.forEach { resource -> classLoader.getResourceAsStream("sponsorblock/host/layout/youtube_controls_layout.xml")!!
val hostingResourceStream = classLoader.getResourceAsStream("sponsorblock/host/$path/$resource.xml")!!
val targetXmlEditor = data.xmlEditor["res/$path/$resource.xml"] val targetXmlEditor = data.xmlEditor["res/layout/youtube_controls_layout.xml"]
"RelativeLayout".copyXmlNode( "RelativeLayout".copyXmlNode(
data.xmlEditor[hostingResourceStream], data.xmlEditor[hostingResourceStream],
targetXmlEditor targetXmlEditor
).also { ).also {
val children = targetXmlEditor.file.getElementsByTagName("RelativeLayout").item(0).childNodes val children = targetXmlEditor.file.getElementsByTagName("RelativeLayout").item(0).childNodes
// Replace the startOf with the voting button view so that the button does not overlap // Replace the startOf with the voting button view so that the button does not overlap
for (i in 1 until children.length) { for (i in 1 until children.length) {
val view = children.item(i) val view = children.item(i)
// Replace the attribute for a specific node only // Replace the attribute for a specific node only
if (!(view.hasAttributes() && view.attributes.getNamedItem("android:id").nodeValue.endsWith("live_chat_overlay_button"))) continue 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 // voting button id from the voting button view from the youtube_controls_layout.xml host file
val votingButtonId = "@+id/voting_button" val votingButtonId = "@+id/voting_button"
view.attributes.getNamedItem("android:layout_toStartOf").nodeValue = votingButtonId view.attributes.getNamedItem("android:layout_toStartOf").nodeValue = votingButtonId
break break
}
}.close() // close afterwards
} }
} }.close() // close afterwards
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -0,0 +1,13 @@
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("17.26.35", "17.29.34", "17.32.35")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class TabletMiniPlayerCompatibility

View File

@@ -0,0 +1,41 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-dimensions-calculator-fingerprint")
@MatchingMethod(
"Lkkr;", "pM"
)
@FuzzyPatternScanMethod(2) // TODO: Find a good threshold value
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L"),
listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.MUL_FLOAT,
Opcode.INVOKE_INTERFACE,
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.INVOKE_DIRECT,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.FLOAT_TO_DOUBLE,
Opcode.CONST_WIDE_HIGH16,
Opcode.CMPL_DOUBLE,
)
)

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-override-fingerprint")
@MatchingMethod(
"Lkkr;", "j"
)
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerOverrideFingerprint : MethodFingerprint(
"Z", AccessFlags.STATIC or AccessFlags.PUBLIC ,null,
listOf(Opcode.RETURN), // anchor to insert the instruction
)

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-override-no-context-fingerprint")
@MatchingMethod(
"Lkkr;", "k"
)
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint(
"Z", AccessFlags.FINAL or AccessFlags.PRIVATE ,null,
listOf(Opcode.RETURN), // anchor to insert the instruction
)

View File

@@ -0,0 +1,37 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-response-model-size-check-fingerprint")
@MatchingMethod(
"Lenv;", "a"
)
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerResponseModelSizeCheckFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L", "L"),
listOf(
Opcode.OR_INT_LIT8,
Opcode.IPUT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.RETURN_OBJECT,
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST,
Opcode.CHECK_CAST,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
),
null
)

View File

@@ -0,0 +1,103 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
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.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
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
)
) {
override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(SwitchPreference(
"revanced_tablet_miniplayer",
StringResource("revanced_tablet_miniplayer_title", "Enable the tablet Mini-player"),
false,
StringResource("revanced_tablet_miniplayer_summary_on", "Tablet Mini-player is enabled"),
StringResource("revanced_tablet_miniplayer_summary_off", "Tablet Mini-player is disabled")
))
// first resolve the fingerprints via the parent fingerprint
val miniPlayerClass = MiniPlayerDimensionsCalculatorFingerprint.result!!.classDef
/*
* no context parameter method
*/
MiniPlayerOverrideNoContextFingerprint.resolve(data, miniPlayerClass)
val (method, _, parameterRegister) = MiniPlayerOverrideNoContextFingerprint.addProxyCall()
// - 1 means to insert before the return instruction
val secondInsertIndex = method.implementation!!.instructions.size - 1
method.insertOverride(secondInsertIndex, parameterRegister /** same register used to return **/)
/*
* method with context parameter
*/
MiniPlayerOverrideFingerprint.resolve(data, miniPlayerClass)
val (_, _, _) = MiniPlayerOverrideFingerprint.addProxyCall()
/*
* size check return value override
*/
val (_, _, _) = MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall()
return PatchResultSuccess()
}
// helper methods
private companion object {
fun MethodFingerprint.addProxyCall(): Triple<MutableMethod, Int, Int> {
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<MutableMethod, Int, Int> {
val result = this.result!!
val scanIndex = result.patternScanResult!!.endIndex
val method = result.mutableMethod
val instructions = method.implementation!!.instructions
val parameterRegister = (instructions[scanIndex] as OneRegisterInstruction).registerA
return Triple(method, scanIndex, parameterRegister)
}
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -10,16 +10,19 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkParentFingerprint import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkParentFingerprint
import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkFingerprint import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("hide-watermark") @Name("hide-watermark")
@Description("Hides creator's watermarks on videos.") @Description("Hides creator's watermarks on videos.")
@HideWatermarkCompatibility @HideWatermarkCompatibility
@@ -30,6 +33,16 @@ class HideWatermarkPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_branding_watermark_enabled",
StringResource("revanced_branding_watermark_enabled_title", "Show branding watermark"),
false,
StringResource("revanced_branding_watermark_summary_on", "Branding watermark is shown"),
StringResource("revanced_branding_watermark_summary_off", "Branding watermark is hidden")
)
)
HideWatermarkFingerprint.resolve(data, HideWatermarkParentFingerprint.result!!.classDef) HideWatermarkFingerprint.resolve(data, HideWatermarkParentFingerprint.result!!.classDef)
val result = HideWatermarkFingerprint.result val result = HideWatermarkFingerprint.result
?: return PatchResultError("Required parent method could not be found.") ?: return PatchResultError("Required parent method could not be found.")

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -42,7 +42,7 @@ See:
*/ */
object WideSearchbarTwoFingerprint : MethodFingerprint( object WideSearchbarTwoFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf( "L", AccessFlags.PUBLIC or AccessFlags.STATIC, null, listOf(
Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_EQZ, Opcode.NEW_INSTANCE Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_EQZ, Opcode.NEW_INSTANCE
), ),
null, null null, null

View File

@@ -3,10 +3,8 @@ package app.revanced.patches.youtube.layout.widesearchbar.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
@@ -14,7 +12,6 @@ import org.jf.dexlib2.AccessFlags
@MatchingMethod( @MatchingMethod(
"Lkrf;", "i" "Lkrf;", "i"
) )
@FuzzyPatternScanMethod(3)
@WideSearchbarCompatibility @WideSearchbarCompatibility
@Version("0.0.1") @Version("0.0.1")

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -19,9 +19,12 @@ import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearch
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoFingerprint import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoParentFingerprint import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("enable-wide-searchbar") @Name("enable-wide-searchbar")
@Description("Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.") @Description("Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.")
@WideSearchbarCompatibility @WideSearchbarCompatibility
@@ -32,6 +35,16 @@ class WideSearchbarPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_wide_searchbar_enabled",
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")
)
)
WideSearchbarOneFingerprint.resolve(data, WideSearchbarOneParentFingerprint.result!!.classDef) WideSearchbarOneFingerprint.resolve(data, WideSearchbarOneParentFingerprint.result!!.classDef)
WideSearchbarTwoFingerprint.resolve(data, WideSearchbarTwoParentFingerprint.result!!.classDef) WideSearchbarTwoFingerprint.resolve(data, WideSearchbarTwoParentFingerprint.result!!.classDef)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -10,16 +10,19 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility 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.AutoRepeatFingerprint
import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
@Name("always-autorepeat") @Name("always-autorepeat")
@Description("Always repeats the playing video again.") @Description("Always repeats the playing video again.")
@AutoRepeatCompatibility @AutoRepeatCompatibility
@@ -30,6 +33,16 @@ class AutoRepeatPatch : BytecodePatch(
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_pref_auto_repeat",
StringResource("revanced_auto_repeat_enabled_title", "Enable auto-repeat"),
true,
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. //Get Result from the ParentFingerprint which is the playMethod we need to get.
val parentResult = AutoRepeatParentFingerprint.result val parentResult = AutoRepeatParentFingerprint.result
?: return PatchResultError("ParentFingerprint did not resolve.") ?: return PatchResultError("ParentFingerprint did not resolve.")

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.24.34", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
@@ -25,7 +25,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Name("custom-playback-speed") @Name("custom-playback-speed")
@Description("Adds more video playback speed options.") @Description("Adds more video playback speed options.")
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
@CustomPlaybackSpeedCompatibility @CustomPlaybackSpeedCompatibility
@Version("0.0.1") @Version("0.0.1")
class CustomPlaybackSpeedPatch : BytecodePatch( class CustomPlaybackSpeedPatch : BytecodePatch(
@@ -35,6 +35,8 @@ class CustomPlaybackSpeedPatch : BytecodePatch(
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
//TODO: include setting to skip remembering the new speed
val arrayGenMethod = SpeedArrayGeneratorFingerprint.result?.mutableMethod!! val arrayGenMethod = SpeedArrayGeneratorFingerprint.result?.mutableMethod!!
val arrayGenMethodImpl = arrayGenMethod.implementation!! val arrayGenMethodImpl = arrayGenMethod.implementation!!

View File

@@ -1,48 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("force-vp9-codec-fingerprint")
@MatchingMethod(
"Lpzs;", "aI"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ForceVP9CodecFingerprint : MethodFingerprint(
"Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "I"), listOf(
Opcode.SGET, Opcode.IF_NEZ, Opcode.INVOKE_STATIC
), null, null
)
/*
public static boolean aI(Context context, int i) {
if (b == 0) {
aH(context);
}
return b >= i; // Override to: return Lapp/revanced/integrations/patches/ForceCodecPatch->shouldForceVP9()
}
.method public static aI(Landroid/content/Context;I)Z
sget v0, Lpzs;->b:I
if-nez v0, :cond_7
invoke-static {p0}, Lpzs;->aH(Landroid/content/Context;)V
:cond_7
//remove after here, and inject only our code
sget p0, Lpzs;->b:I
if-lt p0, p1, :cond_d
const/4 p0, 0x1
return p0
:cond_d
const/4 p0, 0x0
return p0
.end method
*/

View File

@@ -1,73 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("force-vp9-codec-fingerprint-two")
@MatchingMethod(
"Lpzs;", "aO"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ForceVP9CodecFingerprintTwo : MethodFingerprint(
"Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("I"), listOf(
Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT_OBJECT, Opcode.CONST_4
), null, null
)
/*
public static boolean aO(int i) {
Pair aG = aG();
return (aG == null ? 0 : Math.min(((Integer) aG.first).intValue(), ((Integer) aG.second).intValue())) >= i;
//replace line with: return Lapp/revanced/integrations/patches/ForceCodecPatch/shouldForceVP9();
}
becomes:
public static boolean aO(int i) {
return Lapp/revanced/integrations/patches/ForceCodecPatch/shouldForceVP9();
}
.method public static aO(I)Z
invoke-static {}, Lpzs;->aG()Landroid/util/Pair;
move-result-object v0
const/4 v1, 0x0
if-nez v0, :cond_9
const/4 v0, 0x0
goto :goto_1d
:cond_9
iget-object v2, v0, Landroid/util/Pair;->first:Ljava/lang/Object;
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
iget-object v0, v0, Landroid/util/Pair;->second:Ljava/lang/Object;
check-cast v0, Ljava/lang/Integer;
invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
move-result v0
invoke-static {v2, v0}, Ljava/lang/Math;->min(II)I
move-result v0
:goto_1d
if-lt v0, p0, :cond_21
const/4 p0, 0x1
return p0
:cond_21
return v1
.end method
becomes:
.method public static aO(I)Z
invoke-static {}, Lapp/revanced/integrations/patches/ForceCodecPatch;->shouldForceVP9()Z
move-result v0
return v0
.end method
*/

View File

@@ -1,24 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
@Name("force-vp9-codec-parent-fingerprint")
@MatchingMethod(
"Lqaa;", "U"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ForceVP9ParentFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf(), null,
listOf(
"sys.display-size", "x"
)
)

View File

@@ -1,30 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
@Name("replace-device-info-parent-fingerprint")
@MatchingMethod(
"Lvjb;", "e"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ReplaceDeviceInfoFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), null,
null,
customFingerprint = { methodDef ->
methodDef.implementation!!.instructions.any {
((it as? ReferenceInstruction)?.reference as? FieldReference)?.definingClass.equals("Landroid/os/Build;")
&& ((it as? ReferenceInstruction)?.reference as? FieldReference)?.name.equals("MANUFACTURER")
}
}
)

View File

@@ -1,24 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
@Name("replace-device-info-parent-fingerprint")
@MatchingMethod(
"Lvjb;", "b"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ReplaceDeviceInfoParentFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), null,
listOf(
"Failed to read the client side experiments map from the disk"
)
)

View File

@@ -1,87 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.extensions.removeInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.misc.forcevp9.annotations.ForceVP9Compatibility
import app.revanced.patches.youtube.misc.forcevp9.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
@Patch
@Dependencies([IntegrationsPatch::class])
@Name("force-vp9-codec")
@Description("Forces the VP9 codec for videos.")
@ForceVP9Compatibility
@Version("0.0.1")
class ForceVP9CodecPatch : BytecodePatch(
listOf(
ForceVP9ParentFingerprint, ReplaceDeviceInfoParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val classDef = ForceVP9ParentFingerprint.result!!.classDef
ForceVP9CodecFingerprint.resolve(data, classDef)
ForceVP9CodecFingerprintTwo.resolve(data, classDef)
replaceInstructions(ForceVP9CodecFingerprint.result!!)
replaceInstructions(ForceVP9CodecFingerprintTwo.result!!)
ReplaceDeviceInfoFingerprint.resolve(data, ReplaceDeviceInfoParentFingerprint.result!!.classDef)
var method = ReplaceDeviceInfoFingerprint.result!!.mutableMethod
replaceDeviceInfos("Manufacturer", method)
replaceDeviceInfos("Model", method)
return PatchResultSuccess()
}
private fun replaceInstructions(result: MethodFingerprintResult) {
val method = result.mutableMethod
method.removeInstructions(0, method.implementation!!.instructions.size - 1)
method.addInstructions(
0, """
invoke-static {}, Lapp/revanced/integrations/patches/ForceCodecPatch;->shouldForceVP9()Z
move-result v0
return v0
"""
)
}
private fun replaceDeviceInfos(name: String, method: MutableMethod) {
var impl = method.implementation!!
//find target instruction for Build.name.uppercase() and replace that with our method
impl.instructions.filter {
((it as? ReferenceInstruction)?.reference as? FieldReference)?.let { field ->
//sget-object v1, Landroid/os/Build;->MANUFACTURER:Ljava/lang/String;
//sget-object v1, Landroid/os/Build;->MODEL:Ljava/lang/String;
field.definingClass == "Landroid/os/Build;" && field.name == name.uppercase()
} == true
}.forEach { instruction ->
val index = method.implementation!!.instructions.indexOf(instruction)
val register = (instruction as OneRegisterInstruction).registerA
// inject the call to
method.removeInstruction(index)
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/ForceCodecPatch;->get$name()Ljava/lang/String;
move-result-object v$register
"""
)
}
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -8,12 +8,15 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.hdrbrightness.annotations.HDRBrightnessCompatibility import app.revanced.patches.youtube.misc.hdrbrightness.annotations.HDRBrightnessCompatibility
import app.revanced.patches.youtube.misc.hdrbrightness.fingerprints.HDRBrightnessFingerprintXXZ import app.revanced.patches.youtube.misc.hdrbrightness.fingerprints.HDRBrightnessFingerprintXXZ
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.reference.FieldReference import org.jf.dexlib2.iface.reference.FieldReference
@@ -23,13 +26,23 @@ import org.jf.dexlib2.iface.reference.FieldReference
@Description("Makes the brightness of HDR videos follow the system default.") @Description("Makes the brightness of HDR videos follow the system default.")
@HDRBrightnessCompatibility @HDRBrightnessCompatibility
@Version("0.0.2") @Version("0.0.2")
@Dependencies([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
class HDRBrightnessPatch : BytecodePatch( class HDRBrightnessPatch : BytecodePatch(
listOf( listOf(
HDRBrightnessFingerprintXXZ HDRBrightnessFingerprintXXZ
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): 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 = HDRBrightnessFingerprintXXZ.result?.mutableMethod val method = HDRBrightnessFingerprintXXZ.result?.mutableMethod
?: return PatchResultError("HDRBrightnessFingerprint could not resolve the method!") ?: return PatchResultError("HDRBrightnessFingerprint could not resolve the method!")

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

Some files were not shown because too many files have changed in this diff Show More