mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-26 04:01:02 +00:00
Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d22fc2d2f | ||
|
|
6e6dbd0c1a | ||
|
|
4272fade4f | ||
|
|
2095e34db8 | ||
|
|
1483a9d8bb | ||
|
|
ea113f01a3 | ||
|
|
d4658c7056 | ||
|
|
a615717580 | ||
|
|
04db353154 | ||
|
|
7cb0312a9d | ||
|
|
5357ff2e48 | ||
|
|
62083ead98 | ||
|
|
6f04169117 | ||
|
|
cc1b283cb7 | ||
|
|
4597a74e32 | ||
|
|
3734545ca6 | ||
|
|
60ef90c745 | ||
|
|
ece4ac1a9e | ||
|
|
d6e17f948d | ||
|
|
9ab3bd0313 | ||
|
|
0f10888aa3 | ||
|
|
63c0e5dc84 | ||
|
|
41bc0222b9 | ||
|
|
71e4cc964b | ||
|
|
afc9886ebd | ||
|
|
de06d96ea0 | ||
|
|
1139f77cb9 | ||
|
|
5a801b1562 | ||
|
|
7f301090b9 | ||
|
|
28a687c605 | ||
|
|
9b74a08ae1 | ||
|
|
1177c41373 | ||
|
|
be4de62c8f | ||
|
|
528156aec9 | ||
|
|
e377ecf208 | ||
|
|
fa147bd6cc | ||
|
|
88211e28ca | ||
|
|
a4e3a97937 | ||
|
|
02bd807a27 | ||
|
|
a06e81ae39 | ||
|
|
a87d0bc440 | ||
|
|
a2b64f63e0 | ||
|
|
80ab1592c3 | ||
|
|
e17f476c46 | ||
|
|
bfa9abe4cf | ||
|
|
0e0118eaa6 | ||
|
|
7b6439b200 | ||
|
|
65e3b21d64 | ||
|
|
d90bcc3135 | ||
|
|
eee47ee37c | ||
|
|
d340dd0e0d | ||
|
|
2193a0307e | ||
|
|
58dcd172f9 | ||
|
|
f818396243 | ||
|
|
3d124af58c | ||
|
|
df18d4a15a | ||
|
|
f08a2b6a90 | ||
|
|
fce8df8284 | ||
|
|
6ec99045d7 | ||
|
|
757784b038 | ||
|
|
7e06f23e29 | ||
|
|
26a43b1753 | ||
|
|
c8023f0b66 | ||
|
|
25f65c7c02 | ||
|
|
07d39f2b81 | ||
|
|
01e226d0c9 | ||
|
|
c98e10adf7 | ||
|
|
858b8a6fa8 | ||
|
|
53a66f64ab | ||
|
|
e2b9baed25 | ||
|
|
6bc24755d5 | ||
|
|
e871d655d2 | ||
|
|
1fa0d5da0e | ||
|
|
461e4bef09 | ||
|
|
9b1df03087 | ||
|
|
541a1a0e0a | ||
|
|
ce2f7042da | ||
|
|
ca3438b640 | ||
|
|
5121c3d45b | ||
|
|
666b241a53 | ||
|
|
b961bdf9d3 | ||
|
|
8aa1d58b76 | ||
|
|
570723bb59 | ||
|
|
7027929e30 | ||
|
|
f11f269c2f | ||
|
|
b0cd520b1a | ||
|
|
5c0fd8a6da | ||
|
|
e34d67f01e | ||
|
|
72703d6a56 | ||
|
|
b8c473796a | ||
|
|
25e86c5545 | ||
|
|
f1bf2c589b | ||
|
|
8b54559953 | ||
|
|
3761dbd7b2 | ||
|
|
8cf0343f29 | ||
|
|
f3753a22da | ||
|
|
c90312a925 | ||
|
|
c1d6aa3e49 | ||
|
|
c097370960 | ||
|
|
8ffa3b4746 | ||
|
|
1e6d0f7f62 | ||
|
|
e73c5dfebd | ||
|
|
32309ac007 | ||
|
|
079800aa1a | ||
|
|
06f0d05d19 | ||
|
|
c618a18851 | ||
|
|
1aac521af3 |
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -15,14 +15,14 @@ jobs:
|
|||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-18.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup JDK
|
- name: Setup JDK
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'adopt'
|
distribution: 'temurin'
|
||||||
cache: gradle
|
cache: gradle
|
||||||
- name: Setup Android SDK
|
- name: Setup Android SDK
|
||||||
uses: android-actions/setup-android@v2
|
uses: android-actions/setup-android@v2
|
||||||
|
|||||||
311
CHANGELOG.md
311
CHANGELOG.md
@@ -1,3 +1,314 @@
|
|||||||
|
## [2.111.2](https://github.com/revanced/revanced-patches/compare/v2.111.1...v2.111.2) (2022-11-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/general-ads:** import correct compatibility annotation ([#1065](https://github.com/revanced/revanced-patches/issues/1065)) ([db2085c](https://github.com/revanced/revanced-patches/commit/db2085c217311a8b7d45a01c03c6162bc60a9298))
|
||||||
|
|
||||||
|
## [2.111.1](https://github.com/revanced/revanced-patches/compare/v2.111.0...v2.111.1) (2022-11-18)
|
||||||
|
|
||||||
|
# [2.111.0](https://github.com/revanced/revanced-patches/compare/v2.110.0...v2.111.0) (2022-11-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **iconpackstudio:** `unlock-pro` patch ([#1047](https://github.com/revanced/revanced-patches/issues/1047)) ([fcbca9c](https://github.com/revanced/revanced-patches/commit/fcbca9cf0ff3940c48df53a9e5e4d06d65f9a1b1))
|
||||||
|
|
||||||
|
# [2.110.0](https://github.com/revanced/revanced-patches/compare/v2.109.0...v2.110.0) (2022-11-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/debugging:** include by default & add option to debug on Android ([9d6d5b2](https://github.com/revanced/revanced-patches/commit/9d6d5b29227980aacb4c1331161afb3fa265bbe4))
|
||||||
|
* **youtube/debugging:** use more suitable preference title ([d182351](https://github.com/revanced/revanced-patches/commit/d182351e789bcbfb7982774406449e8d973765b2))
|
||||||
|
* **youtube/general-ads:** hide chapter teaser under videos ([9cf415a](https://github.com/revanced/revanced-patches/commit/9cf415a894ab5458134ef1cd5a4c5bf7579e592c))
|
||||||
|
* **youtube/general-ads:** hide self sponsored cards ([b627d75](https://github.com/revanced/revanced-patches/commit/b627d751b49c228e52f7f9fb5d2bcacb9d243a64))
|
||||||
|
* **youtube/general-ads:** hide shorts in search ([c01ba5c](https://github.com/revanced/revanced-patches/commit/c01ba5cbcc694f8c9ee83a4e9eb081cf5b45753c))
|
||||||
|
|
||||||
|
# [2.109.0](https://github.com/revanced/revanced-patches/compare/v2.108.0...v2.109.0) (2022-11-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **twitch:** `block-audio-ads` patch ([#1041](https://github.com/revanced/revanced-patches/issues/1041)) ([3419bae](https://github.com/revanced/revanced-patches/commit/3419baed489ce231f84b3e2d600cf123cdfa7ff7))
|
||||||
|
* **twitch:** `block-video-ads` patch ([#1040](https://github.com/revanced/revanced-patches/issues/1040)) ([b47bf24](https://github.com/revanced/revanced-patches/commit/b47bf24d1b52cfa1883a942894a6216ae81b8325))
|
||||||
|
|
||||||
|
# [2.108.0](https://github.com/revanced/revanced-patches/compare/v2.107.0...v2.108.0) (2022-11-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **twitch:** `debug-mode` patch ([#1031](https://github.com/revanced/revanced-patches/issues/1031)) ([c514860](https://github.com/revanced/revanced-patches/commit/c514860bc4a46295b11f09df9ffc1c556b798eb3))
|
||||||
|
|
||||||
|
# [2.107.0](https://github.com/revanced/revanced-patches/compare/v2.106.1...v2.107.0) (2022-11-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **ticktick:** `unlock-themes` patch ([#1028](https://github.com/revanced/revanced-patches/issues/1028)) ([7f1fedc](https://github.com/revanced/revanced-patches/commit/7f1fedcddd4330a5f884b813a20f2f8e84e2c9da))
|
||||||
|
* **twitch/show-deleted-messages:** `show-deleted-messages` patch ([#1030](https://github.com/revanced/revanced-patches/issues/1030)) ([7e6b453](https://github.com/revanced/revanced-patches/commit/7e6b4534013a03ddc7eb11a1f911fa0564372118))
|
||||||
|
|
||||||
|
## [2.106.1](https://github.com/revanced/revanced-patches/compare/v2.106.0...v2.106.1) (2022-11-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/custom-branding:** use high resolution icons ([#1018](https://github.com/revanced/revanced-patches/issues/1018)) ([1c9d1ac](https://github.com/revanced/revanced-patches/commit/1c9d1acf2b7aff4cd52d17009ff01246f74d2214))
|
||||||
|
|
||||||
|
# [2.106.0](https://github.com/revanced/revanced-patches/compare/v2.105.0...v2.106.0) (2022-11-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** `open-links-directly` patch ([#999](https://github.com/revanced/revanced-patches/issues/999)) ([bf85f62](https://github.com/revanced/revanced-patches/commit/bf85f62f30242f91bdaf53b44ae6a9a2b3b6e1b4))
|
||||||
|
|
||||||
|
# [2.105.0](https://github.com/revanced/revanced-patches/compare/v2.104.2...v2.105.0) (2022-11-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **nyx:** `unlock-pro` patch ([#1004](https://github.com/revanced/revanced-patches/issues/1004)) ([9dd8239](https://github.com/revanced/revanced-patches/commit/9dd82391f3f97247224e09e0143b2272a3d47053))
|
||||||
|
|
||||||
|
## [2.104.2](https://github.com/revanced/revanced-patches/compare/v2.104.1...v2.104.2) (2022-11-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/hide-endscreen-cards:** restore functionality ([#993](https://github.com/revanced/revanced-patches/issues/993)) ([eb1bae2](https://github.com/revanced/revanced-patches/commit/eb1bae2c55e65ad29030dce6746a18662dd0fe25))
|
||||||
|
|
||||||
|
## [2.104.1](https://github.com/revanced/revanced-patches/compare/v2.104.0...v2.104.1) (2022-11-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/general-ads:** incorrect description for info panels ([77b029e](https://github.com/revanced/revanced-patches/commit/77b029e82e481a13516b1c8a888c42817507cdea))
|
||||||
|
* **youtube/hide-info-cards:** remove initial popup of info-cards ([#992](https://github.com/revanced/revanced-patches/issues/992)) ([19f3f03](https://github.com/revanced/revanced-patches/commit/19f3f038585c313a969adf3d4095a60ab4c83ede))
|
||||||
|
|
||||||
|
# [2.104.0](https://github.com/revanced/revanced-patches/compare/v2.103.0...v2.104.0) (2022-11-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **hexeditor:** `disable-ads` patch ([#973](https://github.com/revanced/revanced-patches/issues/973)) ([a48e5fd](https://github.com/revanced/revanced-patches/commit/a48e5fd50dcf9ee061ffd5c5ed0b997067f40652))
|
||||||
|
|
||||||
|
# [2.103.0](https://github.com/revanced/revanced-patches/compare/v2.102.1...v2.103.0) (2022-11-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* apply multiple changes from integrations, refactor package structure, class names and implementations ([e756fac](https://github.com/revanced/revanced-patches/commit/e756face362e4abf2c7b17afa536feed9b0cd631))
|
||||||
|
* **youtube/video-information:** use correct compatibility annotation ([b42e048](https://github.com/revanced/revanced-patches/commit/b42e04884bb9a60c3df30b668bfba55b1cf8eaa4))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **debugging:** simplify patch name and description ([61762f7](https://github.com/revanced/revanced-patches/commit/61762f76c457f348ef599e146f3853e941d4c45c))
|
||||||
|
|
||||||
|
## [2.102.1](https://github.com/revanced/revanced-patches/compare/v2.102.0...v2.102.1) (2022-11-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* use original app name ([#977](https://github.com/revanced/revanced-patches/issues/977)) ([ffc3c08](https://github.com/revanced/revanced-patches/commit/ffc3c08d96734893121397d506a97bd50b06bc1d))
|
||||||
|
|
||||||
|
# [2.102.0](https://github.com/revanced/revanced-patches/compare/v2.101.0...v2.102.0) (2022-11-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube-music:** bump patches compatibility to v5.31.50 ([#962](https://github.com/revanced/revanced-patches/issues/962)) ([476fcc8](https://github.com/revanced/revanced-patches/commit/476fcc87ca0d33cfbf251e4307755f02ed8f8baa))
|
||||||
|
|
||||||
|
# [2.101.0](https://github.com/revanced/revanced-patches/compare/v2.100.3...v2.101.0) (2022-11-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** bump patches compatibility to v17.43.36 ([#924](https://github.com/revanced/revanced-patches/issues/924)) ([3867514](https://github.com/revanced/revanced-patches/commit/38675144dcb616474a047bcf8f7e1bf1f668ea46))
|
||||||
|
|
||||||
|
## [2.100.3](https://github.com/revanced/revanced-patches/compare/v2.100.2...v2.100.3) (2022-11-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/video-ads:** add switch to temporarily fix buffering issues ([7aa3bce](https://github.com/revanced/revanced-patches/commit/7aa3bce6ccd669a66de10ef6ffe2151f27b40365))
|
||||||
|
|
||||||
|
## [2.100.2](https://github.com/revanced/revanced-patches/compare/v2.100.1...v2.100.2) (2022-10-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/theme-patch:** respect app specific theme ([#946](https://github.com/revanced/revanced-patches/issues/946)) ([fe8d6c7](https://github.com/revanced/revanced-patches/commit/fe8d6c7b2c10be5cca0717b6a03cfa1bef10e2c0))
|
||||||
|
|
||||||
|
## [2.100.1](https://github.com/revanced/revanced-patches/compare/v2.100.0...v2.100.1) (2022-10-31)
|
||||||
|
|
||||||
|
# [2.100.0](https://github.com/revanced/revanced-patches/compare/v2.99.0...v2.100.0) (2022-10-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `hide-watch-in-vr` patch ([#911](https://github.com/revanced/revanced-patches/issues/911)) ([8ea0b20](https://github.com/revanced/revanced-patches/commit/8ea0b20e96df53211039df0468b2d4a735a381f1))
|
||||||
|
|
||||||
|
# [2.99.0](https://github.com/revanced/revanced-patches/compare/v2.98.0...v2.99.0) (2022-10-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/sponsorblock:** skip segments once automatically ([#907](https://github.com/revanced/revanced-patches/issues/907)) ([afc7588](https://github.com/revanced/revanced-patches/commit/afc75882062a9316dbc28a9dc4f990cf88b52654))
|
||||||
|
|
||||||
|
# [2.98.0](https://github.com/revanced/revanced-patches/compare/v2.97.0...v2.98.0) (2022-10-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/comments:** hide shorts comments button ([#866](https://github.com/revanced/revanced-patches/issues/866)) ([c78a74e](https://github.com/revanced/revanced-patches/commit/c78a74e21b4521034f44e9bfd226c5a362c21e6c))
|
||||||
|
|
||||||
|
# [2.97.0](https://github.com/revanced/revanced-patches/compare/v2.96.0...v2.97.0) (2022-10-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/microg-support:** handle availability of Vanced MicroG ([bfd0d14](https://github.com/revanced/revanced-patches/commit/bfd0d1418fb68f1d37687ec2072d3b64a9c3c6ee))
|
||||||
|
|
||||||
|
# [2.96.0](https://github.com/revanced/revanced-patches/compare/v2.95.0...v2.96.0) (2022-10-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/return-youtube-dislike:** compatibility for old and new button layout ([6629bd7](https://github.com/revanced/revanced-patches/commit/6629bd71716a753be06617724e536b8ab4c3b69a))
|
||||||
|
|
||||||
|
# [2.95.0](https://github.com/revanced/revanced-patches/compare/v2.94.0...v2.95.0) (2022-10-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** bump patches compatibility to v17.41.37 ([#888](https://github.com/revanced/revanced-patches/issues/888)) ([11ed0c0](https://github.com/revanced/revanced-patches/commit/11ed0c0fb3236d87284806d2fa957699e908cc61))
|
||||||
|
|
||||||
|
# [2.94.0](https://github.com/revanced/revanced-patches/compare/v2.93.0...v2.94.0) (2022-10-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* remove compatibility for YouTube v17.41.37 ([#886](https://github.com/revanced/revanced-patches/issues/886)) ([0f4bc19](https://github.com/revanced/revanced-patches/commit/0f4bc197455574b84dd1cb1a43f03af90858bc39))
|
||||||
|
|
||||||
|
# [2.93.0](https://github.com/revanced/revanced-patches/compare/v2.92.3...v2.93.0) (2022-10-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* bump YouTube patches to v17.41.37 ([#878](https://github.com/revanced/revanced-patches/issues/878)) ([9072986](https://github.com/revanced/revanced-patches/commit/9072986f99e624386ff51c7eeb1d65158bd9249a))
|
||||||
|
|
||||||
|
## [2.92.3](https://github.com/revanced/revanced-patches/compare/v2.92.2...v2.92.3) (2022-10-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube:** resolve fingerprints on mutable methods ([10e4af3](https://github.com/revanced/revanced-patches/commit/10e4af386652d51c621519f7a67aac8c22ed8c18))
|
||||||
|
|
||||||
|
## [2.92.2](https://github.com/revanced/revanced-patches/compare/v2.92.1...v2.92.2) (2022-10-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/theme:** theme missing gray color ([#873](https://github.com/revanced/revanced-patches/issues/873)) ([5267d56](https://github.com/revanced/revanced-patches/commit/5267d56a05b4053d556171ffd2d2870f3f932e8e))
|
||||||
|
|
||||||
|
## [2.92.1](https://github.com/revanced/revanced-patches/compare/v2.92.0...v2.92.1) (2022-10-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/custom-branding:** use proper scaled icons ([24b5bcd](https://github.com/revanced/revanced-patches/commit/24b5bcdd703474c940fd436a37f0ae924d8b8c74))
|
||||||
|
|
||||||
|
# [2.92.0](https://github.com/revanced/revanced-patches/compare/v2.91.0...v2.92.0) (2022-10-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/hide-mix-playlists:** hide in video suggestions ([#854](https://github.com/revanced/revanced-patches/issues/854)) ([acde5f0](https://github.com/revanced/revanced-patches/commit/acde5f066053ca3d58ca09fc2a6a1381ba27d84b))
|
||||||
|
|
||||||
|
# [2.91.0](https://github.com/revanced/revanced-patches/compare/v2.90.0...v2.91.0) (2022-10-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* remove partially complete patch ([d212e19](https://github.com/revanced/revanced-patches/commit/d212e19c3276c2ba6550f03dfd9bba47b7773524))
|
||||||
|
|
||||||
|
# [2.90.0](https://github.com/revanced/revanced-patches/compare/v2.89.0...v2.90.0) (2022-10-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `comment` patch ([#858](https://github.com/revanced/revanced-patches/issues/858)) ([472fb4f](https://github.com/revanced/revanced-patches/commit/472fb4f3747c835be2c5069a0f65017ab42f8d7e))
|
||||||
|
|
||||||
|
# [2.89.0](https://github.com/revanced/revanced-patches/compare/v2.88.0...v2.89.0) (2022-10-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `hide-album-cards` patch ([#857](https://github.com/revanced/revanced-patches/issues/857)) ([bce9d0c](https://github.com/revanced/revanced-patches/commit/bce9d0c9405d7afd5c51c2a9c2c247f3ff7581f5))
|
||||||
|
|
||||||
|
# [2.88.0](https://github.com/revanced/revanced-patches/compare/v2.87.0...v2.88.0) (2022-10-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `hide-artist-card` patch ([#859](https://github.com/revanced/revanced-patches/issues/859)) ([1f76246](https://github.com/revanced/revanced-patches/commit/1f7624680b86e3a7afd45521bfef86f88f52c976))
|
||||||
|
|
||||||
|
# [2.87.0](https://github.com/revanced/revanced-patches/compare/v2.86.0...v2.87.0) (2022-10-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **metanav/fix-scaling:** use semantic versioning in package versions ([a9445a8](https://github.com/revanced/revanced-patches/commit/a9445a823e3a4885764cea9d08b51a1584d3238f))
|
||||||
|
* **youtube/theme:** theme litho ui components & use correct theme for settings ([#791](https://github.com/revanced/revanced-patches/issues/791)) ([91c03c5](https://github.com/revanced/revanced-patches/commit/91c03c5624ca28ac13ee761261dea423f0ac42d7))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `fix-metanav-scaling` patch ([#831](https://github.com/revanced/revanced-patches/issues/831)) ([4808e09](https://github.com/revanced/revanced-patches/commit/4808e099856e50a6f7e66834a92e2210cc84c8bc))
|
||||||
|
* `hide-crowdfunding-box` patch ([#856](https://github.com/revanced/revanced-patches/issues/856)) ([3704ce2](https://github.com/revanced/revanced-patches/commit/3704ce22dbbff02b2e2d6dbdf9a74254a2511d3c))
|
||||||
|
|
||||||
|
# [2.86.0](https://github.com/revanced/revanced-patches/compare/v2.85.2...v2.86.0) (2022-10-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube/theme:** extend theming to splash screen ([#769](https://github.com/revanced/revanced-patches/issues/769)) ([f7bb937](https://github.com/revanced/revanced-patches/commit/f7bb937ef2374d1042ea3772f03627d7f0111b78))
|
||||||
|
|
||||||
|
## [2.85.2](https://github.com/revanced/revanced-patches/compare/v2.85.1...v2.85.2) (2022-10-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/integrations:** set context for remaining activities ([#828](https://github.com/revanced/revanced-patches/issues/828)) ([b2b6a3d](https://github.com/revanced/revanced-patches/commit/b2b6a3d1492bc2d5a6e27c68c74e3904764dda4b))
|
||||||
|
|
||||||
|
## [2.85.1](https://github.com/revanced/revanced-patches/compare/v2.85.0...v2.85.1) (2022-10-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/theme:** extend dark mode theming ([#827](https://github.com/revanced/revanced-patches/issues/827)) ([6d803c5](https://github.com/revanced/revanced-patches/commit/6d803c5386e1f6f6fb6a7fa0a9f0bb81ee1022ac))
|
||||||
|
|
||||||
|
# [2.85.0](https://github.com/revanced/revanced-patches/compare/v2.84.1...v2.85.0) (2022-10-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** `hide-captions-button` patch ([#770](https://github.com/revanced/revanced-patches/issues/770)) ([478af6a](https://github.com/revanced/revanced-patches/commit/478af6ad54ffdf6f99abab35a84a4f50b59d28c8))
|
||||||
|
|
||||||
|
## [2.84.1](https://github.com/revanced/revanced-patches/compare/v2.84.0...v2.84.1) (2022-10-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **youtube/hide-mix-playlists:** correct switch title, summary and defaults ([#821](https://github.com/revanced/revanced-patches/issues/821)) ([f9eea33](https://github.com/revanced/revanced-patches/commit/f9eea332cea0b8c3d5c3dfff645b60861e925b5a))
|
||||||
|
|
||||||
|
# [2.84.0](https://github.com/revanced/revanced-patches/compare/v2.83.3...v2.84.0) (2022-10-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **youtube:** `hide-mix-playlists` patch ([#816](https://github.com/revanced/revanced-patches/issues/816)) ([e76c73b](https://github.com/revanced/revanced-patches/commit/e76c73b455c65aa605e418f19d88b64e0e244901))
|
||||||
|
|
||||||
## [2.83.3](https://github.com/revanced/revanced-patches/compare/v2.83.2...v2.83.3) (2022-10-20)
|
## [2.83.3](https://github.com/revanced/revanced-patches/compare/v2.83.2...v2.83.3) (2022-10-20)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
132
README.md
132
README.md
@@ -4,6 +4,14 @@ The official Patch bundle provided by ReVanced and the community.
|
|||||||
|
|
||||||
> Looking for the JSON variant of this? [Click here](patches.json).
|
> Looking for the JSON variant of this? [Click here](patches.json).
|
||||||
|
|
||||||
|
### 📦 `ginlemon.iconpackstudio`
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|
|:--------:|:--------------:|:-----------------:|
|
||||||
|
| `unlock-pro` | Unlocks all pro features. | all |
|
||||||
|
</details>
|
||||||
|
|
||||||
### 📦 `com.ss.android.ugc.trill`
|
### 📦 `com.ss.android.ugc.trill`
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@@ -50,6 +58,14 @@ The official Patch bundle provided by ReVanced and the community.
|
|||||||
| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all |
|
| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all |
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### 📦 `com.myprog.hexedit`
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|
|:--------:|:--------------:|:-----------------:|
|
||||||
|
| `disable-ads` | Disables ads in HexEditor. | all |
|
||||||
|
</details>
|
||||||
|
|
||||||
### 📦 `com.spotify.music`
|
### 📦 `com.spotify.music`
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@@ -65,42 +81,51 @@ The official Patch bundle provided by ReVanced and the community.
|
|||||||
|
|
||||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|:--------:|:--------------:|:-----------------:|
|
|:--------:|:--------------:|:-----------------:|
|
||||||
| `hide-time-and-seekbar` | Hides progress bar and time counter on videos. | 17.36.37 |
|
| `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 17.43.36 |
|
||||||
| `hide-video-buttons` | Adds options to hide action buttons under a video. | 17.36.37 |
|
| `hide-time-and-seekbar` | Hides progress bar and time counter on videos. | 17.43.36 |
|
||||||
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.36.37 |
|
| `hide-video-buttons` | Adds options to hide action buttons under a video. | 17.43.36 |
|
||||||
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.36.37 |
|
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.43.36 |
|
||||||
| `hide-create-button` | Hides the create button in the navigation bar. | 17.36.37 |
|
| `hide-captions-button` | Hides the captions button on video player. | 17.43.36 |
|
||||||
| `disable-startup-shorts-player` | Disables playing YouTube Shorts when launching YouTube. | 17.36.37 |
|
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.43.36 |
|
||||||
|
| `hide-create-button` | Hides the create button in the navigation bar. | 17.43.36 |
|
||||||
|
| `disable-startup-shorts-player` | Disables playing YouTube Shorts when launching YouTube. | 17.43.36 |
|
||||||
|
| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 17.43.36 |
|
||||||
| `hide-cast-button` | Hides the cast button in the video player. | all |
|
| `hide-cast-button` | Hides the cast button in the video player. | all |
|
||||||
| `sponsorblock` | Integrate SponsorBlock. | 17.36.37 |
|
| `sponsorblock` | Integrate SponsorBlock. | 17.43.36 |
|
||||||
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.36.37 |
|
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.43.36 |
|
||||||
| `disable-auto-player-popup-panels` | Disable automatic popup panels (playlist or live chat) on video player. | 17.36.37 |
|
| `hide-watch-in-vr` | Hides the Watch in VR option from the player settings flyout panel. | 17.43.36 |
|
||||||
| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 17.36.37 |
|
| `hide-album-cards` | Hides the album cards below the artist description. | 17.43.36 |
|
||||||
| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 17.36.37 |
|
| `disable-auto-player-popup-panels` | Disable automatic popup panels (playlist or live chat) on video player. | 17.43.36 |
|
||||||
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 17.36.37 |
|
| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 17.43.36 |
|
||||||
|
| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 17.43.36 |
|
||||||
|
| `hide-artist-card` | Hides the artist card below the searchbar. | 17.43.36 |
|
||||||
|
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 17.43.36 |
|
||||||
|
| `comments` | Hides components related to comments. | 17.43.36 |
|
||||||
| `theme` | Applies a custom theme. | all |
|
| `theme` | Applies a custom theme. | all |
|
||||||
| `hide-email-address` | Hides the email address in the account switcher. | 17.36.37 |
|
| `hide-email-address` | Hides the email address in the account switcher. | 17.43.36 |
|
||||||
| `tablet-mini-player` | Enables the tablet mini player layout. | 17.36.37 |
|
| `tablet-mini-player` | Enables the tablet mini player layout. | 17.43.36 |
|
||||||
| `hide-watermark` | Hides creator's watermarks on videos. | 17.36.37 |
|
| `hide-watermark` | Hides creator's watermarks on videos. | 17.43.36 |
|
||||||
|
| `hide-info-cards` | Hides info-cards in videos. | 17.43.36 |
|
||||||
|
| `hide-my-mix` | Hides mix playlists. | 17.43.36 |
|
||||||
| `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 |
|
||||||
| `premium-heading` | Shows premium branding on the home screen. | all |
|
| `premium-heading` | Shows premium branding on the home screen. | all |
|
||||||
| `old-quality-layout` | Enables the original quality flyout menu. | 17.36.37 |
|
| `old-quality-layout` | Enables the original quality flyout menu. | 17.43.36 |
|
||||||
| `general-ads` | Removes general ads. | 17.36.37 |
|
| `general-ads` | Removes general ads. | 17.43.36 |
|
||||||
| `video-ads` | Removes ads in the video player. | 17.36.37 |
|
| `video-ads` | Removes ads in the video player. | 17.43.36 |
|
||||||
| `hide-infocard-suggestions` | Hides infocards in videos. | 17.36.37 |
|
| `swipe-controls` | Adds volume and brightness swipe controls. | 17.43.36 |
|
||||||
| `swipe-controls` | Adds volume and brightness swipe controls. | 17.36.37 |
|
| `downloads` | Enables downloading music and videos from YouTube. | 17.43.36 |
|
||||||
| `downloads` | Enables downloading music and videos from YouTube. | 17.36.37 |
|
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.43.36 |
|
||||||
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.36.37 |
|
|
||||||
| `settings` | Adds settings for ReVanced to YouTube. | all |
|
| `settings` | Adds settings for ReVanced to YouTube. | all |
|
||||||
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 17.36.37 |
|
| `open-links-directly` | Bypasses redirect links and allows opening links directly. | 17.43.36 |
|
||||||
| `custom-video-buffer` | Lets you change the buffers of videos. | 17.36.37 |
|
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 17.43.36 |
|
||||||
|
| `custom-video-buffer` | Lets you change the buffers of videos. | 17.43.36 |
|
||||||
|
| `debugging` | Adds debugging options. | all |
|
||||||
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
|
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
|
||||||
| `always-autorepeat` | Always repeats the playing video again. | 17.36.37 |
|
| `always-autorepeat` | Always repeats the playing video again. | 17.43.36 |
|
||||||
| `enable-debugging` | Enables app debugging by patching the manifest file. | all |
|
| `minimized-playback` | Enables minimized and background playback. | 17.43.36 |
|
||||||
| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.36.37 |
|
| `custom-video-speed` | Adds more video speed options. | 17.43.36 |
|
||||||
| `minimized-playback` | Enables minimized and background playback. | 17.36.37 |
|
| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.43.36 |
|
||||||
| `custom-playback-speed` | Adds more video playback speed options. | 17.36.37 |
|
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 17.43.36 |
|
||||||
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 17.36.37 |
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### 📦 `com.vanced.android.youtube`
|
### 📦 `com.vanced.android.youtube`
|
||||||
@@ -111,6 +136,25 @@ The official Patch bundle provided by ReVanced and the community.
|
|||||||
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
|
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### 📦 `com.ticktick.task`
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|
|:--------:|:--------------:|:-----------------:|
|
||||||
|
| `unlock-themes` | Unlocks all themes. | all |
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### 📦 `tv.twitch.android.app`
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|
|:--------:|:--------------:|:-----------------:|
|
||||||
|
| `debug-mode` | Enables Twitch's internal debugging mode. | all |
|
||||||
|
| `block-audio-ads` | Blocks audio ads in streams and VODs. | all |
|
||||||
|
| `block-video-ads` | Blocks video ads in streams and VODs. | all |
|
||||||
|
| `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | all |
|
||||||
|
</details>
|
||||||
|
|
||||||
### 📦 `com.garzotto.pflotsh.ecmwf_a`
|
### 📦 `com.garzotto.pflotsh.ecmwf_a`
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
@@ -124,16 +168,16 @@ The official Patch bundle provided by ReVanced and the community.
|
|||||||
|
|
||||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|:--------:|:--------------:|:-----------------:|
|
|:--------:|:--------------:|:-----------------:|
|
||||||
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | 5.29.52 |
|
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | 5.31.50 |
|
||||||
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.29.52 |
|
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.31.50 |
|
||||||
| `minimized-playback-music` | Enables minimized playback on Kids music. | 5.29.52 |
|
| `minimized-playback-music` | Enables minimized playback on Kids music. | 5.31.50 |
|
||||||
| `compact-header` | Hides the music category bar at the top of the homepage. | 5.29.52 |
|
| `compact-header` | Hides the music category bar at the top of the homepage. | 5.31.50 |
|
||||||
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.29.52 |
|
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.31.50 |
|
||||||
| `music-video-ads` | Removes ads in the music player. | 5.29.52 |
|
| `music-video-ads` | Removes ads in the music player. | 5.31.50 |
|
||||||
| `background-play` | Enables playing music in the background. | 5.29.52 |
|
| `background-play` | Enables playing music in the background. | 5.31.50 |
|
||||||
| `exclusive-audio-playback` | Enables the option to play music without video. | 5.29.52 |
|
| `exclusive-audio-playback` | Enables the option to play music without video. | 5.31.50 |
|
||||||
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.29.52 |
|
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.31.50 |
|
||||||
| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.29.52 |
|
| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.31.50 |
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### 📦 `com.reddit.frontpage`
|
### 📦 `com.reddit.frontpage`
|
||||||
@@ -145,6 +189,14 @@ The official Patch bundle provided by ReVanced and the community.
|
|||||||
| `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.awedea.nyx`
|
||||||
|
<details>
|
||||||
|
|
||||||
|
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||||
|
|:--------:|:--------------:|:-----------------:|
|
||||||
|
| `unlock-pro` | Unlocks all pro features. | all |
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 📝 JSON Format
|
## 📝 JSON Format
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("app.revanced:revanced-patcher:6.0.0")
|
implementation("app.revanced:revanced-patcher:6.0.2")
|
||||||
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
||||||
// Required for meta
|
// Required for meta
|
||||||
implementation("com.google.code.gson:gson:2.9.1")
|
implementation("com.google.code.gson:gson:2.9.1")
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 2.83.3
|
version = 2.111.2
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -18,17 +18,6 @@ import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
|||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
// TODO: this method does not make sense here
|
|
||||||
internal fun MutableMethodImplementation.injectHideCall(
|
|
||||||
index: Int,
|
|
||||||
register: Int
|
|
||||||
) {
|
|
||||||
this.addInstruction(
|
|
||||||
index,
|
|
||||||
"invoke-static { v$register }, Lapp/revanced/integrations/patches/HideHomeAdsPatch;->HideHomeAds(Landroid/view/View;)V".toInstruction()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* traverse the class hierarchy starting from the given root class
|
* traverse the class hierarchy starting from the given root class
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.hexeditor.ad.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[
|
||||||
|
Package("com.myprog.hexedit")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class HexEditorAdsCompatibility
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package app.revanced.patches.hexeditor.ad.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility
|
||||||
|
|
||||||
|
@Name("ads-fingerprint-primary")
|
||||||
|
@HexEditorAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object PrimaryAdsFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("PreferencesHelper;") && methodDef.name == "isAdsDisabled"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package app.revanced.patches.hexeditor.ad.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.removeInstruction
|
||||||
|
import app.revanced.patcher.extensions.replaceInstructions
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility
|
||||||
|
import app.revanced.patches.hexeditor.ad.fingerprints.PrimaryAdsFingerprint
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("disable-ads")
|
||||||
|
@Description("Disables ads in HexEditor.")
|
||||||
|
@HexEditorAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HexEditorAdsPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
PrimaryAdsFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
val method = PrimaryAdsFingerprint.result!!.mutableMethod
|
||||||
|
|
||||||
|
method.replaceInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x1
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package app.revanced.patches.iconpackstudio.misc.pro.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("ginlemon.iconpackstudio")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class UnlockProCompatibility
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package app.revanced.patches.iconpackstudio.misc.pro.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.iconpackstudio.misc.pro.annotations.UnlockProCompatibility
|
||||||
|
|
||||||
|
@Name("check-pro-fingerprint")
|
||||||
|
@UnlockProCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object CheckProFingerprint : MethodFingerprint(
|
||||||
|
"Z",
|
||||||
|
customFingerprint = { it.definingClass.endsWith("IPSPurchaseRepository;")}
|
||||||
|
)
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package app.revanced.patches.iconpackstudio.misc.pro.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.removeInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.iconpackstudio.misc.pro.annotations.UnlockProCompatibility
|
||||||
|
import app.revanced.patches.iconpackstudio.misc.pro.fingerprints.CheckProFingerprint
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("unlock-pro")
|
||||||
|
@Description("Unlocks all pro features.")
|
||||||
|
@UnlockProCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class UnlockProPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
CheckProFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
val method = CheckProFingerprint.result!!.mutableMethod
|
||||||
|
method.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x1
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
*/
|
*/
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.apps.youtube.music", arrayOf("5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package app.revanced.patches.music.misc.microg.shared
|
package app.revanced.patches.music.misc.microg.shared
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
internal const val REVANCED_MUSIC_APP_NAME = "YouTube Music ReVanced"
|
internal const val REVANCED_MUSIC_APP_NAME = "YT Music ReVanced"
|
||||||
internal const val REVANCED_MUSIC_PACKAGE_NAME = "app.revanced.android.apps.youtube.music"
|
internal const val REVANCED_MUSIC_PACKAGE_NAME = "app.revanced.android.apps.youtube.music"
|
||||||
internal const val MUSIC_PACKAGE_NAME = "com.google.android.apps.youtube.music"
|
internal const val MUSIC_PACKAGE_NAME = "com.google.android.apps.youtube.music"
|
||||||
internal const val SPOOFED_PACKAGE_NAME = MUSIC_PACKAGE_NAME
|
internal const val SPOOFED_PACKAGE_NAME = MUSIC_PACKAGE_NAME
|
||||||
internal const val SPOOFED_PACKAGE_SIGNATURE = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875"
|
internal const val SPOOFED_PACKAGE_SIGNATURE = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package app.revanced.patches.nyx.misc.pro.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("com.awedea.nyx")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class UnlockProCompatibility
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package app.revanced.patches.nyx.misc.pro.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.nyx.misc.pro.annotations.UnlockProCompatibility
|
||||||
|
|
||||||
|
@Name("check-pro-fingerprint")
|
||||||
|
@UnlockProCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object CheckProFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("BillingManager;") && methodDef.name == "isProVersion"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package app.revanced.patches.nyx.misc.pro.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.removeInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.nyx.misc.pro.annotations.UnlockProCompatibility
|
||||||
|
import app.revanced.patches.nyx.misc.pro.fingerprints.CheckProFingerprint
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("unlock-pro")
|
||||||
|
@Description("Unlocks all pro features.")
|
||||||
|
@UnlockProCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class UnlockProPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
CheckProFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
val method = CheckProFingerprint.result!!.mutableMethod
|
||||||
|
method.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x1
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package app.revanced.patches.ticktick.misc.themeunlock.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("com.ticktick.task")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class UnlockThemesCompatibility
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package app.revanced.patches.ticktick.misc.themeunlock.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
|
||||||
|
|
||||||
|
@Name("check-locked-theme-fingerprint")
|
||||||
|
@UnlockThemesCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object CheckLockedThemesFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("Theme;") && methodDef.name == "isLockedTheme"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package app.revanced.patches.ticktick.misc.themeunlock.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
|
||||||
|
|
||||||
|
@Name("set-theme-fingerprint")
|
||||||
|
@UnlockThemesCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object SetThemeFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("ThemePreviewActivity;") && methodDef.name == "lambda\$updateUserBtn\$1"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package app.revanced.patches.ticktick.misc.themeunlock.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.removeInstructions
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
|
||||||
|
import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.CheckLockedThemesFingerprint
|
||||||
|
import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.SetThemeFingerprint
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("unlock-themes")
|
||||||
|
@Description("Unlocks all themes.")
|
||||||
|
@UnlockThemesCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class UnlockProPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
CheckLockedThemesFingerprint,
|
||||||
|
SetThemeFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
val lockedThemesMethod = CheckLockedThemesFingerprint.result!!.mutableMethod
|
||||||
|
lockedThemesMethod.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x0
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
val setThemeMethod = SetThemeFingerprint.result!!.mutableMethod
|
||||||
|
setThemeMethod.removeInstructions(0, 9)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.audio.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("tv.twitch.android.app")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class AudioAdsCompatibility
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.audio.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.ad.audio.annotations.AudioAdsCompatibility
|
||||||
|
|
||||||
|
@Name("audio-ads-presenter-play-fingerprint")
|
||||||
|
@AudioAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object AudioAdsPresenterPlayFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { method ->
|
||||||
|
method.definingClass.endsWith("AudioAdsPlayerPresenter;") && method.name == "playAd"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.audio.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.twitch.ad.audio.annotations.AudioAdsCompatibility
|
||||||
|
import app.revanced.patches.twitch.ad.audio.fingerprints.AudioAdsPresenterPlayFingerprint
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("block-audio-ads")
|
||||||
|
@Description("Blocks audio ads in streams and VODs.")
|
||||||
|
@AudioAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class AudioAdsPatch : BytecodePatch(
|
||||||
|
listOf(AudioAdsPresenterPlayFingerprint)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
// Block playAds call
|
||||||
|
with(AudioAdsPresenterPlayFingerprint.result!!) {
|
||||||
|
mutableMethod.addInstruction(0, "return-void")
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.video.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("tv.twitch.android.app")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class VideoAdsCompatibility
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.video.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||||
|
|
||||||
|
@Name("ads-manager-play-fingerprint")
|
||||||
|
@VideoAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object AdsManagerFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { method ->
|
||||||
|
method.definingClass.endsWith("AdsManagerImpl;") && method.name == "playAds"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.video.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("check-ad-eligibility-fingerprint")
|
||||||
|
@VideoAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object CheckAdEligibilityLambdaFingerprint : MethodFingerprint(
|
||||||
|
"L",
|
||||||
|
AccessFlags.PRIVATE or AccessFlags.FINAL or AccessFlags.STATIC,
|
||||||
|
listOf("L", "L", "L"),
|
||||||
|
customFingerprint = { method ->
|
||||||
|
method.definingClass.endsWith("AdEligibilityFetcher;") &&
|
||||||
|
method.name.contains("shouldRequestAd")
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.video.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||||
|
|
||||||
|
@Name("content-config-show-ads-fingerprint")
|
||||||
|
@VideoAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object ContentConfigShowAdsFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { method ->
|
||||||
|
method.definingClass.endsWith("ContentConfigData;") && method.name == "getShowAds"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package app.revanced.patches.twitch.ad.video.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||||
|
import app.revanced.patches.twitch.ad.video.fingerprints.AdsManagerFingerprint
|
||||||
|
import app.revanced.patches.twitch.ad.video.fingerprints.CheckAdEligibilityLambdaFingerprint
|
||||||
|
import app.revanced.patches.twitch.ad.video.fingerprints.ContentConfigShowAdsFingerprint
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("block-video-ads")
|
||||||
|
@Description("Blocks video ads in streams and VODs.")
|
||||||
|
@VideoAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class VideoAdsPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
ContentConfigShowAdsFingerprint,
|
||||||
|
AdsManagerFingerprint,
|
||||||
|
CheckAdEligibilityLambdaFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
// Pretend our player is ineligible for all ads
|
||||||
|
with(CheckAdEligibilityLambdaFingerprint.result!!) {
|
||||||
|
mutableMethod.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0
|
||||||
|
invoke-static {v0}, Lio/reactivex/Single;->just(Ljava/lang/Object;)Lio/reactivex/Single;
|
||||||
|
move-result-object p0
|
||||||
|
return-object p0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spoof showAds JSON field
|
||||||
|
with(ContentConfigShowAdsFingerprint.result!!) {
|
||||||
|
mutableMethod.addInstructions(0, """
|
||||||
|
const/4 v0, 0
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block playAds call
|
||||||
|
with(AdsManagerFingerprint.result!!) {
|
||||||
|
mutableMethod.addInstruction(0, "return-void")
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package app.revanced.patches.twitch.chat.antidelete.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("tv.twitch.android.app")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class ShowDeletedMessagesCompatibility
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package app.revanced.patches.twitch.chat.antidelete.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("deleted-msg-span-ctor-fingerprint")
|
||||||
|
@ShowDeletedMessagesCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object DeletedMessageClickableSpanCtorFingerprint : MethodFingerprint(
|
||||||
|
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("DeletedMessageClickableSpan;")
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.twitch.chat.antidelete.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
||||||
|
|
||||||
|
@Name("has-mod-access-fingerprint")
|
||||||
|
@ShowDeletedMessagesCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object SetHasModAccessFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("DeletedMessageClickableSpan;") && methodDef.name == "setHasModAccess"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package app.revanced.patches.twitch.chat.antidelete.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.*
|
||||||
|
import app.revanced.patcher.patch.*
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
||||||
|
import app.revanced.patches.twitch.chat.antidelete.fingerprints.*
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction10x
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("show-deleted-messages")
|
||||||
|
@Description("Shows deleted chat messages behind a clickable spoiler.")
|
||||||
|
@ShowDeletedMessagesCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class ShowDeletedMessagesPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
SetHasModAccessFingerprint,
|
||||||
|
DeletedMessageClickableSpanCtorFingerprint,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
// Force set hasModAccess member to true in constructor
|
||||||
|
with(DeletedMessageClickableSpanCtorFingerprint.result!!.mutableMethod) {
|
||||||
|
addInstructions(
|
||||||
|
implementation!!.instructions.lastIndex, /* place in front of return-void */
|
||||||
|
"""
|
||||||
|
const/4 v0, 1
|
||||||
|
iput-boolean v0, p0, $definingClass->hasModAccess:Z
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable setHasModAccess setter
|
||||||
|
with(SetHasModAccessFingerprint.result!!.mutableMethod.implementation!!) {
|
||||||
|
addInstruction(0, BuilderInstruction10x(Opcode.RETURN_VOID))
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package app.revanced.patches.twitch.debug.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility([Package("tv.twitch.android.app")])
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class DebugModeCompatibility
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.twitch.debug.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||||
|
|
||||||
|
@Name("is-debug-config-enabled-fingerprint")
|
||||||
|
@DebugModeCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object IsDebugConfigEnabledFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "isDebugConfigEnabled"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.twitch.debug.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||||
|
|
||||||
|
@Name("is-om-verification-enabled-fingerprint")
|
||||||
|
@DebugModeCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object IsOmVerificationEnabledFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "isOmVerificationEnabled"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.twitch.debug.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||||
|
|
||||||
|
@Name("should-show-debug-options-fingerprint")
|
||||||
|
@DebugModeCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object ShouldShowDebugOptionsFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "shouldShowDebugOptions"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package app.revanced.patches.twitch.debug.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||||
|
import app.revanced.patches.twitch.debug.fingerprints.IsDebugConfigEnabledFingerprint
|
||||||
|
import app.revanced.patches.twitch.debug.fingerprints.IsOmVerificationEnabledFingerprint
|
||||||
|
import app.revanced.patches.twitch.debug.fingerprints.ShouldShowDebugOptionsFingerprint
|
||||||
|
|
||||||
|
@Patch(false)
|
||||||
|
@Name("debug-mode")
|
||||||
|
@Description("Enables Twitch's internal debugging mode.")
|
||||||
|
@DebugModeCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class DebugModePatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
IsDebugConfigEnabledFingerprint,
|
||||||
|
IsOmVerificationEnabledFingerprint,
|
||||||
|
ShouldShowDebugOptionsFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
listOf(
|
||||||
|
IsDebugConfigEnabledFingerprint,
|
||||||
|
IsOmVerificationEnabledFingerprint,
|
||||||
|
ShouldShowDebugOptionsFingerprint
|
||||||
|
).forEach {
|
||||||
|
with(it.result!!) {
|
||||||
|
with(mutableMethod) {
|
||||||
|
addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x1
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.general.bytecode.extensions
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.softCompareTo
|
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
|
|
||||||
import org.jf.dexlib2.iface.Method
|
|
||||||
import org.jf.dexlib2.iface.instruction.Instruction
|
|
||||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
|
||||||
import org.jf.dexlib2.iface.reference.FieldReference
|
|
||||||
import org.jf.dexlib2.iface.reference.MethodReference
|
|
||||||
import org.jf.dexlib2.iface.reference.Reference
|
|
||||||
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
|
||||||
|
|
||||||
internal object MethodExtensions {
|
|
||||||
internal fun MutableClass.findMutableMethodOf(
|
|
||||||
method: Method
|
|
||||||
) = this.methods.first {
|
|
||||||
it.softCompareTo(
|
|
||||||
ImmutableMethodReference(
|
|
||||||
method.definingClass, method.name, method.parameters, method.returnType
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inline fun <reified T : Reference> Instruction.toDescriptor(): String {
|
|
||||||
val reference = (this as ReferenceInstruction).reference
|
|
||||||
return when (T::class) {
|
|
||||||
MethodReference::class -> {
|
|
||||||
val methodReference = reference as MethodReference
|
|
||||||
"${methodReference.definingClass}->${methodReference.name}(${
|
|
||||||
methodReference.parameterTypes.joinToString(
|
|
||||||
""
|
|
||||||
) { it }
|
|
||||||
})${methodReference.returnType}"
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldReference::class -> {
|
|
||||||
val fieldReference = reference as FieldReference
|
|
||||||
"${fieldReference.definingClass}->${fieldReference.name}:${fieldReference.type}"
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> throw PatchResultError("Unsupported reference type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,390 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.general.bytecode.patch
|
|
||||||
|
|
||||||
import app.revanced.extensions.injectHideCall
|
|
||||||
import app.revanced.patcher.annotation.Description
|
|
||||||
import app.revanced.patcher.annotation.Name
|
|
||||||
import app.revanced.patcher.annotation.Version
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
|
||||||
import app.revanced.patcher.extensions.instruction
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
|
||||||
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
|
||||||
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.findMutableMethodOf
|
|
||||||
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.toDescriptor
|
|
||||||
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralResourceAdsPatch
|
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
|
||||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
|
||||||
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.builder.instruction.BuilderInstruction10x
|
|
||||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
|
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
|
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
|
||||||
import org.jf.dexlib2.iface.reference.FieldReference
|
|
||||||
import org.jf.dexlib2.iface.reference.MethodReference
|
|
||||||
import org.jf.dexlib2.iface.reference.StringReference
|
|
||||||
|
|
||||||
@Patch
|
|
||||||
@DependsOn([ResourceMappingResourcePatch::class, IntegrationsPatch::class, SettingsPatch::class, GeneralResourceAdsPatch::class])
|
|
||||||
@Name("general-ads")
|
|
||||||
@Description("Removes general ads.")
|
|
||||||
@GeneralAdsCompatibility
|
|
||||||
@Version("0.0.1")
|
|
||||||
class GeneralBytecodeAdsPatch : BytecodePatch() {
|
|
||||||
// a constant used by litho
|
|
||||||
private val lithoConstant = 0xaed2868
|
|
||||||
|
|
||||||
// list of resource names to get the id of
|
|
||||||
private val resourceIds = arrayOf(
|
|
||||||
"ad_attribution",
|
|
||||||
"reel_multiple_items_shelf",
|
|
||||||
"info_cards_drawer_header",
|
|
||||||
"endscreen_element_layout_video",
|
|
||||||
"endscreen_element_layout_circle",
|
|
||||||
"endscreen_element_layout_icon",
|
|
||||||
"promoted_video_item_land",
|
|
||||||
"promoted_video_item_full_bleed",
|
|
||||||
).map { name ->
|
|
||||||
ResourceMappingResourcePatch.resourceMappings.single { it.name == name }.id
|
|
||||||
}
|
|
||||||
|
|
||||||
private val stringReferences = arrayOf(
|
|
||||||
"Claiming to use more elements than provided",
|
|
||||||
"loadVideo() called on LocalDirector in wrong state",
|
|
||||||
"LoggingProperties are not in proto format"
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
|
||||||
SettingsPatch.PreferenceScreen.ADS.addPreferences(
|
|
||||||
SwitchPreference(
|
|
||||||
"revanced_home_ads_removal",
|
|
||||||
StringResource("revanced_home_ads_removal_title", "Remove home ads"),
|
|
||||||
true,
|
|
||||||
StringResource("revanced_home_ads_removal_summary_on", "Home ads are hidden"),
|
|
||||||
StringResource("revanced_home_ads_removal_summary_off", "Home ads are shown")
|
|
||||||
),
|
|
||||||
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"),
|
|
||||||
false,
|
|
||||||
StringResource("revanced_adremover_community_posts_enabled_summary_on", "Community posts are hidden"),
|
|
||||||
StringResource("revanced_adremover_community_posts_enabled_summary_off", "Community posts are shown")
|
|
||||||
),
|
|
||||||
SwitchPreference(
|
|
||||||
"revanced_adremover_compact_banner_removal",
|
|
||||||
StringResource("revanced_adremover_compact_banner_enabled_title", "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_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
|
|
||||||
for (classDef in context.classes) {
|
|
||||||
var mutableClass: MutableClass? = null
|
|
||||||
|
|
||||||
method@ for (method in classDef.methods) {
|
|
||||||
var mutableMethod: MutableMethod? = null
|
|
||||||
|
|
||||||
if (method.implementation == null) continue@method
|
|
||||||
|
|
||||||
val instructions = method.implementation!!.instructions
|
|
||||||
instructions.forEachIndexed { index, instruction ->
|
|
||||||
when (instruction.opcode) {
|
|
||||||
Opcode.CONST -> {
|
|
||||||
// TODO: find a way to de-duplicate code.
|
|
||||||
// The issue is we need to save mutableClass and mutableMethod to the existing fields
|
|
||||||
when ((instruction as Instruction31i).wideLiteral) {
|
|
||||||
resourceIds[0] -> { // general ads
|
|
||||||
// and is followed by an instruction with the mnemonic INVOKE_VIRTUAL
|
|
||||||
val insertIndex = index + 1
|
|
||||||
val invokeInstruction = instructions.elementAt(insertIndex)
|
|
||||||
if (invokeInstruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
|
|
||||||
|
|
||||||
// create proxied method, make sure to not re-resolve() the current class
|
|
||||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
|
||||||
if (mutableMethod == null) mutableMethod =
|
|
||||||
mutableClass!!.findMutableMethodOf(method)
|
|
||||||
|
|
||||||
// insert hide call to hide the view corresponding to the resource
|
|
||||||
val viewRegister = (invokeInstruction as Instruction35c).registerC
|
|
||||||
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceIds[1] -> { // reel ads
|
|
||||||
// and is followed by an instruction at insertIndex with the mnemonic IPUT_OBJECT
|
|
||||||
val insertIndex = index + 4
|
|
||||||
val iPutInstruction = instructions.elementAt(insertIndex)
|
|
||||||
if (iPutInstruction.opcode != Opcode.IPUT_OBJECT) return@forEachIndexed
|
|
||||||
|
|
||||||
// create proxied method, make sure to not re-resolve() the current class
|
|
||||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
|
||||||
if (mutableMethod == null) mutableMethod =
|
|
||||||
mutableClass!!.findMutableMethodOf(method)
|
|
||||||
|
|
||||||
val viewRegister = (iPutInstruction as Instruction22c).registerA
|
|
||||||
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceIds[2] -> { // info cards ads
|
|
||||||
// and is followed by an instruction with the mnemonic INVOKE_VIRTUAL
|
|
||||||
val removeIndex = index - 1
|
|
||||||
val invokeInstruction = instructions.elementAt(removeIndex)
|
|
||||||
if (invokeInstruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
|
|
||||||
|
|
||||||
// create proxied method, make sure to not re-resolve() the current class
|
|
||||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
|
||||||
if (mutableMethod == null) mutableMethod =
|
|
||||||
mutableClass!!.findMutableMethodOf(method)
|
|
||||||
|
|
||||||
//ToDo: Add Settings toggle for whatever this is
|
|
||||||
mutableMethod!!.implementation!!.removeInstruction(removeIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceIds[3], resourceIds[4], resourceIds[5] -> { // end screen ads
|
|
||||||
// and is followed by an instruction with the mnemonic IPUT_OBJECT
|
|
||||||
val insertIndex = index + 7
|
|
||||||
val invokeInstruction = instructions.elementAt(insertIndex)
|
|
||||||
if (invokeInstruction.opcode != Opcode.IPUT_OBJECT) return@forEachIndexed
|
|
||||||
|
|
||||||
// create proxied method, make sure to not re-resolve() the current class
|
|
||||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
|
||||||
if (mutableMethod == null) mutableMethod =
|
|
||||||
mutableClass!!.findMutableMethodOf(method)
|
|
||||||
|
|
||||||
// TODO: dynamically get registers
|
|
||||||
mutableMethod!!.addInstructions(
|
|
||||||
insertIndex, """
|
|
||||||
const/16 v1, 0x8
|
|
||||||
invoke-virtual {v0,v1}, Landroid/widget/FrameLayout;->setVisibility(I)V
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceIds[6] -> {
|
|
||||||
// and is followed by an instruction with the mnemonic INVOKE_DIRECT
|
|
||||||
val insertIndex = index + 3
|
|
||||||
val invokeInstruction = instructions.elementAt(insertIndex)
|
|
||||||
if (invokeInstruction.opcode != Opcode.INVOKE_DIRECT) return@forEachIndexed
|
|
||||||
|
|
||||||
// create proxied method, make sure to not re-resolve() the current class
|
|
||||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
|
||||||
if (mutableMethod == null) mutableMethod =
|
|
||||||
mutableClass!!.findMutableMethodOf(method)
|
|
||||||
|
|
||||||
// insert hide call to hide the view corresponding to the resource
|
|
||||||
val viewRegister = (invokeInstruction as Instruction35c).registerE
|
|
||||||
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
|
|
||||||
}
|
|
||||||
|
|
||||||
resourceIds[7] -> {
|
|
||||||
// TODO, go to class, hide the inflated view
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Opcode.CONST_STRING -> {
|
|
||||||
when (((instruction as Instruction21c).reference as StringReference).string) {
|
|
||||||
stringReferences[0] -> {
|
|
||||||
val stringInstruction = instructions.elementAt(3)
|
|
||||||
if (stringInstruction.opcode == Opcode.CONST_STRING) return@forEachIndexed
|
|
||||||
|
|
||||||
// create proxied method, make sure to not re-resolve() the current class
|
|
||||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
|
||||||
if (mutableMethod == null) mutableMethod =
|
|
||||||
mutableClass!!.findMutableMethodOf(method)
|
|
||||||
|
|
||||||
// return the method
|
|
||||||
val insertIndex = 1 // after super constructor
|
|
||||||
//ToDo: Add setting here
|
|
||||||
mutableMethod!!.implementation!!.addInstruction(
|
|
||||||
insertIndex, BuilderInstruction10x(Opcode.RETURN_VOID)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
stringReferences[1] -> {
|
|
||||||
// TODO: migrate video ads patch to here if necessary
|
|
||||||
}
|
|
||||||
|
|
||||||
stringReferences[2] -> { // Litho ads
|
|
||||||
val proxy = context.proxy(classDef)
|
|
||||||
val proxiedClass = proxy.mutableClass
|
|
||||||
|
|
||||||
val lithoMethod = getLithoMethod(proxiedClass)
|
|
||||||
?: return PatchResultError("Could not find required Litho method to patch.")
|
|
||||||
|
|
||||||
val instructionWithNeededDescriptor =
|
|
||||||
lithoMethod.implementation!!.instructions.indexOfFirst {
|
|
||||||
it.opcode == Opcode.INVOKE_STATIC_RANGE
|
|
||||||
}
|
|
||||||
|
|
||||||
// get required descriptors
|
|
||||||
val createEmptyComponentDescriptor =
|
|
||||||
lithoMethod.instruction(instructionWithNeededDescriptor)
|
|
||||||
.toDescriptor<MethodReference>()
|
|
||||||
val emptyComponentFieldDescriptor =
|
|
||||||
lithoMethod.instruction(instructionWithNeededDescriptor + 2)
|
|
||||||
.toDescriptor<FieldReference>()
|
|
||||||
|
|
||||||
val pathBuilderAnchorFingerprint = object : MethodFingerprint(
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.CONST_16,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.IPUT_OBJECT
|
|
||||||
)
|
|
||||||
) {}
|
|
||||||
|
|
||||||
val pathBuilderScanResult = pathBuilderAnchorFingerprint.also {
|
|
||||||
it.resolve(context, lithoMethod, classDef)
|
|
||||||
}.result!!.scanResult.patternScanResult!!
|
|
||||||
|
|
||||||
val clobberedRegister =
|
|
||||||
(lithoMethod.instruction(pathBuilderScanResult.startIndex) as OneRegisterInstruction).registerA
|
|
||||||
|
|
||||||
val insertIndex = pathBuilderScanResult.endIndex + 1
|
|
||||||
lithoMethod.addInstructions(
|
|
||||||
insertIndex, // right after setting the component.pathBuilder field,
|
|
||||||
"""
|
|
||||||
invoke-static {v5, v2}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z
|
|
||||||
move-result v$clobberedRegister
|
|
||||||
if-eqz v$clobberedRegister, :not_an_ad
|
|
||||||
move-object/from16 v2, p1
|
|
||||||
invoke-static {v2}, $createEmptyComponentDescriptor
|
|
||||||
move-result-object v0
|
|
||||||
iget-object v0, v0, $emptyComponentFieldDescriptor
|
|
||||||
return-object v0
|
|
||||||
""",
|
|
||||||
listOf(ExternalLabel("not_an_ad", lithoMethod.instruction(insertIndex)))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> return@forEachIndexed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PatchResultSuccess()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getLithoMethod(mutableClass: MutableClass) = mutableClass.methods.firstOrNull {
|
|
||||||
it.implementation?.instructions?.any { instruction ->
|
|
||||||
instruction.opcode == Opcode.CONST && (instruction as Instruction31i).narrowLiteral == lithoConstant
|
|
||||||
} ?: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.general.bytecode.utils
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
|
||||||
import org.jf.dexlib2.AccessFlags
|
|
||||||
import org.jf.dexlib2.iface.MethodImplementation
|
|
||||||
import org.jf.dexlib2.immutable.ImmutableMethod
|
|
||||||
import org.jf.dexlib2.immutable.ImmutableMethodParameter
|
|
||||||
|
|
||||||
internal object MethodUtils {
|
|
||||||
internal fun createMutableMethod(
|
|
||||||
definingClass: String, name: String, returnType: String, parameter: String, implementation: MethodImplementation
|
|
||||||
) = ImmutableMethod(
|
|
||||||
definingClass, name, listOf(
|
|
||||||
ImmutableMethodParameter(
|
|
||||||
parameter, null, null
|
|
||||||
)
|
|
||||||
), returnType, AccessFlags.PRIVATE or AccessFlags.STATIC, null, null, implementation
|
|
||||||
).toMutable()
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
package app.revanced.patches.youtube.ad.general.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
|
||||||
|
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.StringResource
|
||||||
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn(dependencies = [FixLocaleConfigErrorPatch::class, LithoFilterPatch::class, SettingsPatch::class])
|
||||||
|
@Name("general-ads")
|
||||||
|
@Description("Removes general ads.")
|
||||||
|
@GeneralAdsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class GeneralAdsPatch : ResourcePatch {
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.ADS.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_home_ads_removal",
|
||||||
|
StringResource("revanced_home_ads_removal_title", "Remove home ads"),
|
||||||
|
true,
|
||||||
|
StringResource("revanced_home_ads_removal_summary_on", "Home ads are hidden"),
|
||||||
|
StringResource("revanced_home_ads_removal_summary_off", "Home ads are shown")
|
||||||
|
),
|
||||||
|
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"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_adremover_community_posts_enabled_summary_on", "Community posts are hidden"),
|
||||||
|
StringResource("revanced_adremover_community_posts_enabled_summary_off", "Community posts are shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_adremover_compact_banner_removal",
|
||||||
|
StringResource("revanced_adremover_compact_banner_enabled_title", "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_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",
|
||||||
|
StringResource("revanced_adremover_shorts_enabled_title", "Remove shorts"),
|
||||||
|
true,
|
||||||
|
StringResource("revanced_adremover_shorts_enabled_summary_on", "Shorts are hidden"),
|
||||||
|
StringResource("revanced_adremover_shorts_enabled_summary_off", "Shorts are shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_adremover_community_guidelines",
|
||||||
|
StringResource("revanced_adremover_community_guidelines_enabled_title", "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", "Info panels are hidden"),
|
||||||
|
StringResource("revanced_adremover_info_panel_enabled_summary_off", "Info panels are shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_adremover_medical_panel",
|
||||||
|
StringResource("revanced_adremover_medical_panel_enabled_title", "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_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"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_adremover_self_sponsor",
|
||||||
|
StringResource("revanced_adremover_self_sponsor_enabled_title", "Hide self sponsored cards"),
|
||||||
|
true,
|
||||||
|
StringResource("revanced_adremover_self_sponsor_enabled_summary_on", "Self sponsored cards are hidden"),
|
||||||
|
StringResource("revanced_adremover_self_sponsor_enabled_summary_off", "Self sponsored cards are shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_adremover_chapter_teaser",
|
||||||
|
StringResource(
|
||||||
|
"revanced_adremover_chapter_teaser_enabled_title",
|
||||||
|
"Hide chapter teaser under videos"
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
StringResource(
|
||||||
|
"revanced_adremover_chapter_teaser_enabled_summary_on",
|
||||||
|
"Chapter teasers are hidden"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_adremover_chapter_teaser_enabled_summary_off",
|
||||||
|
"Chapter teasers are shown"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.general.resource.patch
|
|
||||||
|
|
||||||
import app.revanced.extensions.doRecursively
|
|
||||||
import app.revanced.extensions.startsWithAny
|
|
||||||
import app.revanced.patcher.annotation.Description
|
|
||||||
import app.revanced.patcher.annotation.Name
|
|
||||||
import app.revanced.patcher.annotation.Version
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
|
||||||
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
|
||||||
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
|
||||||
import org.w3c.dom.Element
|
|
||||||
|
|
||||||
@DependsOn(dependencies = [FixLocaleConfigErrorPatch::class])
|
|
||||||
@Name("general-resource-ads")
|
|
||||||
@Description("Patch to remove general ads in resources.")
|
|
||||||
@GeneralAdsCompatibility
|
|
||||||
@Version("0.0.1")
|
|
||||||
class GeneralResourceAdsPatch : ResourcePatch {
|
|
||||||
// list of resource file names which need to be hidden
|
|
||||||
private val resourceFileNames = arrayOf(
|
|
||||||
"compact_promoted_",
|
|
||||||
"promoted_video_",
|
|
||||||
)
|
|
||||||
|
|
||||||
// the attributes to change the value of
|
|
||||||
private val replacements = arrayOf(
|
|
||||||
"height",
|
|
||||||
"width",
|
|
||||||
"marginTop",
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext): PatchResult {
|
|
||||||
context.forEach {
|
|
||||||
if (!it.name.startsWithAny(*resourceFileNames)) return@forEach
|
|
||||||
|
|
||||||
// for each file in the "layouts" directory replace all necessary attributes content
|
|
||||||
context.xmlEditor[it.absolutePath].use { editor ->
|
|
||||||
editor.file.doRecursively { node ->
|
|
||||||
replacements.forEach replacement@{ replacement ->
|
|
||||||
if (node !is Element) return@replacement
|
|
||||||
|
|
||||||
node.getAttributeNode("android:layout_$replacement")?.let { attribute ->
|
|
||||||
attribute.textContent = "1.0dip"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PatchResultSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.infocardsuggestions.annotations
|
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Compatibility
|
|
||||||
import app.revanced.patcher.annotation.Package
|
|
||||||
|
|
||||||
@Compatibility(
|
|
||||||
[Package(
|
|
||||||
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
|
||||||
internal annotation class HideInfocardSuggestionsCompatibility
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.infocardsuggestions.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.impl.MethodFingerprint
|
|
||||||
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
|
||||||
import org.jf.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
@Name("hide-infocard-suggestions-fingerprint")
|
|
||||||
@FuzzyPatternScanMethod(2)
|
|
||||||
@HideInfocardSuggestionsCompatibility
|
|
||||||
@Version("0.0.1")
|
|
||||||
object HideInfocardSuggestionsFingerprint : MethodFingerprint(
|
|
||||||
"Ljava/lang/Boolean;",
|
|
||||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
|
||||||
strings = listOf("vibrator")
|
|
||||||
)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.infocardsuggestions.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.impl.MethodFingerprint
|
|
||||||
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
|
||||||
import org.jf.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
@Name("hide-infocard-suggestions-parent-fingerprint")
|
|
||||||
@FuzzyPatternScanMethod(2)
|
|
||||||
@HideInfocardSuggestionsCompatibility
|
|
||||||
@Version("0.0.1")
|
|
||||||
object HideInfocardSuggestionsParentFingerprint : MethodFingerprint(
|
|
||||||
"Ljava/lang/String;",
|
|
||||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
|
||||||
strings = listOf("player_overlay_info_card_teaser"),
|
|
||||||
)
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.infocardsuggestions.patch
|
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Description
|
|
||||||
import app.revanced.patcher.annotation.Name
|
|
||||||
import app.revanced.patcher.annotation.Version
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.replaceInstruction
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
|
||||||
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
|
||||||
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsFingerprint
|
|
||||||
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsParentFingerprint
|
|
||||||
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
|
|
||||||
|
|
||||||
@Patch
|
|
||||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
|
||||||
@Name("hide-infocard-suggestions")
|
|
||||||
@Description("Hides infocards in videos.")
|
|
||||||
@HideInfocardSuggestionsCompatibility
|
|
||||||
@Version("0.0.1")
|
|
||||||
class HideInfocardSuggestionsPatch : BytecodePatch(
|
|
||||||
listOf(
|
|
||||||
HideInfocardSuggestionsParentFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext): 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
|
|
||||||
?: return PatchResultError("Parent fingerprint not resolved!")
|
|
||||||
|
|
||||||
|
|
||||||
HideInfocardSuggestionsFingerprint.resolve(context, parentResult.classDef)
|
|
||||||
val result = HideInfocardSuggestionsFingerprint.result
|
|
||||||
?: return PatchResultError("Required parent method could not be found.")
|
|
||||||
|
|
||||||
val method = result.mutableMethod
|
|
||||||
val implementation = method.implementation
|
|
||||||
?: return PatchResultError("Implementation not found.")
|
|
||||||
|
|
||||||
val index = implementation.instructions.indexOfFirst { ((it as? BuilderInstruction35c)?.reference.toString() == "Landroid/view/View;->setVisibility(I)V") }
|
|
||||||
|
|
||||||
method.replaceInstruction(index, """
|
|
||||||
invoke-static {p1}, Lapp/revanced/integrations/patches/HideInfoCardSuggestionsPatch;->hideInfoCardSuggestions(Landroid/view/View;)V
|
|
||||||
""")
|
|
||||||
|
|
||||||
return PatchResultSuccess()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
|
|||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
object LoadVideoAdsFingerprint : MethodFingerprint(
|
object LoadVideoAdsFingerprint : MethodFingerprint(
|
||||||
strings = listOf(
|
strings = listOf(
|
||||||
"OnFulfillmentTriggersActivated has non registered slot",
|
"TriggerBundle doesn't have the required metadata specified by the trigger ",
|
||||||
"markFillRequested",
|
"Tried to enter slot with no assigned slotAdapter",
|
||||||
"Trying to enter a slot when a slot of same type and physical position is already active. Its status: ",
|
"Trying to enter a slot when a slot of same type and physical position is already active. Its status: ",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -15,12 +15,13 @@ import app.revanced.patcher.util.smali.ExternalLabel
|
|||||||
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.LoadVideoAdsFingerprint
|
import app.revanced.patches.youtube.ad.video.fingerprints.LoadVideoAdsFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playback.fix.patch.FixPlaybackPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, FixPlaybackPatch::class])
|
||||||
@Name("video-ads")
|
@Name("video-ads")
|
||||||
@Description("Removes ads in the video player.")
|
@Description("Removes ads in the video player.")
|
||||||
@VideoAdsCompatibility
|
@VideoAdsCompatibility
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.27.39", "17.29.34", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import app.revanced.patcher.patch.annotations.Patch
|
|||||||
import app.revanced.patches.youtube.interaction.downloads.annotation.DownloadsCompatibility
|
import app.revanced.patches.youtube.interaction.downloads.annotation.DownloadsCompatibility
|
||||||
import app.revanced.patches.youtube.interaction.downloads.resource.patch.DownloadsResourcePatch
|
import app.revanced.patches.youtube.interaction.downloads.resource.patch.DownloadsResourcePatch
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
|
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
|
||||||
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@Name("downloads")
|
@Name("downloads")
|
||||||
|
|||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import app.revanced.patcher.patch.annotations.Patch
|
|||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
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.SwipeControlsHostActivityFingerprint
|
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.SwipeControlsHostActivityFingerprint
|
||||||
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.WatchWhileActivityFingerprint
|
import app.revanced.shared.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.playertype.patch.PlayerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
|
||||||
|
|||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import app.revanced.patcher.patch.annotations.DependsOn
|
|||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
import app.revanced.patches.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 app.revanced.util.resources.ResourceUtils
|
||||||
|
import app.revanced.util.resources.ResourceUtils.copyResources
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@@ -22,36 +22,43 @@ import java.nio.file.Files
|
|||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class CustomBrandingPatch : ResourcePatch {
|
class CustomBrandingPatch : ResourcePatch {
|
||||||
override fun execute(context: ResourceContext): PatchResult {
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
val resDirectory = context["res"]
|
fun copyResources(resourceGroups: List<ResourceUtils.ResourceGroup>) {
|
||||||
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
|
iconPath?.let { iconPathString ->
|
||||||
|
val iconPath = File(iconPathString)
|
||||||
|
val resourceDirectory = context["res"]
|
||||||
|
|
||||||
// Icon branding
|
resourceGroups.forEach { group ->
|
||||||
val iconNames = arrayOf(
|
val fromDirectory = iconPath.resolve(group.resourceDirectoryName)
|
||||||
|
val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName)
|
||||||
|
|
||||||
|
group.resources.forEach { iconFileName ->
|
||||||
|
Files.write(
|
||||||
|
toDirectory.resolve(iconFileName).toPath(),
|
||||||
|
fromDirectory.resolve(iconFileName).readBytes()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: resourceGroups.forEach { context.copyResources("branding", it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val iconResourceFileNames = arrayOf(
|
||||||
"adaptiveproduct_youtube_background_color_108",
|
"adaptiveproduct_youtube_background_color_108",
|
||||||
"adaptiveproduct_youtube_foreground_color_108",
|
"adaptiveproduct_youtube_foreground_color_108",
|
||||||
"ic_launcher",
|
"ic_launcher",
|
||||||
"ic_launcher_round"
|
"ic_launcher_round"
|
||||||
|
).map { "$it.png" }.toTypedArray()
|
||||||
|
|
||||||
|
fun createGroup(directory: String) = ResourceUtils.ResourceGroup(
|
||||||
|
directory, *iconResourceFileNames
|
||||||
)
|
)
|
||||||
|
|
||||||
mapOf(
|
// change the app icon
|
||||||
"xxxhdpi" to 192,
|
arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi")
|
||||||
"xxhdpi" to 144,
|
.map { "mipmap-$it" }
|
||||||
"xhdpi" to 96,
|
.map(::createGroup)
|
||||||
"hdpi" to 72,
|
.let(::copyResources)
|
||||||
"mdpi" to 48
|
|
||||||
).forEach { (iconDirectory, size) ->
|
|
||||||
iconNames.forEach { iconName ->
|
|
||||||
val iconFile = getIconStream("branding/$size/$iconName.png")
|
|
||||||
?: return PatchResultError("The icon $iconName can not be found.")
|
|
||||||
|
|
||||||
Files.write(
|
// change the name of the app
|
||||||
resDirectory.resolve("mipmap-$iconDirectory").resolve("$iconName.png").toPath(),
|
|
||||||
iconFile.readBytes()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name branding
|
|
||||||
val manifest = context["AndroidManifest.xml"]
|
val manifest = context["AndroidManifest.xml"]
|
||||||
manifest.writeText(
|
manifest.writeText(
|
||||||
manifest.readText()
|
manifest.readText()
|
||||||
@@ -64,15 +71,6 @@ class CustomBrandingPatch : ResourcePatch {
|
|||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIconStream(iconPath: String): InputStream? {
|
|
||||||
if (appIconPath == null) {
|
|
||||||
return this.javaClass.classLoader.getResourceAsStream(iconPath)
|
|
||||||
}
|
|
||||||
val file = File(appIconPath!!).resolve(iconPath)
|
|
||||||
if (!file.exists()) return null
|
|
||||||
return FileInputStream(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object : OptionsContainer() {
|
companion object : OptionsContainer() {
|
||||||
private var appName: String? by option(
|
private var appName: String? by option(
|
||||||
PatchOption.StringOption(
|
PatchOption.StringOption(
|
||||||
@@ -84,12 +82,12 @@ class CustomBrandingPatch : ResourcePatch {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private var appIconPath: String? by option(
|
private var iconPath: String? by option(
|
||||||
PatchOption.StringOption(
|
PatchOption.StringOption(
|
||||||
key = "appIconPath",
|
key = "iconPath",
|
||||||
default = null,
|
default = null,
|
||||||
title = "Application Icon Path",
|
title = "App Icon Path",
|
||||||
description = "A path to the icon of the application."
|
description = "A path containing mipmap resource folders with icons."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
|||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
import app.revanced.patches.youtube.ad.general.bytecode.patch.GeneralBytecodeAdsPatch
|
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
|
||||||
import app.revanced.patches.youtube.layout.buttons.annotations.HideButtonsCompatibility
|
import app.revanced.patches.youtube.layout.buttons.annotations.HideButtonsCompatibility
|
||||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
@@ -18,7 +18,7 @@ import app.revanced.patches.youtube.misc.settings.framework.components.impl.Stri
|
|||||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@DependsOn([ResourceMappingResourcePatch::class, GeneralBytecodeAdsPatch::class])
|
@DependsOn([ResourceMappingResourcePatch::class, LithoFilterPatch::class])
|
||||||
@Name("hide-video-buttons")
|
@Name("hide-video-buttons")
|
||||||
@Description("Adds options to hide action buttons under a video.")
|
@Description("Adds options to hide action buttons under a video.")
|
||||||
@HideButtonsCompatibility
|
@HideButtonsCompatibility
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.comments.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class CommentsCompatibility
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.comments.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.comments.annotations.CommentsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.comments.resource.patch.CommentsResourcePatch
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("shorts-comments-button-fingerprint")
|
||||||
|
@CommentsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object ShortsCommentsButtonFingerprint : MethodFingerprint(
|
||||||
|
"V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("Z", "Z", "L"),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any {
|
||||||
|
it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == CommentsResourcePatch.shortsCommentsButtonId
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.comments.bytecode.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.layout.comments.annotations.CommentsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.comments.bytecode.fingerprints.ShortsCommentsButtonFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.comments.resource.patch.CommentsResourcePatch
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, CommentsResourcePatch::class])
|
||||||
|
@Name("comments")
|
||||||
|
@Description("Hides components related to comments.")
|
||||||
|
@CommentsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class CommentsPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
ShortsCommentsButtonFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
val shortsCommentsButtonResult = ShortsCommentsButtonFingerprint.result!!
|
||||||
|
val shortsCommentsButtonMethod = shortsCommentsButtonResult.mutableMethod
|
||||||
|
|
||||||
|
val checkCastAnchorFingerprint = object : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.CONST_HIGH16,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
)
|
||||||
|
) {}
|
||||||
|
|
||||||
|
val checkCastAnchorIndex = checkCastAnchorFingerprint.also {
|
||||||
|
it.resolve(context, shortsCommentsButtonMethod, shortsCommentsButtonResult.classDef)
|
||||||
|
}.result!!.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
|
shortsCommentsButtonMethod.addInstructions(
|
||||||
|
checkCastAnchorIndex + 1, """
|
||||||
|
invoke-static {v${(shortsCommentsButtonMethod.instruction(checkCastAnchorIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideShortsCommentsButtonPatch;->hideShortsCommentsButton(Landroid/view/View;)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.comments.resource.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.youtube.layout.comments.annotations.CommentsCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen
|
||||||
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||||
|
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||||
|
|
||||||
|
@Name("comments-resource-patch")
|
||||||
|
@CommentsCompatibility
|
||||||
|
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
|
||||||
|
@Version("0.0.1")
|
||||||
|
class CommentsResourcePatch : ResourcePatch {
|
||||||
|
companion object {
|
||||||
|
internal var shortsCommentsButtonId: Long = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
PreferenceScreen(
|
||||||
|
"revanced_comments",
|
||||||
|
StringResource("revanced_comments_title", "Comments"),
|
||||||
|
listOf(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_comments_section",
|
||||||
|
StringResource("revanced_hide_comments_section_title", "Remove comments section"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_comments_section_summary_on", "Comment section is hidden"),
|
||||||
|
StringResource("revanced_hide_comments_section_summary_off", "Comment section is shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_preview_comment",
|
||||||
|
StringResource("revanced_hide_preview_comment_title", "Hide preview comment"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_preview_comment_on", "Preview comment is hidden"),
|
||||||
|
StringResource("revanced_hide_preview_comment_off", "Preview comment is shown")
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_shorts_comments_button",
|
||||||
|
StringResource("revanced_hide_shorts_comments_button_title", "Hide shorts comments button"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_shorts_comments_button_on", "Shorts comments button is hidden"),
|
||||||
|
StringResource("revanced_hide_shorts_comments_button_off", "Shorts comments button is shown")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
StringResource("revanced_comments_summary", "Manage the visibility of comments section components")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
shortsCommentsButtonId = ResourceMappingResourcePatch.resourceMappings.single {
|
||||||
|
it.type == "drawable" && it.name == "ic_right_comment_32c"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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", "17.32.35", "17.33.42", "17.34.35", "17.34.36", "17.36.37")
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidealbumcards.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class AlbumCardsCompatibility
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidealbumcards.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hidealbumcards.annotations.AlbumCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hidealbumcards.resource.patch.AlbumCardsResourcePatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("album-cards-view-fingerprint")
|
||||||
|
@AlbumCardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object AlbumCardsFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any { instruction ->
|
||||||
|
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||||
|
(instruction as? WideLiteralInstruction)?.wideLiteral == AlbumCardsResourcePatch.albumCardId
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidealbumcards.bytecode.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.layout.hidealbumcards.annotations.AlbumCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hidealbumcards.bytecode.fingerprints.AlbumCardsFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hidealbumcards.resource.patch.AlbumCardsResourcePatch
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, AlbumCardsResourcePatch::class])
|
||||||
|
@Name("hide-album-cards")
|
||||||
|
@Description("Hides the album cards below the artist description.")
|
||||||
|
@AlbumCardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class AlbumCardsPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
AlbumCardsFingerprint,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
val albumCardsResult = AlbumCardsFingerprint.result!!
|
||||||
|
val albumCardsMethod = albumCardsResult.mutableMethod
|
||||||
|
|
||||||
|
val checkCastAnchorIndex = albumCardsResult.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
|
albumCardsMethod.addInstruction(
|
||||||
|
checkCastAnchorIndex + 1, """
|
||||||
|
invoke-static {v${(albumCardsMethod.instruction(checkCastAnchorIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideAlbumCardsPatch;->hideAlbumCards(Landroid/view/View;)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidealbumcards.resource.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.youtube.layout.hidealbumcards.annotations.AlbumCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
|
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
|
||||||
|
|
||||||
|
@Name("hide-album-cards-resource-patch")
|
||||||
|
@AlbumCardsCompatibility
|
||||||
|
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
|
||||||
|
@Version("0.0.1")
|
||||||
|
class AlbumCardsResourcePatch : ResourcePatch {
|
||||||
|
companion object {
|
||||||
|
internal var albumCardId: Long = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_album_cards",
|
||||||
|
StringResource("revanced_hide_album_cards_title", "Hide the album cards"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_album_cards_summary_on", "Album cards is hidden"),
|
||||||
|
StringResource("revanced_hide_album_cards_summary_off", "Album cards is visible")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
albumCardId = ResourceMappingResourcePatch.resourceMappings.single {
|
||||||
|
it.type == "layout" && it.name == "album_card"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.buttons.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class HideArtistCardCompatibility
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideartistcard.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
|
||||||
|
import app.revanced.patches.youtube.layout.buttons.annotations.HideArtistCardCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
|
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
|
||||||
|
@DependsOn([ResourceMappingResourcePatch::class, LithoFilterPatch::class])
|
||||||
|
@Name("hide-artist-card")
|
||||||
|
@Description("Hides the artist card below the searchbar.")
|
||||||
|
@HideArtistCardCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideArtistCardPatch : ResourcePatch {
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_artist_card",
|
||||||
|
StringResource("revanced_hide_hide_artist_card_title", "Hide artist card"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_hide_artist_card_on", "Artist card is hidden"),
|
||||||
|
StringResource("revanced_hide_hide_artist_card_off", "Artist card is shown")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidecaptionsbutton.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.layout.autocaptions.annotations.AutoCaptionsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleButtonControllerFingerprint
|
||||||
|
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
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||||
|
@Name("hide-captions-button")
|
||||||
|
@Description("Hides the captions button on video player.")
|
||||||
|
@AutoCaptionsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideCaptionsButtonPatch : BytecodePatch(listOf(
|
||||||
|
SubtitleButtonControllerFingerprint,
|
||||||
|
)) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_captions_button",
|
||||||
|
StringResource("revanced_hide_captions_button_title", "Hide captions button"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_captions_button_summary_on", "Captions button is hidden"),
|
||||||
|
StringResource("revanced_hide_captions_button_summary_off", "Captions button is shown")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod
|
||||||
|
|
||||||
|
// Due to previously applied patches, scanResult index cannot be used in this context
|
||||||
|
val igetBooleanIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst {
|
||||||
|
it.opcode == Opcode.IGET_BOOLEAN
|
||||||
|
}
|
||||||
|
|
||||||
|
subtitleButtonControllerMethod.addInstructions(
|
||||||
|
igetBooleanIndex + 1, """
|
||||||
|
invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class CrowdfundingBoxCompatibility
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidecrowdfundingbox.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations.CrowdfundingBoxCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("crowdfunding-box-view-parent-fingerprint")
|
||||||
|
@CrowdfundingBoxCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object CrowdfundingBoxFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.IPUT_OBJECT,
|
||||||
|
Opcode.CONST,
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any { instruction ->
|
||||||
|
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||||
|
(instruction as? WideLiteralInstruction)?.wideLiteral == CrowdfundingBoxResourcePatch.crowdfundingBoxId
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidecrowdfundingbox.bytecode.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch
|
||||||
|
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations.CrowdfundingBoxCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.bytecode.fingerprints.CrowdfundingBoxFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, CrowdfundingBoxResourcePatch::class])
|
||||||
|
@Name("hide-crowdfunding-box")
|
||||||
|
@Description("Hides the crowdfunding box between the player and video description.")
|
||||||
|
@CrowdfundingBoxCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class CrowdfundingBoxPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
CrowdfundingBoxFingerprint,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
val crowdfundingBoxResult = CrowdfundingBoxFingerprint.result!!
|
||||||
|
val crowdfundingBoxMethod = crowdfundingBoxResult.mutableMethod
|
||||||
|
|
||||||
|
val moveResultObjectIndex =
|
||||||
|
crowdfundingBoxResult.scanResult.patternScanResult!!.endIndex - 2
|
||||||
|
|
||||||
|
crowdfundingBoxMethod.addInstruction(
|
||||||
|
moveResultObjectIndex + 1, """
|
||||||
|
invoke-static {v${(crowdfundingBoxMethod.instruction(moveResultObjectIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidecrowdfundingbox.resource.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations.CrowdfundingBoxCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
|
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
|
||||||
|
|
||||||
|
@Name("crowdfunding-box-resource-patch")
|
||||||
|
@CrowdfundingBoxCompatibility
|
||||||
|
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
|
||||||
|
@Version("0.0.1")
|
||||||
|
class CrowdfundingBoxResourcePatch : ResourcePatch {
|
||||||
|
companion object {
|
||||||
|
internal var crowdfundingBoxId: Long = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_crowdfunding_box",
|
||||||
|
StringResource("revanced_hide_crowdfunding_box_title", "Hide the crowdfunding box"),
|
||||||
|
false,
|
||||||
|
StringResource("revanced_hide_crowdfunding_box_summary_on", "Crowdfunding box is hidden"),
|
||||||
|
StringResource("revanced_hide_crowdfunding_box_summary_off", "Crowdfunding box is visible")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
crowdfundingBoxId = ResourceMappingResourcePatch.resourceMappings.single {
|
||||||
|
it.type == "layout" && it.name == "donation_companion"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideendscreencards.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class HideEndscreenCardsCompatibility
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("layout-circle-fingerprint")
|
||||||
|
@HideEndscreenCardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object LayoutCircleFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any { instruction ->
|
||||||
|
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||||
|
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutCircle
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("layout-icon-fingerprint")
|
||||||
|
@HideEndscreenCardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object LayoutIconFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any { instruction ->
|
||||||
|
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||||
|
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutIcon
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("layout-video-fingerprint")
|
||||||
|
@HideEndscreenCardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object LayoutVideoFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any { instruction ->
|
||||||
|
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||||
|
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutVideo
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.fingerprint.Fingerprint
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutCircleFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutIconFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutVideoFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, HideEndscreenCardsResourcePatch::class])
|
||||||
|
@Name("hide-endscreen-cards")
|
||||||
|
@Description("Hides the suggested video cards at the end of a video in fullscreen.")
|
||||||
|
@HideEndscreenCardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideEndscreenCardsPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
LayoutCircleFingerprint,
|
||||||
|
LayoutIconFingerprint,
|
||||||
|
LayoutVideoFingerprint,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
fun MethodFingerprint.injectHideCall() {
|
||||||
|
val layoutResult = result!!
|
||||||
|
val layoutMethod = layoutResult.mutableMethod
|
||||||
|
|
||||||
|
val checkCastIndex = layoutResult.scanResult.patternScanResult!!.endIndex
|
||||||
|
val viewRegister = (layoutMethod.instruction(checkCastIndex) as Instruction21c).registerA
|
||||||
|
|
||||||
|
layoutMethod.addInstruction(
|
||||||
|
checkCastIndex + 1,
|
||||||
|
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideEndscreenCardsPatch;->hideEndscreen(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf(LayoutCircleFingerprint, LayoutIconFingerprint, LayoutVideoFingerprint).forEach(MethodFingerprint::injectHideCall)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideendscreencards.resource.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
|
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
|
||||||
|
|
||||||
|
@Name("hide-endscreen-cards-resource-patch")
|
||||||
|
@HideEndscreenCardsCompatibility
|
||||||
|
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideEndscreenCardsResourcePatch : ResourcePatch {
|
||||||
|
internal companion object {
|
||||||
|
var layoutCircle: Long = -1
|
||||||
|
var layoutIcon: Long = -1
|
||||||
|
var layoutVideo: Long = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_endscreen_cards",
|
||||||
|
StringResource("revanced_hide_endscreen_cards_title", "Hide end-screen cards"),
|
||||||
|
true,
|
||||||
|
StringResource("revanced_hide_endscreen_cards_summary_on", "End-screen cards are hidden"),
|
||||||
|
StringResource("revanced_hide_endscreen_cards_summary_off", "End-screen cards are shown")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun findEndscreenResourceId(name: String) = ResourceMappingResourcePatch.resourceMappings.single {
|
||||||
|
it.type == "layout" && it.name == "endscreen_element_layout_$name"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
layoutCircle = findEndscreenResourceId("circle")
|
||||||
|
layoutIcon = findEndscreenResourceId("icon")
|
||||||
|
layoutVideo = findEndscreenResourceId("video")
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideinfocards.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class HideInfocardsCompatibility
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("infocards-incognito-fingerprint")
|
||||||
|
@HideInfocardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object InfocardsIncognitoFingerprint : MethodFingerprint(
|
||||||
|
"Ljava/lang/Boolean;",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
strings = listOf("vibrator")
|
||||||
|
)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("infocards-incognito-parent-fingerprint")
|
||||||
|
@HideInfocardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object InfocardsIncognitoParentFingerprint : MethodFingerprint(
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
strings = listOf("player_overlay_info_card_teaser"),
|
||||||
|
)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.resource.patch.HideInfocardsResourcePatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("infocards-method-call-fingerprint")
|
||||||
|
@HideInfocardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object InfocardsMethodCallFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
),
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation?.instructions?.any { instruction ->
|
||||||
|
(instruction as? WideLiteralInstruction)?.wideLiteral == HideInfocardsResourcePatch.drawerResourceId
|
||||||
|
} == true
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideinfocards.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.extensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsIncognitoFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsIncognitoParentFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsMethodCallFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.resource.patch.HideInfocardsResourcePatch
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@DependsOn([IntegrationsPatch::class, HideInfocardsResourcePatch::class])
|
||||||
|
@Name("hide-info-cards")
|
||||||
|
@Description("Hides info-cards in videos.")
|
||||||
|
@HideInfocardsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideInfocardsPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
InfocardsIncognitoParentFingerprint,
|
||||||
|
InfocardsMethodCallFingerprint,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
with(InfocardsIncognitoFingerprint.also {
|
||||||
|
it.resolve(context, InfocardsIncognitoParentFingerprint.result!!.classDef)
|
||||||
|
}.result!!.mutableMethod) {
|
||||||
|
val invokeInstructionIndex = implementation!!.instructions.indexOfFirst {
|
||||||
|
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal &&
|
||||||
|
((it as? BuilderInstruction35c)?.reference.toString() ==
|
||||||
|
"Landroid/view/View;->setVisibility(I)V")
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceInstruction(
|
||||||
|
invokeInstructionIndex,
|
||||||
|
"invoke-static {v${(instruction(invokeInstructionIndex) as? BuilderInstruction35c)?.registerC}}," +
|
||||||
|
" Lapp/revanced/integrations/patches/HideInfocardsPatch;->hideInfocardsIncognito(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(InfocardsMethodCallFingerprint.result!!) {
|
||||||
|
val hideInfocardsCallMethod = mutableMethod
|
||||||
|
|
||||||
|
val invokeInterfaceIndex = scanResult.patternScanResult!!.endIndex
|
||||||
|
val toggleRegister = hideInfocardsCallMethod.implementation!!.registerCount - 1
|
||||||
|
|
||||||
|
hideInfocardsCallMethod.addInstructions(
|
||||||
|
invokeInterfaceIndex, """
|
||||||
|
invoke-static {}, Lapp/revanced/integrations/patches/HideInfocardsPatch;->hideInfocardsMethodCall()Z
|
||||||
|
move-result v$toggleRegister
|
||||||
|
if-nez v$toggleRegister, :hide_info_cards
|
||||||
|
""",
|
||||||
|
listOf(
|
||||||
|
ExternalLabel(
|
||||||
|
"hide_info_cards", hideInfocardsCallMethod.instruction(invokeInterfaceIndex + 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hideinfocards.resource.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
|
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||||
|
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
|
||||||
|
|
||||||
|
@HideInfocardsCompatibility
|
||||||
|
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideInfocardsResourcePatch : ResourcePatch {
|
||||||
|
internal companion object {
|
||||||
|
var drawerResourceId: Long = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_infocards",
|
||||||
|
StringResource("revanced_hide_infocards_title", "Hide info-cards"),
|
||||||
|
true,
|
||||||
|
StringResource("revanced_hide_infocards_summary_on", "Info-cards are hidden"),
|
||||||
|
StringResource("revanced_hide_infocards_summary_off", "Info-cards are shown")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
drawerResourceId = ResourceMappingResourcePatch.resourceMappings.single {
|
||||||
|
it.type == "id" && it.name == "info_cards_drawer_header"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.hidemixplaylists.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.36.37", "17.36.39", "17.37.35", "17.38.36", "17.39.35", "17.40.41", "17.41.37", "17.42.35", "17.43.36")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class MixPlaylistsPatchCompatibility
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user