Compare commits

...

121 Commits

Author SHA1 Message Date
semantic-release-bot
9969d03116 chore(release): 2.16.1 [skip ci]
## [2.16.1](https://github.com/revanced/revanced-patches/compare/v2.16.0...v2.16.1) (2022-07-17)

### Bug Fixes

* bump youtube version to 17.27.39 ([9d1fecc](9d1fecc2f5))
2022-07-17 15:04:31 +00:00
TheJeterLP
9d1fecc2f5 fix: bump youtube version to 17.27.39 2022-07-17 17:02:43 +02:00
semantic-release-bot
63df96d251 chore(release): 2.16.0 [skip ci]
# [2.16.0](https://github.com/revanced/revanced-patches/compare/v2.15.1...v2.16.0) (2022-07-17)

### Features

* `force-vp9-codec` patch ([#157](https://github.com/revanced/revanced-patches/issues/157)) ([d1266a2](d1266a252d))
2022-07-17 14:34:06 +00:00
TheJeterLP
d1266a252d feat: force-vp9-codec patch (#157) 2022-07-17 16:32:29 +02:00
semantic-release-bot
6ec6d16dbc chore(release): 2.15.1 [skip ci]
## [2.15.1](https://github.com/revanced/revanced-patches/compare/v2.15.0...v2.15.1) (2022-07-17)

### Bug Fixes

* `old-quality-layout` patch ([f940e46](f940e4647e))
* references to integrations in `return-youtube-dislike` patch ([9860658](986065858d))
2022-07-17 14:05:02 +00:00
oSumAtrIX
f940e4647e fix: old-quality-layout patch 2022-07-17 16:03:20 +02:00
oSumAtrIX
cc39b77b49 refactor: use .single for resourceMappings 2022-07-17 16:03:20 +02:00
oSumAtrIX
986065858d fix: references to integrations in return-youtube-dislike patch 2022-07-17 16:03:19 +02:00
TheJeterLP
56475e8f38 refactor: rename HDRAutoBrightnessPatch 2022-07-17 15:07:21 +02:00
Palm
2e0ff07d1a style: better patch descriptions (#193) 2022-07-17 12:36:46 +02:00
oSumAtrIX
a654e25000 refactor: simplify use of dependencies field in Dependencies annotations 2022-07-16 17:32:03 +02:00
oSumAtrIX
a8736a8f70 style: naming for ReturnYouTubeDislike patch 2022-07-16 17:31:40 +02:00
semantic-release-bot
b0d6cee4db chore(release): 2.15.0 [skip ci]
# [2.15.0](https://github.com/revanced/revanced-patches/compare/v2.14.1...v2.15.0) (2022-07-16)

### Features

* `return-youtube-dislikes` patch ([#175](https://github.com/revanced/revanced-patches/issues/175)) ([6bbcdf8](6bbcdf8ebd))
2022-07-16 14:52:58 +00:00
j4k0xb
6bbcdf8ebd feat: return-youtube-dislikes patch (#175)
* feat: ryd

* refactor: use ryd patches class

* feat: add video id dependency patch

* fix: compatibility with 17.26.35

* refactor: named param variable, simpler mutableClass access
2022-07-16 16:50:37 +02:00
semantic-release-bot
6fa8289ca6 chore(release): 2.14.1 [skip ci]
## [2.14.1](https://github.com/revanced/revanced-patches/compare/v2.14.0...v2.14.1) (2022-07-15)

### Bug Fixes

* `codecs-unlock` patch and update Music patches to `5.14.53` ([97dbb43](97dbb43caa))
2022-07-15 12:57:47 +00:00
Alberto Ponces
97dbb43caa fix: codecs-unlock patch and update Music patches to 5.14.53 2022-07-15 14:56:10 +02:00
semantic-release-bot
8cda5663ef chore(release): 2.14.0 [skip ci]
# [2.14.0](https://github.com/revanced/revanced-patches/compare/v2.13.6...v2.14.0) (2022-07-15)

### Features

* `music-video-ads` patch ([#172](https://github.com/revanced/revanced-patches/issues/172)) ([5587c91](5587c91899))
2022-07-15 11:20:04 +00:00
Alberto Ponces
5587c91899 feat: music-video-ads patch (#172) 2022-07-15 13:18:25 +02:00
semantic-release-bot
4e6d82a334 chore(release): 2.13.6 [skip ci]
## [2.13.6](https://github.com/revanced/revanced-patches/compare/v2.13.5...v2.13.6) (2022-07-14)
2022-07-14 16:48:23 +00:00
TheJeterLP
be7302689e build: trigger build 2022-07-14 18:46:33 +02:00
TheJeterLP
14d94d6a44 refactor: prepare for settings patch (#168) 2022-07-14 18:42:22 +02:00
genericness
8d598f5b82 style: casing in description (#174) 2022-07-14 18:40:21 +02:00
semantic-release-bot
918782908b chore(release): 2.13.5 [skip ci]
## [2.13.5](https://github.com/revanced/revanced-patches/compare/v2.13.4...v2.13.5) (2022-07-14)

### Bug Fixes

* `swipe-controls` with active engagement panel ([#177](https://github.com/revanced/revanced-patches/issues/177)) ([524fe19](524fe19840))
2022-07-14 15:23:07 +00:00
Chris
524fe19840 fix: swipe-controls with active engagement panel (#177) 2022-07-14 17:21:26 +02:00
semantic-release-bot
18aafb400b chore(release): 2.13.4 [skip ci]
## [2.13.4](https://github.com/revanced/revanced-patches/compare/v2.13.3...v2.13.4) (2022-07-13)

### Bug Fixes

* constrain `old-quality-layout` to older version ([83ac6b3](83ac6b3e34))
2022-07-13 11:38:21 +00:00
oSumAtrIX
83ac6b3e34 fix: constrain old-quality-layout to older version 2022-07-13 13:36:09 +02:00
oSumAtrIX
890ebf04df docs: change size of headings [skip ci] 2022-07-12 01:13:09 +02:00
oSumAtrIX
6838daf1c3 refactor: rename class and move to sub-package 2022-07-12 00:04:22 +02:00
bogadana
08f4e8532c docs: properly handle semantic versions (#156) [skip ci] 2022-07-11 21:08:47 +02:00
semantic-release-bot
30d25a87da chore(release): 2.13.3 [skip ci]
## [2.13.3](https://github.com/revanced/revanced-patches/compare/v2.13.2...v2.13.3) (2022-07-11)

### Bug Fixes

* `exclusive-audio-playback` patch ([#153](https://github.com/revanced/revanced-patches/issues/153)) ([af0523d](af0523df39))
2022-07-11 18:07:27 +00:00
Alberto Ponces
af0523df39 fix: exclusive-audio-playback patch (#153) 2022-07-11 20:05:03 +02:00
semantic-release-bot
18a3f8e80c chore(release): 2.13.2 [skip ci]
## [2.13.2](https://github.com/revanced/revanced-patches/compare/v2.13.1...v2.13.2) (2022-07-11)

### Bug Fixes

* `hrd-auto-brightness` ([#152](https://github.com/revanced/revanced-patches/issues/152)) ([ce32c6f](ce32c6f3f7))
2022-07-11 17:01:08 +00:00
Chris
ce32c6f3f7 fix: hrd-auto-brightness (#152) 2022-07-11 18:59:26 +02:00
semantic-release-bot
6b706bc93c chore(release): 2.13.1 [skip ci]
## [2.13.1](https://github.com/revanced/revanced-patches/compare/v2.13.0...v2.13.1) (2022-07-11)

### Bug Fixes

* bump youtube version for swipe-controls patch ([6838e25](6838e25764))
2022-07-11 12:41:09 +00:00
TheJeterLP
6838e25764 fix: bump youtube version for swipe-controls patch 2022-07-11 14:39:36 +02:00
semantic-release-bot
f6f8b0ee31 chore(release): 2.13.0 [skip ci]
# [2.13.0](https://github.com/revanced/revanced-patches/compare/v2.12.4...v2.13.0) (2022-07-11)

### Features

* `swipe-controls` rewrite ([#131](https://github.com/revanced/revanced-patches/issues/131)) ([8e26d09](8e26d0933d))
2022-07-11 12:31:53 +00:00
Chris
8e26d0933d feat: swipe-controls rewrite (#131)
* move patch 'fenster' to 'swipe-controls'

* remove 'injectIntoNamedMethod' function

* move updatePlayerType hook into its own patch

* refactor 'swipe-controls' patch

* add resources for new ui to patch

Co-authored-by: TheJeterLP <joey.peter1998@gmail.com>
2022-07-11 14:29:46 +02:00
semantic-release-bot
6f29325a85 chore(release): 2.12.4 [skip ci]
## [2.12.4](https://github.com/revanced/revanced-patches/compare/v2.12.3...v2.12.4) (2022-07-11)

### Bug Fixes

*  `autorepeat-by-default` patch ([#148](https://github.com/revanced/revanced-patches/issues/148)) ([46e163c](46e163caa9))
2022-07-11 06:58:15 +00:00
TheJeterLP
46e163caa9 fix: autorepeat-by-default patch (#148) 2022-07-11 08:56:33 +02:00
semantic-release-bot
af19363997 chore(release): 2.12.3 [skip ci]
## [2.12.3](https://github.com/revanced/revanced-patches/compare/v2.12.2...v2.12.3) (2022-07-11)

### Bug Fixes

* listing of wrong fingerprint class ([#147](https://github.com/revanced/revanced-patches/issues/147)) ([c578e21](c578e210bb))
2022-07-11 05:51:29 +00:00
Alberto Ponces
c578e210bb fix: listing of wrong fingerprint class (#147) 2022-07-11 07:49:40 +02:00
Sculas
980f7f04cc chore: remove assignees [skip ci] 2022-07-10 20:30:47 +02:00
Sculas
baeb0ad0d4 chore: remove assignees [skip ci] 2022-07-10 20:30:35 +02:00
semantic-release-bot
6c4a69fcfb chore(release): 2.12.2 [skip ci]
## [2.12.2](https://github.com/revanced/revanced-patches/compare/v2.12.1...v2.12.2) (2022-07-10)

### Bug Fixes

* display codename for patch names ([7107ee8](7107ee87d9))
* incorrect package name in gradle task ([8ce3a6b](8ce3a6b4e3))
* invalid regex ([b39d60f](b39d60f46c))
2022-07-10 18:00:21 +00:00
oSumAtrIX
4129fcf8a8 refactor: add missing space in generated string 2022-07-10 19:58:32 +02:00
oSumAtrIX
b39d60f46c fix: invalid regex 2022-07-10 19:58:32 +02:00
oSumAtrIX
8ce3a6b4e3 fix: incorrect package name in gradle task 2022-07-10 19:58:32 +02:00
oSumAtrIX
7107ee87d9 fix: display codename for patch names 2022-07-10 19:58:32 +02:00
semantic-release-bot
7ea5d87fa2 chore(release): 2.12.1 [skip ci]
## [2.12.1](https://github.com/revanced/revanced-patches/compare/v2.12.0...v2.12.1) (2022-07-10)
2022-07-10 16:14:45 +00:00
TheJeterLP
471a3d3263 build: fix readme autogeneration not working 2022-07-10 18:12:52 +02:00
bogadana
b95fe30c78 docs: templated readme (#138) 2022-07-10 15:28:18 +02:00
semantic-release-bot
cb0cf342c0 chore(release): 2.12.0 [skip ci]
# [2.12.0](https://github.com/revanced/revanced-patches/compare/v2.11.0...v2.12.0) (2022-07-10)

### Bug Fixes

* update patches to `17.26.35` ([#142](https://github.com/revanced/revanced-patches/issues/142)) ([11db0f4](11db0f49c9))
* wording [skip ci] ([017ef1f](017ef1fb88))

### Features

* issue templates ([0991fbc](0991fbc9e8))
2022-07-10 05:38:19 +00:00
bogadana
11db0f49c9 fix: update patches to 17.26.35 (#142) 2022-07-10 07:36:43 +02:00
oSumAtrIX
017ef1fb88 fix: wording [skip ci] 2022-07-10 00:31:01 +02:00
oSumAtrIX
0991fbc9e8 feat: issue templates 2022-07-10 00:27:29 +02:00
semantic-release-bot
e1eedc02ab chore(release): 2.11.0 [skip ci]
# [2.11.0](https://github.com/revanced/revanced-patches/compare/v2.10.2...v2.11.0) (2022-07-09)

### Features

* `autorepeat-by-default` patch ([#106](https://github.com/revanced/revanced-patches/issues/106)) ([9be32e1](9be32e10f6))
2022-07-09 13:55:53 +00:00
oSumAtrIX
9be32e10f6 feat: autorepeat-by-default patch (#106) 2022-07-09 15:53:33 +02:00
semantic-release-bot
87996f67a8 chore(release): 2.10.2 [skip ci]
## [2.10.2](https://github.com/revanced/revanced-patches/compare/v2.10.1...v2.10.2) (2022-07-08)

### Bug Fixes

* trigger release on `build` commits ([0822383](0822383271))
2022-07-08 22:19:09 +00:00
Sculas
0822383271 fix: trigger release on build commits 2022-07-09 00:17:31 +02:00
TheJeterLP
0934af1ccd refactor: remove unused imports and merge packages together (#136) 2022-07-08 21:17:50 +02:00
bogadana
b3ad6fb8af docs: auto generate list of patches in README.md (#133)
* feat: auto generate list of patches in `README.md`

* sample readme

* formatting

* add codeblocks

* sample readme

* run on publish

* make workflow commit readme

* update readme [skip ci]

* update gen [skip ci]

* update workflow [skip ci]

* add readme to release assets

* fix: spacing in title

Co-authored-by: Sculas <contact@sculas.xyz>
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-07-08 21:17:39 +02:00
semantic-release-bot
87f5ebce9b chore(release): 2.10.1 [skip ci]
## [2.10.1](https://github.com/revanced/revanced-patches/compare/v2.10.0...v2.10.1) (2022-07-08)

### Bug Fixes

* patch description consistency ([#134](https://github.com/revanced/revanced-patches/issues/134)) ([a35d7c8](a35d7c8951))
2022-07-08 04:32:37 +00:00
bogadana
a35d7c8951 fix: patch description consistency (#134) 2022-07-08 06:30:59 +02:00
semantic-release-bot
3c8d3edff4 chore(release): 2.10.0 [skip ci]
# [2.10.0](https://github.com/revanced/revanced-patches/compare/v2.9.4...v2.10.0) (2022-07-07)

### Features

* implement `wide-searchbar` Patch ([#130](https://github.com/revanced/revanced-patches/issues/130)) ([c35734b](c35734bec2))
2022-07-07 23:42:01 +00:00
TheJeterLP
c35734bec2 feat: implement wide-searchbar Patch (#130) 2022-07-08 01:40:12 +02:00
semantic-release-bot
e2b634053b chore(release): 2.9.4 [skip ci]
## [2.9.4](https://github.com/revanced/revanced-patches/compare/v2.9.3...v2.9.4) (2022-07-06)

### Bug Fixes

* add 17.25.34 as supported version for swipe-controls patch ([3e6df0c](3e6df0c96d))
2022-07-06 18:34:04 +00:00
TheJeterLP
3e6df0c96d fix: add 17.25.34 as supported version for swipe-controls patch 2022-07-06 20:31:59 +02:00
semantic-release-bot
7a2ea95e55 chore(release): 2.9.3 [skip ci]
## [2.9.3](https://github.com/revanced/revanced-patches/compare/v2.9.2...v2.9.3) (2022-07-06)

### Bug Fixes

* Readd `swipe-controls` patch ([#123](https://github.com/revanced/revanced-patches/issues/123)) ([add3058](add3058d24))
2022-07-06 18:29:29 +00:00
TheJeterLP
add3058d24 fix: Readd swipe-controls patch (#123) 2022-07-06 20:27:28 +02:00
semantic-release-bot
ef888f6b59 chore(release): 2.9.2 [skip ci]
## [2.9.2](https://github.com/revanced/revanced-patches/compare/v2.9.1...v2.9.2) (2022-07-05)

### Bug Fixes

* revert `swipe-controls` patch  ([9b077d6](9b077d6ada))
2022-07-05 21:26:17 +00:00
oSumAtrIX
9b077d6ada fix: revert swipe-controls patch
This reverts commit cd66ee4e57.
2022-07-05 23:24:10 +02:00
semantic-release-bot
93d4cee16e chore(release): 2.9.1 [skip ci]
## [2.9.1](https://github.com/revanced/revanced-patches/compare/v2.9.0...v2.9.1) (2022-07-05)

### Bug Fixes

* make `minimized-playback-manager-fingerprint` unique ([#120](https://github.com/revanced/revanced-patches/issues/120)) ([bc3b654](bc3b654357))
2022-07-05 20:24:42 +00:00
bogadana
bc3b654357 fix: make minimized-playback-manager-fingerprint unique (#120) 2022-07-05 22:23:00 +02:00
semantic-release-bot
64b4c92ca0 chore(release): 2.9.0 [skip ci]
# [2.9.0](https://github.com/revanced/revanced-patches/compare/v2.8.2...v2.9.0) (2022-07-05)

### Features

* `swipe-controls` patch ([#115](https://github.com/revanced/revanced-patches/issues/115)) ([cd66ee4](cd66ee4e57))
2022-07-05 20:04:45 +00:00
Chris
cd66ee4e57 feat: swipe-controls patch (#115) 2022-07-05 22:03:07 +02:00
semantic-release-bot
f527226757 chore(release): 2.8.2 [skip ci]
## [2.8.2](https://github.com/revanced/revanced-patches/compare/v2.8.1...v2.8.2) (2022-07-05)

### Bug Fixes

* show minimized playback options in settings ([#118](https://github.com/revanced/revanced-patches/issues/118)) ([ec0b17a](ec0b17a4d8))
2022-07-05 17:47:26 +00:00
bogadana
ec0b17a4d8 fix: show minimized playback options in settings (#118) 2022-07-05 19:45:46 +02:00
bogadana
63598d0d42 build: bump patcher dependency version (#119) 2022-07-05 18:44:58 +02:00
semantic-release-bot
14f6b66135 chore(release): 2.8.1 [skip ci]
## [2.8.1](https://github.com/revanced/revanced-patches/compare/v2.8.0...v2.8.1) (2022-07-05)

### Bug Fixes

* remove unnecessary version constraints ([#117](https://github.com/revanced/revanced-patches/issues/117)) ([18893c0](18893c005e))
2022-07-05 13:04:01 +00:00
bogadana
18893c005e fix: remove unnecessary version constraints (#117) 2022-07-05 15:02:00 +02:00
semantic-release-bot
73b51a0687 chore(release): 2.8.0 [skip ci]
# [2.8.0](https://github.com/revanced/revanced-patches/compare/v2.7.0...v2.8.0) (2022-07-04)

### Features

* `enable-debugging` patch ([#116](https://github.com/revanced/revanced-patches/issues/116)) ([c4de003](c4de003fc1))
2022-07-04 16:12:27 +00:00
Chris
c4de003fc1 feat: enable-debugging patch (#116) 2022-07-04 18:10:49 +02:00
semantic-release-bot
45b8ad099e chore(release): 2.7.0 [skip ci]
# [2.7.0](https://github.com/revanced/revanced-patches/compare/v2.6.0...v2.7.0) (2022-07-03)

### Features

* `hdr-max-brightness` patch ([#105](https://github.com/revanced/revanced-patches/issues/105)) ([8c40ff4](8c40ff4852))
* `hide-infocard-suggestions` patch ([#107](https://github.com/revanced/revanced-patches/issues/107)) ([f304c86](f304c866f1))
2022-07-03 18:52:05 +00:00
oSumAtrIX
8c40ff4852 feat: hdr-max-brightness patch (#105) 2022-07-03 20:50:20 +02:00
oSumAtrIX
f304c866f1 feat: hide-infocard-suggestions patch (#107) 2022-07-03 20:50:09 +02:00
Robert
9adf42c308 Update description (#110) 2022-07-03 19:19:50 +02:00
semantic-release-bot
2391db0f53 chore(release): 2.6.0 [skip ci]
# [2.6.0](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.6.0) (2022-07-02)

### Bug Fixes

* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([d3e1419](d3e1419d0e))
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([c21e177](c21e177ed1))
* remove refreshing home screen not working ([c5ec801](c5ec801b90))

### Features

* migrate to breaking changes of patcher ([9395e08](9395e0835e))
2022-07-02 23:03:09 +00:00
oSumAtrIX
9809e4dfd0 build: bump patcher dependency version 2022-07-03 01:01:20 +02:00
semantic-release-bot
b191efea2d chore(release): 2.6.0-dev.2 [skip ci]
# [2.6.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.6.0-dev.1...v2.6.0-dev.2) (2022-07-02)

### Bug Fixes

* remove refreshing home screen not working ([42def27](42def27fa5))
2022-07-03 01:01:20 +02:00
oSumAtrIX
c5ec801b90 fix: remove refreshing home screen not working 2022-07-03 01:01:20 +02:00
oSumAtrIX
95f22bc2a1 refactor: add package for fingerprints 2022-07-03 01:01:20 +02:00
semantic-release-bot
0098f25bfb chore(release): 2.6.0-dev.1 [skip ci]
# [2.6.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.1-dev.1...v2.6.0-dev.1) (2022-07-02)

### Features

* migrate to breaking changes of patcher ([c95c241](c95c241887))
2022-07-03 01:01:20 +02:00
oSumAtrIX
9395e0835e feat: migrate to breaking changes of patcher 2022-07-03 01:01:20 +02:00
semantic-release-bot
d59d6b7022 chore(release): 2.5.1-dev.1 [skip ci]
## [2.5.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.5.1-dev.1) (2022-06-30)

### Bug Fixes

* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([d3e1419](d3e1419d0e))
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([c21e177](c21e177ed1))
2022-07-03 01:01:20 +02:00
Aunali321
c21e177ed1 fix: invalid version in compatibility annotation (#90) 2022-06-30 20:24:29 +02:00
bogadana
d3e1419d0e fix: freezing panels when watching video in fullscreen (#89) 2022-06-30 19:15:51 +02:00
semantic-release-bot
f44d09059b chore(release): 2.5.0 [skip ci]
# [2.5.0](https://github.com/revanced/revanced-patches/compare/v2.4.0...v2.5.0) (2022-06-30)

### Features

* hide watermark support for 17.25.34 ([#87](https://github.com/revanced/revanced-patches/issues/87)) ([185f6d8](185f6d84fb))
2022-06-30 15:45:24 +00:00
Aunali321
185f6d84fb feat: hide watermark support for 17.25.34 (#87) 2022-06-30 17:43:21 +02:00
semantic-release-bot
3dc6be5d8d chore(release): 2.4.0 [skip ci]
# [2.4.0](https://github.com/revanced/revanced-patches/compare/v2.3.1...v2.4.0) (2022-06-30)

### Features

* add youtube version 17.25.34 ([#85](https://github.com/revanced/revanced-patches/issues/85)) ([742e239](742e2394a9))
2022-06-30 12:51:48 +00:00
Aunali321
742e2394a9 feat: add youtube version 17.25.34 (#85) 2022-06-30 14:50:16 +02:00
bogadana
d9d389b939 refactor: change name to fit in (#86) 2022-06-30 14:48:27 +02:00
semantic-release-bot
b0775e13d5 chore(release): 2.3.1 [skip ci]
## [2.3.1](https://github.com/revanced/revanced-patches/compare/v2.3.0...v2.3.1) (2022-06-30)

### Bug Fixes

* change fingerprint to work on latest youtube ([#80](https://github.com/revanced/revanced-patches/issues/80)) ([0fe98b6](0fe98b6c5e))
2022-06-30 04:19:47 +00:00
bogadana
0fe98b6c5e fix: change fingerprint to work on latest youtube (#80) 2022-06-30 06:18:14 +02:00
oSumAtrIX
3a78021f5e refactor: description of custom-playback-speed patch. 2022-06-30 02:48:18 +02:00
oSumAtrIX
e096009893 refactor: hide-autoplay-button & refactor: hide-autoplay-button && premium-heading patch 2022-06-30 02:39:24 +02:00
semantic-release-bot
b599ee2096 chore(release): 2.3.0 [skip ci]
# [2.3.0](https://github.com/revanced/revanced-patches/compare/v2.2.0...v2.3.0) (2022-06-30)

### Features

* `disable-autoplay-button` patch ([#79](https://github.com/revanced/revanced-patches/issues/79)) ([bd7cede](bd7cedee48))
2022-06-30 00:36:57 +00:00
bogadana
bd7cedee48 feat: disable-autoplay-button patch (#79) 2022-06-30 02:35:11 +02:00
oSumAtrIX
278c07ea56 build: bump patcher dependency version 2022-06-30 01:41:38 +02:00
semantic-release-bot
6dc2875057 chore(release): 2.2.0 [skip ci]
# [2.2.0](https://github.com/revanced/revanced-patches/compare/v2.1.0...v2.2.0) (2022-06-29)

### Features

* make resource mapping patch aware of types ([#77](https://github.com/revanced/revanced-patches/issues/77)) ([7b24071](7b24071956))
2022-06-29 22:50:21 +00:00
bogadana
7b24071956 feat: make resource mapping patch aware of types (#77) 2022-06-30 00:48:53 +02:00
semantic-release-bot
6c472aa71d chore(release): 2.1.0 [skip ci]
# [2.1.0](https://github.com/revanced/revanced-patches/compare/v2.0.3...v2.1.0) (2022-06-28)

### Features

* `custom-playback-speed` patch ([#50](https://github.com/revanced/revanced-patches/issues/50)) ([ca66490](ca66490930))
2022-06-28 21:44:38 +00:00
bogadana
ca66490930 feat: custom-playback-speed patch (#50) 2022-06-28 23:43:07 +02:00
semantic-release-bot
5317a482d1 chore(release): 2.0.3 [skip ci]
## [2.0.3](https://github.com/revanced/revanced-patches/compare/v2.0.2...v2.0.3) (2022-06-27)

### Bug Fixes

* check if resource files exist ([f21d1d8](f21d1d83f6))
2022-06-27 22:41:37 +00:00
oSumAtrIX
f21d1d83f6 fix: check if resource files exist 2022-06-28 00:39:51 +02:00
semantic-release-bot
bb6c805f55 chore(release): 2.0.2 [skip ci]
## [2.0.2](https://github.com/revanced/revanced-patches/compare/v2.0.1...v2.0.2) (2022-06-27)

### Bug Fixes

* some more refactoring of integrations, add hide-watermark patch ([#63](https://github.com/revanced/revanced-patches/issues/63)) ([c5dfe3e](c5dfe3e842))
2022-06-27 20:10:53 +00:00
Joey Peter
c5dfe3e842 fix: some more refactoring of integrations, add hide-watermark patch (#63)
* refactor: integrations

* add HideWatermark patch

* add hidewatermark patch

* fix bug

* use latest patcher version

* Fix sig name

* update to fingerprints

* make cleaner patch

* add 17.24.35 support for hide-watermark
2022-06-27 22:09:17 +02:00
oSumAtrIX
4290a4e820 refactor: remove trimIndent before compiling instructions 2022-06-27 01:09:40 +02:00
semantic-release-bot
1f6b450df3 chore(release): 2.0.1 [skip ci]
## [2.0.1](https://github.com/revanced/revanced-patches/compare/v2.0.0...v2.0.1) (2022-06-26)

### Bug Fixes

* invalid string in strings list ([a29de19](a29de19d4c))
* migrate to new `proxy` api ([d9f05ff](d9f05ffdf8))
2022-06-26 16:12:29 +00:00
oSumAtrIX
d9f05ffdf8 fix: migrate to new proxy api 2022-06-26 18:10:37 +02:00
oSumAtrIX
ddc693e909 build: bump patcher dependency version 2022-06-26 18:03:38 +02:00
oSumAtrIX
a29de19d4c fix: invalid string in strings list 2022-06-26 17:59:28 +02:00
132 changed files with 3268 additions and 323 deletions

24
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@@ -0,0 +1,24 @@
---
name: Bug report
about: Create a bug report on patches
title: 'problem: `some-patch`'
labels: bug
assignees: ''
---
## 🐞 Issue
<!-- Describe your issue in detail here -->
## ⚙ Reproduce
<!-- Include your environment and steps to reproduce the issue as detailed as possible -->
## 🛠 Solution
<!-- If applicable, add a possible solution -->
## ⚠ Additional context
<!-- Add any other context about the problem here -->

View File

@@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest a change to some patch. Do not submit suggestions for patches here.
title: 'feat: some feature'
labels: feature-request
assignees: ''
---
## 🐞 Issue
<!-- Explain here, what the current problem is and why it leads you to request a feature change -->
## ❗ Solution
<!-- Explain how your current issue can be solved -->
## ❓ Motivation
<!-- Explain why your feature should be considered -->
## ⚠ Additional context
<!-- Add any other context or screenshots about the feature request here -->

View File

@@ -33,7 +33,7 @@ jobs:
- name: Build with Gradle - name: Build with Gradle
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build clean run: ./gradlew build clean generateReadme
- name: Install Android build-tools - name: Install Android build-tools
run: sdkmanager "build-tools;32.0.0" run: sdkmanager "build-tools;32.0.0"
- name: Setup semantic-release - name: Setup semantic-release

View File

@@ -7,7 +7,11 @@
} }
], ],
"plugins": [ "plugins": [
"@semantic-release/commit-analyzer", ["@semantic-release/commit-analyzer", {
"releaseRules": [
{"type": "build", "release": "patch"}
]
}],
"@semantic-release/release-notes-generator", "@semantic-release/release-notes-generator",
"@semantic-release/changelog", "@semantic-release/changelog",
"gradle-semantic-release-plugin", "gradle-semantic-release-plugin",
@@ -15,6 +19,7 @@
"@semantic-release/git", "@semantic-release/git",
{ {
"assets": [ "assets": [
"README.md",
"CHANGELOG.md", "CHANGELOG.md",
"gradle.properties" "gradle.properties"
] ]

View File

@@ -1,3 +1,320 @@
## [2.16.1](https://github.com/revanced/revanced-patches/compare/v2.16.0...v2.16.1) (2022-07-17)
### Bug Fixes
* bump youtube version to 17.27.39 ([b93401a](https://github.com/revanced/revanced-patches/commit/b93401a391c0ed4887dd1376ac253f74f98a8d7e))
# [2.16.0](https://github.com/revanced/revanced-patches/compare/v2.15.1...v2.16.0) (2022-07-17)
### Features
* `force-vp9-codec` patch ([#157](https://github.com/revanced/revanced-patches/issues/157)) ([07806a1](https://github.com/revanced/revanced-patches/commit/07806a16e5368118949e0e476e901987433ad403))
## [2.15.1](https://github.com/revanced/revanced-patches/compare/v2.15.0...v2.15.1) (2022-07-17)
### Bug Fixes
* `old-quality-layout` patch ([2497425](https://github.com/revanced/revanced-patches/commit/2497425c9f11b8b14c861c2f0f34ff47bdbfac53))
* references to integrations in `return-youtube-dislike` patch ([5824c2c](https://github.com/revanced/revanced-patches/commit/5824c2cdfb1a2d7b8d68044388e5e0746ef2ca09))
# [2.15.0](https://github.com/revanced/revanced-patches/compare/v2.14.1...v2.15.0) (2022-07-16)
### Features
* `return-youtube-dislikes` patch ([#175](https://github.com/revanced/revanced-patches/issues/175)) ([18a66d8](https://github.com/revanced/revanced-patches/commit/18a66d8454cf6e7cfdd4183631a6870c80d16b90))
## [2.14.1](https://github.com/revanced/revanced-patches/compare/v2.14.0...v2.14.1) (2022-07-15)
### Bug Fixes
* `codecs-unlock` patch and update Music patches to `5.14.53` ([2437d30](https://github.com/revanced/revanced-patches/commit/2437d3070f6a630d353619f642cefebd47abee20))
# [2.14.0](https://github.com/revanced/revanced-patches/compare/v2.13.6...v2.14.0) (2022-07-15)
### Features
* `music-video-ads` patch ([#172](https://github.com/revanced/revanced-patches/issues/172)) ([cbb71b5](https://github.com/revanced/revanced-patches/commit/cbb71b5faf1386ed31dd9e0387f6cf0509d92d31))
## [2.13.6](https://github.com/revanced/revanced-patches/compare/v2.13.5...v2.13.6) (2022-07-14)
## [2.13.5](https://github.com/revanced/revanced-patches/compare/v2.13.4...v2.13.5) (2022-07-14)
### Bug Fixes
* `swipe-controls` with active engagement panel ([#177](https://github.com/revanced/revanced-patches/issues/177)) ([000ec6d](https://github.com/revanced/revanced-patches/commit/000ec6d8f6ecbb910a06ec852564ee9e5f03dcf8))
## [2.13.4](https://github.com/revanced/revanced-patches/compare/v2.13.3...v2.13.4) (2022-07-13)
### Bug Fixes
* constrain `old-quality-layout` to older version ([add7232](https://github.com/revanced/revanced-patches/commit/add72326199e90f677b450b553b9d88c0bb4c490))
## [2.13.3](https://github.com/revanced/revanced-patches/compare/v2.13.2...v2.13.3) (2022-07-11)
### Bug Fixes
* `exclusive-audio-playback` patch ([#153](https://github.com/revanced/revanced-patches/issues/153)) ([9beff95](https://github.com/revanced/revanced-patches/commit/9beff9567f1586e5c58690c1f1d2f7f204025ab7))
## [2.13.2](https://github.com/revanced/revanced-patches/compare/v2.13.1...v2.13.2) (2022-07-11)
### Bug Fixes
* `hrd-auto-brightness` ([#152](https://github.com/revanced/revanced-patches/issues/152)) ([5f2e9ba](https://github.com/revanced/revanced-patches/commit/5f2e9ba30b7432be04bdc9f9f7ec7ac75fdc4b34))
## [2.13.1](https://github.com/revanced/revanced-patches/compare/v2.13.0...v2.13.1) (2022-07-11)
### Bug Fixes
* bump youtube version for swipe-controls patch ([ff207a5](https://github.com/revanced/revanced-patches/commit/ff207a57af7d3c15a8127f4465e97da23878b0d6))
# [2.13.0](https://github.com/revanced/revanced-patches/compare/v2.12.4...v2.13.0) (2022-07-11)
### Features
* `swipe-controls` rewrite ([#131](https://github.com/revanced/revanced-patches/issues/131)) ([b7dba09](https://github.com/revanced/revanced-patches/commit/b7dba09927ba15a9eacb06dcb4bf1f268560c96e))
## [2.12.4](https://github.com/revanced/revanced-patches/compare/v2.12.3...v2.12.4) (2022-07-11)
### Bug Fixes
* `autorepeat-by-default` patch ([#148](https://github.com/revanced/revanced-patches/issues/148)) ([fe628ba](https://github.com/revanced/revanced-patches/commit/fe628ba909d89ea0bf3d95fe94ca78ef819677da))
## [2.12.3](https://github.com/revanced/revanced-patches/compare/v2.12.2...v2.12.3) (2022-07-11)
### Bug Fixes
* listing of wrong fingerprint class ([#147](https://github.com/revanced/revanced-patches/issues/147)) ([95c2bbd](https://github.com/revanced/revanced-patches/commit/95c2bbdd1deb1d76f1177b48286fa6a3bc9f7663))
## [2.12.2](https://github.com/revanced/revanced-patches/compare/v2.12.1...v2.12.2) (2022-07-10)
### Bug Fixes
* display codename for patch names ([10c53f7](https://github.com/revanced/revanced-patches/commit/10c53f720df3e70b9d59e8bc3219d56b996f03db))
* incorrect package name in gradle task ([152b2c9](https://github.com/revanced/revanced-patches/commit/152b2c90cf102170648fcc168da10f46743bdc63))
* invalid regex ([26bf1d8](https://github.com/revanced/revanced-patches/commit/26bf1d818f953abc061126d8b91f17cd9008ba1d))
## [2.12.1](https://github.com/revanced/revanced-patches/compare/v2.12.0...v2.12.1) (2022-07-10)
# [2.12.0](https://github.com/revanced/revanced-patches/compare/v2.11.0...v2.12.0) (2022-07-10)
### Bug Fixes
* update patches to `17.26.35` ([#142](https://github.com/revanced/revanced-patches/issues/142)) ([b04112c](https://github.com/revanced/revanced-patches/commit/b04112c8562a7b95e7555e894b665913094b33eb))
* wording [skip ci] ([ba64d9e](https://github.com/revanced/revanced-patches/commit/ba64d9efc3ee606e9bda30ad7f8017af34b1dc3f))
### Features
* issue templates ([b82b0aa](https://github.com/revanced/revanced-patches/commit/b82b0aad88b7ab9d86f1bcc8e007f6a76a9aa1a5))
# [2.11.0](https://github.com/revanced/revanced-patches/compare/v2.10.2...v2.11.0) (2022-07-09)
### Features
* `autorepeat-by-default` patch ([#106](https://github.com/revanced/revanced-patches/issues/106)) ([e0ac9f3](https://github.com/revanced/revanced-patches/commit/e0ac9f385fc360f4dd2451e26676633120356c10))
## [2.10.2](https://github.com/revanced/revanced-patches/compare/v2.10.1...v2.10.2) (2022-07-08)
### Bug Fixes
* trigger release on `build` commits ([be8bd1b](https://github.com/revanced/revanced-patches/commit/be8bd1b2a4b91f9763448661a802a5dc4a6b1d1d))
## [2.10.1](https://github.com/revanced/revanced-patches/compare/v2.10.0...v2.10.1) (2022-07-08)
### Bug Fixes
* patch description consistency ([#134](https://github.com/revanced/revanced-patches/issues/134)) ([da5896d](https://github.com/revanced/revanced-patches/commit/da5896dde0a2b2b9ffe65e486402e4ef92ec1ce9))
# [2.10.0](https://github.com/revanced/revanced-patches/compare/v2.9.4...v2.10.0) (2022-07-07)
### Features
* implement `wide-searchbar` Patch ([#130](https://github.com/revanced/revanced-patches/issues/130)) ([332f4d1](https://github.com/revanced/revanced-patches/commit/332f4d12d06316d65db252a280fe1f263e65c3a8))
## [2.9.4](https://github.com/revanced/revanced-patches/compare/v2.9.3...v2.9.4) (2022-07-06)
### Bug Fixes
* add 17.25.34 as supported version for swipe-controls patch ([4d84c19](https://github.com/revanced/revanced-patches/commit/4d84c1914f8ecf51cee25667219bc6cf635a6c1c))
## [2.9.3](https://github.com/revanced/revanced-patches/compare/v2.9.2...v2.9.3) (2022-07-06)
### Bug Fixes
* Readd `swipe-controls` patch ([#123](https://github.com/revanced/revanced-patches/issues/123)) ([7f2a2b2](https://github.com/revanced/revanced-patches/commit/7f2a2b2ee4e6045d53aba4e7705431b643981107))
## [2.9.2](https://github.com/revanced/revanced-patches/compare/v2.9.1...v2.9.2) (2022-07-05)
### Bug Fixes
* revert `swipe-controls` patch ([66e1f33](https://github.com/revanced/revanced-patches/commit/66e1f3384a58361737ba889d946be875b23f3163))
## [2.9.1](https://github.com/revanced/revanced-patches/compare/v2.9.0...v2.9.1) (2022-07-05)
### Bug Fixes
* make `minimized-playback-manager-fingerprint` unique ([#120](https://github.com/revanced/revanced-patches/issues/120)) ([cd5e911](https://github.com/revanced/revanced-patches/commit/cd5e911f4ed9ad95b02c13c30cd9466d250e8904))
# [2.9.0](https://github.com/revanced/revanced-patches/compare/v2.8.2...v2.9.0) (2022-07-05)
### Features
* `swipe-controls` patch ([#115](https://github.com/revanced/revanced-patches/issues/115)) ([1d0a7dc](https://github.com/revanced/revanced-patches/commit/1d0a7dcc0cc3ea2bcd8ce0221d5e2f53d6eb0ae5))
## [2.8.2](https://github.com/revanced/revanced-patches/compare/v2.8.1...v2.8.2) (2022-07-05)
### Bug Fixes
* show minimized playback options in settings ([#118](https://github.com/revanced/revanced-patches/issues/118)) ([6e1a538](https://github.com/revanced/revanced-patches/commit/6e1a538d34291d75f19bf66a188bc69241de3a7a))
## [2.8.1](https://github.com/revanced/revanced-patches/compare/v2.8.0...v2.8.1) (2022-07-05)
### Bug Fixes
* remove unnecessary version constraints ([#117](https://github.com/revanced/revanced-patches/issues/117)) ([1cddf8d](https://github.com/revanced/revanced-patches/commit/1cddf8d9063da3bbdba0fd7080c8c93768b83a4c))
# [2.8.0](https://github.com/revanced/revanced-patches/compare/v2.7.0...v2.8.0) (2022-07-04)
### Features
* `enable-debugging` patch ([#116](https://github.com/revanced/revanced-patches/issues/116)) ([bb355e7](https://github.com/revanced/revanced-patches/commit/bb355e7b7e78e602a10b346fe7e5795463615a81))
# [2.7.0](https://github.com/revanced/revanced-patches/compare/v2.6.0...v2.7.0) (2022-07-03)
### Features
* `hdr-max-brightness` patch ([#105](https://github.com/revanced/revanced-patches/issues/105)) ([1310573](https://github.com/revanced/revanced-patches/commit/131057366a777786d6016d3385584b4e17bc4a8b))
* `hide-infocard-suggestions` patch ([#107](https://github.com/revanced/revanced-patches/issues/107)) ([31a767a](https://github.com/revanced/revanced-patches/commit/31a767adbb152906303ab0ae5250769fc38d0625))
# [2.6.0](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.6.0) (2022-07-02)
### Bug Fixes
* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([f5d4f6c](https://github.com/revanced/revanced-patches/commit/f5d4f6c3419916c6a9cf67babc6be8a64c854d3b))
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([df43547](https://github.com/revanced/revanced-patches/commit/df435475cdd0494a1e4ea9e2980c2998c9bc7048))
* remove refreshing home screen not working ([6c24ebe](https://github.com/revanced/revanced-patches/commit/6c24ebef2fb4f0d58e369ac5bf63e4cab6ca0e80))
### Features
* migrate to breaking changes of patcher ([d9147cd](https://github.com/revanced/revanced-patches/commit/d9147cd60c0c25d0c5cc05409b8889dfacd89af9))
# [2.6.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.6.0-dev.1...v2.6.0-dev.2) (2022-07-02)
### Bug Fixes
* remove refreshing home screen not working ([ec7ae90](https://github.com/revanced/revanced-patches/commit/ec7ae900181b6456c692adb3b5bb337e81bc5fea))
# [2.6.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.1-dev.1...v2.6.0-dev.1) (2022-07-02)
### Features
* migrate to breaking changes of patcher ([a116852](https://github.com/revanced/revanced-patches/commit/a11685263fb2274c67684258e73c5247502cb010))
## [2.5.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.5.1-dev.1) (2022-06-30)
### Bug Fixes
* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([f5d4f6c](https://github.com/revanced/revanced-patches/commit/f5d4f6c3419916c6a9cf67babc6be8a64c854d3b))
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([df43547](https://github.com/revanced/revanced-patches/commit/df435475cdd0494a1e4ea9e2980c2998c9bc7048))
# [2.5.0](https://github.com/revanced/revanced-patches/compare/v2.4.0...v2.5.0) (2022-06-30)
### Features
* hide watermark support for 17.25.34 ([#87](https://github.com/revanced/revanced-patches/issues/87)) ([0cdb65b](https://github.com/revanced/revanced-patches/commit/0cdb65bbb3e7b9d75eb393ee87e3718bcd6af4b3))
# [2.4.0](https://github.com/revanced/revanced-patches/compare/v2.3.1...v2.4.0) (2022-06-30)
### Features
* add youtube version 17.25.34 ([#85](https://github.com/revanced/revanced-patches/issues/85)) ([889c9d5](https://github.com/revanced/revanced-patches/commit/889c9d564d16c6e68a52095a4fc8e6d04346c9e9))
## [2.3.1](https://github.com/revanced/revanced-patches/compare/v2.3.0...v2.3.1) (2022-06-30)
### Bug Fixes
* change fingerprint to work on latest youtube ([#80](https://github.com/revanced/revanced-patches/issues/80)) ([4dba323](https://github.com/revanced/revanced-patches/commit/4dba323ddf8980cd2b0908a0de41c4b4dea6b0d7))
# [2.3.0](https://github.com/revanced/revanced-patches/compare/v2.2.0...v2.3.0) (2022-06-30)
### Features
* `disable-autoplay-button` patch ([#79](https://github.com/revanced/revanced-patches/issues/79)) ([0d6fb51](https://github.com/revanced/revanced-patches/commit/0d6fb51e025649aae37e230778ea367482fab0d7))
# [2.2.0](https://github.com/revanced/revanced-patches/compare/v2.1.0...v2.2.0) (2022-06-29)
### Features
* make resource mapping patch aware of types ([#77](https://github.com/revanced/revanced-patches/issues/77)) ([188491a](https://github.com/revanced/revanced-patches/commit/188491a707abccc1164413f075d8a66c145a1455))
# [2.1.0](https://github.com/revanced/revanced-patches/compare/v2.0.3...v2.1.0) (2022-06-28)
### Features
* `custom-playback-speed` patch ([#50](https://github.com/revanced/revanced-patches/issues/50)) ([224254b](https://github.com/revanced/revanced-patches/commit/224254bcce2b394bbfd2549089f0204ce4ed4a89))
## [2.0.3](https://github.com/revanced/revanced-patches/compare/v2.0.2...v2.0.3) (2022-06-27)
### Bug Fixes
* check if resource files exist ([ba1f3af](https://github.com/revanced/revanced-patches/commit/ba1f3af99be58edc44ed1b8f1875508d5034efd8))
## [2.0.2](https://github.com/revanced/revanced-patches/compare/v2.0.1...v2.0.2) (2022-06-27)
### Bug Fixes
* some more refactoring of integrations, add hide-watermark patch ([#63](https://github.com/revanced/revanced-patches/issues/63)) ([feb09c5](https://github.com/revanced/revanced-patches/commit/feb09c56f475e2537a67d3636b08737848158a8e))
## [2.0.1](https://github.com/revanced/revanced-patches/compare/v2.0.0...v2.0.1) (2022-06-26)
### Bug Fixes
* invalid string in strings list ([f08b53b](https://github.com/revanced/revanced-patches/commit/f08b53b07d93bd8ac6e7da376ea6e6023e53076e))
* migrate to new `proxy` api ([db32ffe](https://github.com/revanced/revanced-patches/commit/db32ffe56a8e73177bef724ee10eda9a28b367b8))
# [2.0.0](https://github.com/revanced/revanced-patches/compare/v1.11.0...v2.0.0) (2022-06-26) # [2.0.0](https://github.com/revanced/revanced-patches/compare/v1.11.0...v2.0.0) (2022-06-26)

9
README-template.md Normal file
View File

@@ -0,0 +1,9 @@
# ReVanced Patches
🧩 Official patches by ReVanced
# List of available patches
| 💊 Patch | 📜 Description | 🎯 Target Package | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|:-----------------:|
{{ table }}

View File

@@ -1 +1,39 @@
Repo for all ReVanced patches # ReVanced Patches
🧩 Official patches by ReVanced
# List of available patches
| 💊 Patch | 📜 Description | 🎯 Target Package | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|:-----------------:|
| `music-video-ads` | Removes ads in the music player. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `exclusive-audio-playback` | Enables the option to play music without video. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `background-play` | Enables playing music in the background. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `hide-infocard-suggestions` | Hides infocards in videos. | `com.google.android.youtube` | 17.27.39 |
| `video-ads` | Removes ads in the video player. | `com.google.android.youtube` | 17.27.39 |
| `general-ads` | Removes general ads. | `com.google.android.youtube` | 17.27.39 |
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | `com.google.android.youtube` | 17.27.39 |
| `swipe-controls` | Adds volume and brightness swipe controls. | `com.google.android.youtube` | 17.27.39 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG | `com.google.android.youtube` | 17.27.39 |
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | `com.google.android.youtube` | 17.27.39 |
| `autorepeat-by-default` | Enables auto repeating of videos by default. | `com.google.android.youtube` | 17.27.39 |
| `custom-playback-speed` | Adds more video playback speed options. | `com.google.android.youtube` | 17.27.39 |
| `enable-debugging` | Enables app debugging by patching the manifest file. | `com.google.android.youtube` | all |
| `force-vp9-codec` | Forces the VP9 codec for videos. | `com.google.android.youtube` | 17.27.39 |
| `old-quality-layout` | Enables the original quality flyout menu. | `com.google.android.youtube` | 17.27.39 |
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | `com.google.android.youtube` | 17.27.39 |
| `hide-cast-button` | Hides the cast button in the video player. | `com.google.android.youtube` | all |
| `amoled` | Enables pure black theme. | `com.google.android.youtube` | 17.27.39 |
| `hide-autoplay-button` | Hides the autoplay button in the video player. | `com.google.android.youtube` | 17.27.39 |
| `minimized-playback` | Enables minimized and background playback. | `com.google.android.youtube` | 17.27.39 |
| `premium-heading` | Shows premium branding on the home screen. | `com.google.android.youtube` | all |
| `custom-branding` | Changes the YouTube launcher icon to be ReVanced's. | `com.google.android.youtube` | all |
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | `com.google.android.youtube` | 17.27.39 |
| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | `com.google.android.youtube` | 17.27.39 |
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | `com.google.android.youtube` | 17.27.39 |
| `disable-create-button` | Hides the create button in the navigation bar. | `com.google.android.youtube` | 17.27.39 |
| `hide-watermark` | Hides creator's watermarks on videos. | `com.google.android.youtube` | 17.27.39 |

View File

@@ -22,7 +22,7 @@ repositories {
dependencies { dependencies {
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
implementation("app.revanced:revanced-patcher:2.0.0") implementation("app.revanced:revanced-patcher:2.4.0")
implementation("app.revanced:multidexlib2:2.5.2.r2") implementation("app.revanced:multidexlib2:2.5.2.r2")
} }
@@ -49,12 +49,19 @@ tasks {
} }
} }
} }
register<JavaExec>("generateReadme") {
description = "Generate README.md"
dependsOn(build)
classpath = sourceSets["main"].runtimeClasspath
mainClass.set("app.revanced.meta.readme.Generator")
}
// Dummy task to fix the Gradle semantic-release plugin. // Dummy task to fix the Gradle semantic-release plugin.
// Remove this if you forked it to support building only. // Remove this if you forked it to support building only.
// Tracking issue: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435 // Tracking issue: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
register<DefaultTask>("publish") { register<DefaultTask>("publish") {
group = "publish" group = "publish"
description = "Dummy task" description = "Dummy task"
dependsOn(named("generateDex")) dependsOn(named("generateDex"), named("generateReadme"))
} }
} }

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.0.0 version = 2.16.1

View File

@@ -1,9 +1,23 @@
package app.revanced.extensions package app.revanced.extensions
import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.toInstruction import app.revanced.patcher.util.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.MutableMethodImplementation import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.builder.instruction.BuilderInstruction11n
import org.jf.dexlib2.builder.instruction.BuilderInstruction11x
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
import org.w3c.dom.Node import org.w3c.dom.Node
import java.io.OutputStream
import java.nio.file.Files
// TODO: this method does not make sense here
internal fun MutableMethodImplementation.injectHideCall( internal fun MutableMethodImplementation.injectHideCall(
index: Int, index: Int,
register: Int register: Int
@@ -14,6 +28,143 @@ internal fun MutableMethodImplementation.injectHideCall(
) )
} }
/**
* Insert an event hook at the top of the method. If the hook returns true, the event is consumed and the method will return with true
*
* the hook method MUST return a boolean and MUST take two parameters, like so:
* fun hook(thisRef: Object, eventData: Object): Boolean {}
*
* The final injected code will resemble the following logic:
* if( YouHook(this, event) ) { return true; }
* ...
*
* @param hookRef reference to the hook method
*/
internal fun MutableMethod.injectConsumableEventHook(hookRef: ImmutableMethodReference) {
val isStaticMethod = AccessFlags.STATIC.isSet(this.accessFlags)
this.implementation?.let { impl ->
// create label to index 0 to continue to the normal program flow
val lblContinueNormalFlow = impl.newLabelForIndex(0)
// define registers
/** V0 */
val regV0 = 0
/** this */
val regP0 = impl.registerCount - this.parameters.size - (if (isStaticMethod) 0 else 1)
/** motionEvent */
val regP1 = regP0 + 1
// insert instructions at the start of the method:
// if( Hook(this, event) ) { return true; }
impl.addInstructions(
0, listOf(
// invoke-static { p0, p1 } <hook>
BuilderInstruction35c(
Opcode.INVOKE_STATIC,
2,
regP0,
regP1,
0, 0, 0,
hookRef
),
// move-result v0
BuilderInstruction11x(
Opcode.MOVE_RESULT,
regV0
),
// if-eqz v0, :continue_normal_flow
BuilderInstruction21t(
Opcode.IF_EQZ,
regV0,
lblContinueNormalFlow
),
// const/4 v0, 0x1
BuilderInstruction11n(
Opcode.CONST_4,
regV0,
0x1
),
// return v0
BuilderInstruction11x(
Opcode.RETURN,
regV0
)
// :continue_normal_flow
)
)
}
}
/**
* inject resources into the patched app
*
* @param classLoader classloader to use for loading the resources
* @param patchDirectoryPath path to the files. this will be the directory you created under the 'resources' source folder
* @param resourceType the resource type, for example 'drawable'. this has to match both the source and the target
* @param resourceFileNames names of all resources of this type to inject
*/
fun ResourceData.injectResources(
classLoader: ClassLoader,
patchDirectoryPath: String,
resourceType: String,
resourceFileNames: List<String>
) {
resourceFileNames.forEach { name ->
val relativePath = "$resourceType/$name"
val sourceRes = classLoader.getResourceAsStream("$patchDirectoryPath/$relativePath")
?: throw PatchResultError("could not open resource '$patchDirectoryPath/$relativePath'")
Files.copy(
sourceRes,
this["res"].resolve(relativePath).toPath()
)
}
}
/**
* inject strings into the patched app
*
* @param classLoader classloader to use for loading the resources
* @param patchDirectoryPath path to the files. this will be the directory you created under the 'resources' source folder
* @param languageIdentifier ISO 639-2 two- letter language code identifier (aka the one android uses for values directory)
*/
fun ResourceData.injectStrings(
classLoader: ClassLoader,
patchDirectoryPath: String,
languageIdentifier: String? = null,
) {
val relativePath =
if (languageIdentifier.isNullOrBlank()) "values/strings.xml" else "values/strings-$languageIdentifier.xml"
// open source strings.xml
val sourceInputStream = classLoader.getResourceAsStream("$patchDirectoryPath/$relativePath")
?: throw PatchResultError("failed to open '$patchDirectoryPath/$relativePath'")
xmlEditor[sourceInputStream, OutputStream.nullOutputStream()].use { sourceStringsXml ->
val strings = sourceStringsXml.file.getElementsByTagName("resources").item(0).childNodes
// open target strings.xml
xmlEditor["res/$relativePath"].use { targetStringsXml ->
val targetFile = targetStringsXml.file
val targetRootNode = targetFile.getElementsByTagName("resources").item(0)
// process all children strings in the source
for (i in 0 until strings.length) {
// clone the node from source to target
val node = strings.item(i).cloneNode(true)
targetFile.adoptNode(node)
targetRootNode.appendChild(node)
}
}
}
}
internal fun Node.doRecursively(action: (Node) -> Unit) { internal fun Node.doRecursively(action: (Node) -> Unit) {
action(this) action(this)
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action) for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)

View File

@@ -0,0 +1,41 @@
package app.revanced.meta.readme
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.description
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.util.patch.implementation.JarPatchBundle
import java.io.File
class Generator {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val buildDir = File("build/libs/")
val buildJar =
buildDir.listFiles()?.first { it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar") }!!
val bundle = JarPatchBundle(buildJar.absolutePath).loadPatches()
val patches = StringBuilder()
for (patch in bundle) {
val patchName = patch.patchName
val compatiblePackage = patch.compatiblePackages?.first()
val latestVersion =
compatiblePackage?.versions?.map { SemanticVersion.fromString(it) }?.maxWithOrNull(
SemanticVersionComparator
) ?: "all"
patches.appendLine("| `$patchName` | ${patch.description} | `${compatiblePackage?.name}` | $latestVersion |")
}
val readMeTemplateFile = File("README-template.md")
val readmeTemplate = Template(readMeTemplateFile.readText())
readmeTemplate.replaceVariable("table", patches.toString())
val readme = File("README.md")
readme.writeText(readmeTemplate.toString())
}
}
}

View File

@@ -0,0 +1,24 @@
package app.revanced.meta.readme
data class SemanticVersion(val major: Int, val minor: Int, val patch: Int) {
companion object {
fun fromString(version: String): SemanticVersion {
var parts = version.split(".")
if (parts.count() != 3) throw IllegalArgumentException("Invalid semantic version")
val versionNumbers = parts.map { it.toInt() }
return SemanticVersion(versionNumbers[0], versionNumbers[1], versionNumbers[2])
}
}
override fun toString(): String = "$major.$minor.$patch"
}
object SemanticVersionComparator : Comparator<SemanticVersion> {
override fun compare(a: SemanticVersion, b: SemanticVersion): Int = when {
a.major != b.major -> a.major - b.major
a.minor != b.minor -> a.minor - b.minor
else -> a.patch - b.patch
}
}

View File

@@ -0,0 +1,14 @@
package app.revanced.meta.readme
class Template(template: String) {
val result: StringBuilder = StringBuilder(template)
fun replaceVariable(name: String, value: String) {
val regex = Regex("\\{\\{\\s?$name\\s?}}")
val range = regex.find(result)!!.range
result.replace(range.first, range.last + 1, value)
}
override fun toString(): String = result.toString()
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.music.ad.video.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class MusicVideoAdsCompatibility

View File

@@ -0,0 +1,39 @@
package app.revanced.patches.music.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.music.ad.video.annotations.MusicVideoAdsCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("show-video-ads-constructor-fingerprint")
@MatchingMethod(
"Laghd;",
"<init>",
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@MusicVideoAdsCompatibility
@Version("0.0.1")
object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf(
Opcode.INVOKE_DIRECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.CONST_4,
Opcode.IPUT_BOOLEAN,
Opcode.RETURN_VOID
)
)

View File

@@ -0,0 +1,26 @@
package app.revanced.patches.music.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.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.music.ad.video.annotations.MusicVideoAdsCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("show-video-ads-method-fingerprint")
@MatchingMethod(
"Laghd;", "d"
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@MusicVideoAdsCompatibility
@Version("0.0.1")
object ShowMusicVideoAdsFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), listOf(
Opcode.IPUT_BOOLEAN,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
)
)

View File

@@ -0,0 +1,40 @@
package app.revanced.patches.music.ad.video.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.music.ad.video.annotations.MusicVideoAdsCompatibility
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsConstructorFingerprint
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerprint
@Patch
@Name("music-video-ads")
@Description("Removes ads in the music player.")
@MusicVideoAdsCompatibility
@Version("0.0.1")
class MusicVideoAdsPatch : BytecodePatch(
listOf(
ShowMusicVideoAdsConstructorFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
ShowMusicVideoAdsFingerprint.resolve(data, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef)
val result = ShowMusicVideoAdsFingerprint.result!!
result.mutableMethod.addInstructions(
result.patternScanResult!!.startIndex, """
const/4 p1, 0x0
"""
)
return PatchResultSuccess()
}
}

View File

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

View File

@@ -20,8 +20,9 @@ import org.jf.dexlib2.Opcode
@Version("0.0.1") @Version("0.0.1")
object CodecsLockFingerprint : MethodFingerprint( object CodecsLockFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf( "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_STATIC, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
@@ -29,18 +30,11 @@ object CodecsLockFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.SGET, Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.RETURN_OBJECT Opcode.RETURN_OBJECT
) )

View File

@@ -16,7 +16,7 @@ import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprin
@Patch @Patch
@Name("codecs-unlock") @Name("codecs-unlock")
@Description("Enables more audio codecs. Usually results in better audio quality but may depend on song and device.") @Description("Adds more audio codec options. The new audio codecs usually result in better audio quality.")
@CodecsUnlockCompatibility @CodecsUnlockCompatibility
@Version("0.0.1") @Version("0.0.1")
class CodecsUnlockPatch : BytecodePatch( class CodecsUnlockPatch : BytecodePatch(

View File

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

View File

@@ -1,3 +1,5 @@
package app.revanced.patches.music.audio.exclusiveaudio.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.music.audio.exclusiveaudio.patch package app.revanced.patches.music.audio.exclusiveaudio.patch
import AudioOnlyEnablerFingerprint
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
@@ -13,22 +12,21 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AudioOnlyEnablerFingerprint
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.ExclusiveAudioFingerprint import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.ExclusiveAudioFingerprint
@Patch @Patch
@Name("exclusive-audio-playback") @Name("exclusive-audio-playback")
@Description("Add the option to play music without video.") @Description("Enables the option to play music without video.")
@ExclusiveAudioCompatibility @ExclusiveAudioCompatibility
@Version("0.0.1") @Version("0.0.1")
class ExclusiveAudioPatch : BytecodePatch( class ExclusiveAudioPatch : BytecodePatch(
listOf( listOf(
ExclusiveAudioFingerprint AudioOnlyEnablerFingerprint
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
ExclusiveAudioFingerprint.resolve(data, AudioOnlyEnablerFingerprint.result!!.classDef) val method = AudioOnlyEnablerFingerprint.result!!.mutableMethod
val method = ExclusiveAudioFingerprint.result!!.mutableMethod
method.replaceInstruction(method.implementation!!.instructions.count() - 1, "const/4 v0, 0x1") method.replaceInstruction(method.implementation!!.instructions.count() - 1, "const/4 v0, 0x1")
method.addInstruction("return v0") method.addInstruction("return v0")

View File

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

View File

@@ -15,7 +15,7 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction22c
@Patch @Patch
@Name("tasteBuilder-remover") @Name("tasteBuilder-remover")
@Description("Removes the \"Tell us which artists you like\" card from the Home screen. The same functionality can be triggered from the settings anyway.") @Description("Removes the \"Tell us which artists you like\" card from the home screen.")
@RemoveTasteBuilderCompatibility @RemoveTasteBuilderCompatibility
@Version("0.0.1") @Version("0.0.1")
class RemoveTasteBuilderPatch : BytecodePatch( class RemoveTasteBuilderPatch : BytecodePatch(

View File

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

View File

@@ -20,7 +20,7 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch @Patch
@Name("upgrade-button-remover") @Name("upgrade-button-remover")
@Description("Remove the upgrade tab from the pivot bar in YouTube music.") @Description("Removes the upgrade tab from the pivot bar.")
@RemoveUpgradeButtonCompatibility @RemoveUpgradeButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class RemoveUpgradeButtonPatch : BytecodePatch( class RemoveUpgradeButtonPatch : BytecodePatch(

View File

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

View File

@@ -14,7 +14,7 @@ import app.revanced.patches.music.premium.backgroundplay.fingerprints.Background
@Patch @Patch
@Name("background-play") @Name("background-play")
@Description("Enable playing music in the background.") @Description("Enables playing music in the background.")
@BackgroundPlayCompatibility @BackgroundPlayCompatibility
@Version("0.0.1") @Version("0.0.1")
class BackgroundPlayPatch : BytecodePatch( class BackgroundPlayPatch : BytecodePatch(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -5,14 +5,13 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.proxy
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.toInstructions import app.revanced.patcher.util.smali.toInstructions
@@ -22,7 +21,6 @@ import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensi
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.insertBlocks import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.insertBlocks
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.toDescriptor import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.toDescriptor
import app.revanced.patches.youtube.ad.general.bytecode.utils.MethodUtils.createMutableMethod import app.revanced.patches.youtube.ad.general.bytecode.utils.MethodUtils.createMutableMethod
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralResourceAdsPatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
@@ -40,16 +38,12 @@ import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
@Patch @Patch
@Dependencies( @Dependencies([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class])
dependencies = [ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class, GeneralResourceAdsPatch::class]
)
@Name("general-ads") @Name("general-ads")
@Description("Patch to remove general ads in bytecode.") @Description("Removes general ads.")
@GeneralAdsCompatibility @GeneralAdsCompatibility
@Version("0.0.1") @Version("0.0.1")
class GeneralBytecodeAdsPatch : BytecodePatch( class GeneralBytecodeAdsPatch : BytecodePatch() {
listOf()
) {
// a constant used by litho // a constant used by litho
private val lithoConstant = 0xaed2868 private val lithoConstant = 0xaed2868
@@ -63,8 +57,8 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
"endscreen_element_layout_icon", "endscreen_element_layout_icon",
"promoted_video_item_land", "promoted_video_item_land",
"promoted_video_item_full_bleed", "promoted_video_item_full_bleed",
).map { ).map { name ->
ResourceIdMappingProviderResourcePatch.resourceMappings[it]!! ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.name == name }.id
} }
private val stringReferences = arrayOf( private val stringReferences = arrayOf(
@@ -245,20 +239,20 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
val block1 = """ val block1 = """
invoke-static/range {p3}, $thisType->getTemplateName($templateNameParameterType)Ljava/lang/String; invoke-static/range {p3}, $thisType->getTemplateName($templateNameParameterType)Ljava/lang/String;
move-result-object v0 move-result-object v0
""".trimIndent().toInstructions(lithoMethod) """.toInstructions(lithoMethod)
val block2 = """ val block2 = """
move-object/from16 v1, p3 move-object/from16 v1, p3
iget-object v2, v1, $templateNameParameterType->b:Ljava/nio/ByteBuffer; iget-object v2, v1, $templateNameParameterType->b:Ljava/nio/ByteBuffer;
invoke-static {v0, v2}, Lapp/revanced/integrations/patches/GeneralBytecodeAdsPatch;->containsAd(Ljava/lang/String;Ljava/nio/ByteBuffer;)Z invoke-static {v0, v2}, Lapp/revanced/integrations/patches/GeneralBytecodeAdsPatch;->containsAd(Ljava/lang/String;Ljava/nio/ByteBuffer;)Z
move-result v1 move-result v1
""".trimIndent().toInstructions(lithoMethod) """.toInstructions(lithoMethod)
val block3 = """ val block3 = """
move-object/from16 v2, p1 move-object/from16 v2, p1
invoke-static {v2}, $descriptor1 invoke-static {v2}, $descriptor1
move-result-object v0 move-result-object v0
iget-object v0, v0, $descriptor2 iget-object v0, v0, $descriptor2
return-object v0 return-object v0
""".trimIndent().toInstructions(lithoMethod) """.toInstructions(lithoMethod)
// insert blocks and branch instructions // insert blocks and branch instructions
lithoMethodImplementation.insertBlocks( lithoMethodImplementation.insertBlocks(
@@ -369,7 +363,7 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
const v0, $lithoConstant const v0, $lithoConstant
invoke-static {p0, v0}, ${descriptors[1]} invoke-static {p0, v0}, ${descriptors[1]}
move-result-object p0 move-result-object p0
""".trimIndent().toInstructions() """.toInstructions()
val block2 = """ val block2 = """
invoke-static {p0}, ${descriptors[2]} invoke-static {p0}, ${descriptors[2]}
move-result-object p0 move-result-object p0
@@ -377,12 +371,12 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
move-result-object v0 move-result-object v0
invoke-static {v0}, ${this.type}->getIsEmpty(Ljava/lang/String;)Z invoke-static {v0}, ${this.type}->getIsEmpty(Ljava/lang/String;)Z
move-result v0 move-result v0
""".trimIndent().toInstructions() """.toInstructions()
val block3 = """ val block3 = """
invoke-virtual {p0}, ${descriptors[3]} invoke-virtual {p0}, ${descriptors[3]}
move-result-object p0 move-result-object p0
return-object p0 return-object p0
""".trimIndent().toInstructions() """.toInstructions()
// create target instruction // create target instruction
val targetInstruction = BuilderInstruction11n(Opcode.CONST_4, 1, 0) val targetInstruction = BuilderInstruction11n(Opcode.CONST_4, 1, 0)

View File

@@ -1,60 +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.impl.ResourceData
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import org.w3c.dom.Element
@Dependencies(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_video_item.xml",
"inline_muted_metadata_swap.xml",
"interstitial_promo_view.xml",
"pip_ad_overlay.xml",
"promoted_",
"watch_metadata_companion_cards.xml",
//"watch_while_activity.xml" // FIXME: find out why patching this resource fails
)
// the attributes to change the value of
private val replacements = arrayOf(
"height",
"width",
"marginTop",
)
override fun execute(data: ResourceData): PatchResult {
data.forEach {
if (!it.name.startsWithAny(*resourceFileNames)) return@forEach
// for each file in the "layouts" directory replace all necessary attributes content
data.getXmlEditor(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()
}
}

View File

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

View File

@@ -0,0 +1,24 @@
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.annotation.MatchingMethod
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")
@MatchingMethod("Liff;", "i")
@FuzzyPatternScanMethod(2)
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
object HideInfocardSuggestionsFingerprint : MethodFingerprint(
"Ljava/lang/Boolean;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
null,
listOf("vibrator"),
null
)

View File

@@ -0,0 +1,24 @@
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.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("hide-infocard-suggestions-parent-fingerprint")
@MatchingMethod("Liff;", "lE")
@FuzzyPatternScanMethod(2)
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
object HideInfocardSuggestionsParentFingerprint : MethodFingerprint(
"Ljava/lang/String;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
null,
listOf("player_overlay_info_card_teaser"),
null
)

View File

@@ -0,0 +1,63 @@
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.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
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 org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch
@Dependencies([IntegrationsPatch::class])
@Name("hide-infocard-suggestions")
@Description("Hides infocards in videos.")
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
class HideInfocardSuggestionsPatch : BytecodePatch(
listOf(
HideInfocardSuggestionsParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val parentResult = HideInfocardSuggestionsParentFingerprint.result
?: return PatchResultError("Parent fingerprint not resolved!")
HideInfocardSuggestionsFingerprint.resolve(data, 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") }
val register = "v" + (implementation.instructions.get(index) as FiveRegisterInstruction).registerD
method.removeInstruction(index)
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/HideInfoCardSuggestionsPatch;->hideInfoCardSuggestions()I
move-result $register
invoke-virtual {p1, $register}, Landroid/view/View;->setVisibility(I)V
"""
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -1,3 +1,5 @@
package app.revanced.patches.youtube.ad.video.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.ad.video.patch package app.revanced.patches.youtube.ad.video.patch
import ShowVideoAdsFingerprint
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
@@ -14,12 +13,13 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsConstructorFingerprint import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsConstructorFingerprint
import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch @Patch
@Dependencies(dependencies = [IntegrationsPatch::class]) @Dependencies([IntegrationsPatch::class])
@Name("video-ads") @Name("video-ads")
@Description("Patch to remove ads in the YouTube video player.") @Description("Removes ads in the video player.")
@VideoAdsCompatibility @VideoAdsCompatibility
@Version("0.0.1") @Version("0.0.1")
class VideoAdsPatch : BytecodePatch( class VideoAdsPatch : BytecodePatch(
@@ -40,4 +40,4 @@ class VideoAdsPatch : BytecodePatch(
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -22,9 +22,9 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction11n
import org.jf.dexlib2.iface.instruction.formats.Instruction35c import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch @Patch
@Dependencies(dependencies = [IntegrationsPatch::class]) @Dependencies([IntegrationsPatch::class])
@Name("seekbar-tapping") @Name("seekbar-tapping")
@Description("Enable tapping on the seekbar of the YouTube player.") @Description("Enables tap-to-seek on the seekbar of the video player.")
@SeekbarTappingCompatibility @SeekbarTappingCompatibility
@Version("0.0.1") @Version("0.0.1")
class EnableSeekbarTappingPatch : BytecodePatch( class EnableSeekbarTappingPatch : BytecodePatch(
@@ -92,4 +92,4 @@ class EnableSeekbarTappingPatch : BytecodePatch(
) )
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.interaction.swipecontrols.annotation
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class SwipeControlsCompatibility

View File

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

View File

@@ -0,0 +1,45 @@
package app.revanced.patches.youtube.interaction.swipecontrols.patch.bytecode
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.WatchWhileOnStartFingerprint
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.playeroverlay.patch.PlayerOverlaysHookPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
@Patch
@Name("swipe-controls")
@Description("Adds volume and brightness swipe controls.")
@SwipeControlsCompatibility
@Version("0.0.2")
@Dependencies(
[
IntegrationsPatch::class,
PlayerTypeHookPatch::class,
PlayerOverlaysHookPatch::class,
SwipeControlsResourcePatch::class
]
)
class SwipeControlsBytecodePatch : BytecodePatch(
listOf(
WatchWhileOnStartFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
WatchWhileOnStartFingerprint.result!!.mutableMethod.addInstruction(
0,
"invoke-static { p0 }, Lapp/revanced/integrations/patches/SwipeControlsPatch;->WatchWhileActivity_onStartHookEX(Ljava/lang/Object;)V"
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,32 @@
package app.revanced.patches.youtube.interaction.swipecontrols.patch.resource
import app.revanced.extensions.injectResources
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
@Name("swipe-controls-resource-patch")
@SwipeControlsCompatibility
@Version("0.0.1")
class SwipeControlsResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult {
val resourcesDir = "swipecontrols"
data.injectResources(
this.javaClass.classLoader,
resourcesDir,
"drawable",
listOf(
"ic_sc_brightness_auto",
"ic_sc_brightness_manual",
"ic_sc_volume_mute",
"ic_sc_volume_normal"
).map { "$it.xml" }
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -4,29 +4,25 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import org.w3c.dom.Element import org.w3c.dom.Element
import java.io.File import java.io.File
@Patch @Patch
@Dependencies( @Dependencies([FixLocaleConfigErrorPatch::class])
dependencies = [
FixLocaleConfigErrorPatch::class
]
)
@Name("amoled") @Name("amoled")
@Description("Enables pure black theme.") @Description("Enables pure black theme.")
@AmoledCompatibility @AmoledCompatibility
@Version("0.0.1") @Version("0.0.1")
class AmoledPatch : ResourcePatch() { class AmoledPatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult { override fun execute(data: ResourceData): PatchResult {
data.getXmlEditor("res${File.separator}values${File.separator}colors.xml").use { editor -> data.xmlEditor["res${File.separator}values${File.separator}colors.xml"].use { editor ->
val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element
for (i in 0 until resourcesNode.childNodes.length) { for (i in 0 until resourcesNode.childNodes.length) {

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.autoplaybutton.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")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class AutoplayButtonCompatibility

View File

@@ -0,0 +1,34 @@
package app.revanced.patches.youtube.layout.autoplaybutton.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("autonav-informer-fingerprint")
@MatchingMethod(
"LWillAutonavInformer;", "k"
)
@FuzzyPatternScanMethod(2)
@AutoplayButtonCompatibility
@Version("0.0.1")
object AutonavInformerFingerprint : MethodFingerprint(
"Z",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
),
null,
{ it.definingClass.endsWith("WillAutonavInformer;") }
)

View File

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

View File

@@ -0,0 +1,61 @@
package app.revanced.patches.youtube.layout.autoplaybutton.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.removeInstructions
import app.revanced.patcher.extensions.replaceInstructions
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.AutonavInformerFingerprint
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Patch
@Dependencies([ResourceIdMappingProviderResourcePatch::class])
@Name("hide-autoplay-button")
@Description("Hides the autoplay button in the video player.")
@AutoplayButtonCompatibility
@Version("0.0.1")
class HideAutoplayButton : BytecodePatch(
listOf(
LayoutConstructorFingerprint, AutonavInformerFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val layoutGenMethod = LayoutConstructorFingerprint.result!!.mutableMethod
val autonavToggle =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "autonav_toggle" }
val autonavPreviewStub =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "autonav_preview_stub" }
val autonavToggleConstIndex =
layoutGenMethod.implementation!!.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavToggle.id }
val autonavPreviewStubConstIndex =
layoutGenMethod.implementation!!.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavPreviewStub.id }
//remove adding autoplay button to the layout
layoutGenMethod.removeInstructions(autonavToggleConstIndex, 5)
layoutGenMethod.removeInstructions(autonavPreviewStubConstIndex, 5)
val autonavInformerMethod = AutonavInformerFingerprint.result!!.mutableMethod
//force disable autoplay since it's hard to do without the button
autonavInformerMethod.replaceInstructions(
0,
"""
const/4 v0, 0x0
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -4,28 +4,27 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
import kotlin.io.path.exists
@Patch @Patch
@Dependencies( @Dependencies([FixLocaleConfigErrorPatch::class])
dependencies = [FixLocaleConfigErrorPatch::class]
)
@Name("premium-heading") @Name("premium-heading")
@Description("Show the premium branding on the the YouTube home screen.") @Description("Shows premium branding on the home screen.")
@PremiumHeadingCompatibility @PremiumHeadingCompatibility
@Version("0.0.1") @Version("0.0.1")
class PremiumHeadingPatch : ResourcePatch() { class PremiumHeadingPatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult { override fun execute(data: ResourceData): PatchResult {
val resDirectory = data.get("res") val resDirectory = data["res"]
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.") if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
val (original, replacement) = "yt_premium_wordmark_header" to "yt_wordmark_header" val (original, replacement) = "yt_premium_wordmark_header" to "yt_wordmark_header"
@@ -33,10 +32,15 @@ class PremiumHeadingPatch : ResourcePatch() {
arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi").forEach { size -> arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi").forEach { size ->
val headingDirectory = resDirectory.resolve("drawable-$size") val headingDirectory = resDirectory.resolve("drawable-$size")
modes.forEach {mode -> modes.forEach { mode ->
val fromPath = headingDirectory.resolve("${original}_$mode.png").toPath()
val toPath = headingDirectory.resolve("${replacement}_$mode.png").toPath()
if (!fromPath.exists())
return PatchResultError("The file $fromPath does not exist in the resources. Therefore, this patch can not succeed.")
Files.copy( Files.copy(
headingDirectory.resolve("${original}_$mode.png").toPath(), fromPath,
headingDirectory.resolve("${replacement}_$mode.png").toPath(), toPath,
StandardCopyOption.REPLACE_EXISTING StandardCopyOption.REPLACE_EXISTING
) )
} }

View File

@@ -4,27 +4,25 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import java.nio.file.Files import java.nio.file.Files
@Patch @Patch
@Dependencies( @Dependencies([FixLocaleConfigErrorPatch::class])
dependencies = [FixLocaleConfigErrorPatch::class]
)
@Name("custom-branding") @Name("custom-branding")
@Description("Change the branding of YouTube.") @Description("Changes the YouTube launcher icon to be ReVanced's.")
@CustomBrandingCompatibility @CustomBrandingCompatibility
@Version("0.0.1") @Version("0.0.1")
class CustomBrandingPatch : ResourcePatch() { class CustomBrandingPatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult { override fun execute(data: ResourceData): PatchResult {
val resDirectory = data.get("res") val resDirectory = data["res"]
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.") if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
val iconNames = arrayOf( val iconNames = arrayOf(

View File

@@ -4,7 +4,6 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.proxy
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
@@ -15,12 +14,12 @@ import app.revanced.patches.youtube.layout.castbutton.annotations.CastButtonComp
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch @Patch
@Dependencies(dependencies = [IntegrationsPatch::class]) @Dependencies([IntegrationsPatch::class])
@Name("hide-cast-button") @Name("hide-cast-button")
@Description("Patch to hide the cast button.") @Description("Hides the cast button in the video player.")
@CastButtonCompatibility @CastButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideCastButtonPatch : BytecodePatch(listOf()) { class HideCastButtonPatch : BytecodePatch() {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
data.classes.forEach { classDef -> data.classes.forEach { classDef ->
classDef.methods.forEach { method -> classDef.methods.forEach { method ->

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -22,9 +22,9 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Dependencies(dependencies = [IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class]) @Dependencies([IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class])
@Name("disable-create-button") @Name("disable-create-button")
@Description("Disable the create button.") @Description("Hides the create button in the navigation bar.")
@CreateButtonCompatibility @CreateButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class CreateButtonRemoverPatch : BytecodePatch( class CreateButtonRemoverPatch : BytecodePatch(
@@ -38,11 +38,11 @@ class CreateButtonRemoverPatch : BytecodePatch(
// Get the required register which holds the view object we need to pass to the method hideCreateButton // Get the required register which holds the view object we need to pass to the method hideCreateButton
val implementation = result.mutableMethod.implementation!! val implementation = result.mutableMethod.implementation!!
val imageOnlyLayout = ResourceIdMappingProviderResourcePatch.resourceMappings["image_only_tab"] val imageOnlyLayout =
?: return PatchResultError("Required resource could not be found in the map") ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "layout" && it.name == "image_only_tab" }
val imageOnlyLayoutConstIndex = val imageOnlyLayoutConstIndex =
implementation.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == imageOnlyLayout } implementation.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == imageOnlyLayout.id }
val (instructionIndex, instruction) = implementation.instructions.drop(imageOnlyLayoutConstIndex).withIndex() val (instructionIndex, instruction) = implementation.instructions.drop(imageOnlyLayoutConstIndex).withIndex()
.first { .first {
@@ -63,4 +63,4 @@ class CreateButtonRemoverPatch : BytecodePatch(
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -0,0 +1,32 @@
package app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility
import org.jf.dexlib2.Opcode
@Name("fullscreen-view-adder-fingerprint")
@MatchingMethod(
"LFullscreenEngagementPanelOverlay;", "e"
)
@FuzzyPatternScanMethod(2)
@ShortsButtonCompatibility
@Version("0.0.1")
object FullscreenViewAdderFingerprint : MethodFingerprint(
null,
null,
listOf("L", "L"),
listOf(
Opcode.GOTO,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQ,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
),
null,
{ it.definingClass.endsWith("FullscreenEngagementPanelOverlay;") }
)

View File

@@ -4,32 +4,47 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.proxy import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.fullscreenpanels.annotations.FullscreenPanelsCompatibility import app.revanced.patches.youtube.layout.fullscreenpanels.annotations.FullscreenPanelsCompatibility
import app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints.FullscreenViewAdderFingerprint
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Name("disable-fullscreen-panels") @Name("disable-fullscreen-panels")
@Description("Disable comments panel in fullscreen view.") @Description("Disables video description and comments panel in fullscreen view.")
@FullscreenPanelsCompatibility @FullscreenPanelsCompatibility
@Version("0.0.1") @Version("0.0.1")
class FullscreenPanelsRemovalPatch : BytecodePatch(listOf()) { class FullscreenPanelsRemovalPatch : BytecodePatch(
listOf(
FullscreenViewAdderFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
val classDef = data.classes.first { it.type.endsWith("FullscreenEngagementPanelOverlay;") } val method = FullscreenViewAdderFingerprint.result?.mutableMethod!!
val method = data.proxy(classDef).resolve().methods.first { it.name == "<init>" }
val implementation = method.implementation!! val implementation = method.implementation!!
method.addInstructions( val (visibilityCallIndex, visibilityCall) =
implementation.instructions.count() - 1, implementation.instructions.withIndex()
""" .first { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.name == ("setVisibility") }
const/4 v1, 0x0
iput-boolean v1, v0, ${classDef.type}->a:Z val gotoIndex =
""" implementation.instructions.subList(0, visibilityCallIndex).indexOfLast { it.opcode == Opcode.GOTO }
)
//force the if
method.removeInstruction(gotoIndex)
val visibilityIntRegister = (visibilityCall as FiveRegisterInstruction).registerD
//set the visibility to GONE
method.addInstruction(visibilityCallIndex - 1, "const/16 v$visibilityIntRegister, 0x8")
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -0,0 +1,37 @@
package app.revanced.patches.youtube.layout.minimizedplayback.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("minimized-playback-manager-fingerprint")
@MatchingMethod(
"Ladj", "w"
)
@FuzzyPatternScanMethod(2)
@MinimizedPlaybackCompatibility
@Version("0.0.1")
object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST
),
)

View File

@@ -3,24 +3,30 @@ package app.revanced.patches.youtube.layout.minimizedplayback.patch
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility
import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Name("minimized-playback") @Name("minimized-playback")
@Description("Enable minimized and background playback.") @Description("Enables minimized and background playback.")
@MinimizedPlaybackCompatibility @MinimizedPlaybackCompatibility
@Version("0.0.1") @Version("0.0.1")
class MinimizedPlaybackPatch : BytecodePatch( class MinimizedPlaybackPatch : BytecodePatch(
listOf( listOf(
MinimizedPlaybackManagerFingerprint MinimizedPlaybackManagerFingerprint, MinimizedPlaybackSettingsFingerprint
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
@@ -32,6 +38,22 @@ class MinimizedPlaybackPatch : BytecodePatch(
return v0 return v0
""" """
) )
val method = MinimizedPlaybackSettingsFingerprint.result!!.mutableMethod
val booleanCalls = method.implementation!!.instructions.withIndex()
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }
val settingsBooleanIndex = booleanCalls.elementAt(1).index
val settingsBooleanMethod =
data.toMethodWalker(method).nextMethod(settingsBooleanIndex, true).getMethod() as MutableMethod
settingsBooleanMethod.addInstructions(
0, """
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -1,27 +0,0 @@
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("old-quality-fingerprint")
@MatchingMethod(definingClass = "Libh")
@FuzzyPatternScanMethod(2)
@OldQualityLayoutCompatibility
@Version("0.0.1")
object OldQualityFingerprint : MethodFingerprint(
"L", AccessFlags.FINAL or AccessFlags.PRIVATE, listOf("Z"), listOf(
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.GOTO,
Opcode.IGET_OBJECT,
)
)

View File

@@ -1,50 +0,0 @@
package app.revanced.patches.youtube.layout.oldqualitylayout.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("old-quality-parent-method-fingerprint")
@MatchingMethod(
"Libh", "<init>"
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@OldQualityLayoutCompatibility
@Version("0.0.1")
object OldQualityParentFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L", "L", "L", "L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
)
)

View File

@@ -0,0 +1,39 @@
package app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("quality-menu-view-inflate-fingerprint")
@MatchingMethod("Lkhp;", "K")
@OldQualityLayoutCompatibility
@Version("0.0.1")
object QualityMenuViewInflateFingerprint : MethodFingerprint(
"L", AccessFlags.FINAL or AccessFlags.PUBLIC, listOf("L", "L", "L"), listOf(
Opcode.INVOKE_SUPER,
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.CONST_STRING,
)
)

View File

@@ -1,54 +1,46 @@
package app.revanced.patches.youtube.layout.oldqualitylayout.patch package app.revanced.patches.youtube.layout.oldqualitylayout.patch
import OldQualityFingerprint
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.OldQualityParentFingerprint import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.QualityMenuViewInflateFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
@Patch @Patch
@Dependencies(dependencies = [IntegrationsPatch::class]) @Dependencies([IntegrationsPatch::class])
@Name("old-quality-layout") @Name("old-quality-layout")
@Description("Enable the original quality flyout menu.") @Description("Enables the original quality flyout menu.")
@OldQualityLayoutCompatibility @OldQualityLayoutCompatibility
@Version("0.0.1") @Version("0.0.1")
class OldQualityLayoutPatch : BytecodePatch( class OldQualityLayoutPatch : BytecodePatch(
listOf( listOf(QualityMenuViewInflateFingerprint)
OldQualityParentFingerprint
)
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
OldQualityFingerprint.resolve(data, OldQualityParentFingerprint.result!!.classDef) val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!!
val result = OldQualityFingerprint.result val method = inflateFingerprintResult.mutableMethod
?: return PatchResultError("Required parent method could not be found.") val instructions = method.implementation!!.instructions
val implementation = result.mutableMethod.implementation!! // at this index the listener is added to the list view
val listenerInvokeRegister = instructions.size - 1 - 1
// if useOldStyleQualitySettings == true, jump over all instructions // get the register which stores the quality menu list view
val jmpInstruction = BuilderInstruction21t( val onItemClickViewRegister = (instructions[listenerInvokeRegister] as FiveRegisterInstruction).registerC
Opcode.IF_NEZ, 0, implementation.instructions[result.patternScanResult!!.endIndex].location.labels.first()
) // insert the integrations method
implementation.addInstruction(5, jmpInstruction) method.addInstruction(
result.mutableMethod.addInstructions( listenerInvokeRegister, // insert the integrations instructions right before the listener
0, """ "invoke-static { v$onItemClickViewRegister }, Lapp/revanced/integrations/patches/OldQualityLayoutPatch;->showOldQualityMenu(Landroid/widget/ListView;)V"
invoke-static { }, Lapp/revanced/integrations/patches/OldStyleQualityPatch;->useOldStyleQualitySettings()Z
move-result v0
"""
) )
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

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

View File

@@ -13,7 +13,7 @@ import app.revanced.patches.youtube.layout.reels.fingerprints.HideReelsFingerpri
//@Patch TODO: this is currently in the general-bytecode-ads patch due to the integrations having a preference for including reels or not. Move it here. //@Patch TODO: this is currently in the general-bytecode-ads patch due to the integrations having a preference for including reels or not. Move it here.
@Name("hide-reels") @Name("hide-reels")
@Description("Hide reels on the page.") @Description("Hides reels on the home page.")
@HideReelsCompatibility @HideReelsCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideReelsPatch : BytecodePatch( class HideReelsPatch : BytecodePatch(
@@ -33,4 +33,4 @@ class HideReelsPatch : BytecodePatch(
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ReturnYouTubeDislikeCompatibility

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import org.jf.dexlib2.AccessFlags
@Name("dislike-fingerprint")
@MatchingMethod(
"Luqs;", "<init>"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
object DislikeFingerprint : MethodFingerprint(
"V",
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
null,
null,
listOf("like/dislike")
)

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import org.jf.dexlib2.AccessFlags
@Name("like-fingerprint")
@MatchingMethod(
"Luqt;", "<init>"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
object LikeFingerprint : MethodFingerprint(
"V",
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
null,
null,
listOf("like/like")
)

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import org.jf.dexlib2.AccessFlags
@Name("remove-like-fingerprint")
@MatchingMethod(
"Luqw;", "<init>"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
object RemoveLikeFingerprint : MethodFingerprint(
"V",
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
null,
null,
listOf("like/removelike")
)

View File

@@ -0,0 +1,23 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
@Name("text-component-spec-parent-fingerprint")
@MatchingMethod(
"Lnvy;", "e"
)
@DirectPatternScanMethod
@ReturnYouTubeDislikeCompatibility
@Version("0.0.1")
object TextComponentSpecParentFingerprint : MethodFingerprint(
null,
null,
null,
null,
listOf("TextComponentSpec: No converter for extension: ")
)

View File

@@ -0,0 +1,79 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.TextComponentSpecParentFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.DislikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.LikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RemoveLikeFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
@Patch
@Dependencies([IntegrationsPatch::class, VideoIdPatch::class])
@Name("return-youtube-dislike")
@Description("Shows the dislike count of videos using the Return YouTube Dislike API.")
@ReturnYouTubeDislikeCompatibility
@Version("0.0.1")
class ReturnYouTubeDislikePatch : BytecodePatch(
listOf(
TextComponentSpecParentFingerprint, LikeFingerprint, DislikeFingerprint, RemoveLikeFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
LikeFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, 1
invoke-static {v0}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->sendVote(I)V
"""
)
DislikeFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, -1
invoke-static {v0}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->sendVote(I)V
"""
)
RemoveLikeFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, 0
invoke-static {v0}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->sendVote(I)V
"""
)
VideoIdPatch.injectCall("Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->newVideoLoaded(Ljava/lang/String;)V")
val parentResult = TextComponentSpecParentFingerprint.result!!
val createComponentMethod = parentResult.mutableClass.methods.find { method ->
method.parameters.size >= 19 && method.parameterTypes.takeLast(4)
.all { param -> param == "Ljava/util/concurrent/atomic/AtomicReference;" }
}
?: return PatchResultError("TextComponentSpec.createComponent not found")
val conversionContextParam = 5
val textRefParam = createComponentMethod.parameters.size - 2
createComponentMethod.addInstructions(
0,
"""
move-object/from16 v0, p$conversionContextParam
move-object/from16 v1, p$textRefParam
invoke-static {v0, v1}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V
"""
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35") "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")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -17,9 +17,9 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch @Patch
@Dependencies(dependencies = [IntegrationsPatch::class]) @Dependencies([IntegrationsPatch::class])
@Name("disable-shorts-button") @Name("hide-shorts-button")
@Description("Hide the shorts button.") @Description("Hides the shorts button on the navigation bar.")
@ShortsButtonCompatibility @ShortsButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class ShortsButtonRemoverPatch : BytecodePatch( class ShortsButtonRemoverPatch : BytecodePatch(
@@ -38,6 +38,7 @@ class ShortsButtonRemoverPatch : BytecodePatch(
val moveViewInstruction = buttonsViewImplementation.instructions[buttonsViewResult.patternScanResult!!.endIndex] val moveViewInstruction = buttonsViewImplementation.instructions[buttonsViewResult.patternScanResult!!.endIndex]
val viewRegister = (moveViewInstruction as OneRegisterInstruction).registerA val viewRegister = (moveViewInstruction as OneRegisterInstruction).registerA
// Save the tab enum in XGlobals to avoid smali/register workarounds // Save the tab enum in XGlobals to avoid smali/register workarounds
tabEnumResult.mutableMethod.addInstruction( tabEnumResult.mutableMethod.addInstruction(
tabEnumResult.patternScanResult!!.endIndex + 1, tabEnumResult.patternScanResult!!.endIndex + 1,

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.watermark.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HideWatermarkCompatibility

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.youtube.layout.watermark.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
import org.jf.dexlib2.AccessFlags
@Name("hide-watermark-signature")
@MatchingMethod(
"Ljvy;", "<init>"
)
@FuzzyPatternScanMethod(3)
@HideWatermarkCompatibility
@Version("0.0.1")
object HideWatermarkFingerprint : MethodFingerprint (
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L"), null ,null, null
)

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.youtube.layout.watermark.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
import org.jf.dexlib2.AccessFlags
@Name("hide-watermark-parent-signature")
@MatchingMethod(
"Ljvy;", "<init>"
)
@FuzzyPatternScanMethod(3)
@HideWatermarkCompatibility
@Version("0.0.1")
object HideWatermarkParentFingerprint : MethodFingerprint (
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, null, null, listOf("player_overlay_in_video_programming"), null
)

View File

@@ -0,0 +1,50 @@
package app.revanced.patches.youtube.layout.watermark.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkParentFingerprint
import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch
@Dependencies([IntegrationsPatch::class])
@Name("hide-watermark")
@Description("Hides creator's watermarks on videos.")
@HideWatermarkCompatibility
@Version("0.0.1")
class HideWatermarkPatch : BytecodePatch(
listOf(
HideWatermarkParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
HideWatermarkFingerprint.resolve(data, HideWatermarkParentFingerprint.result!!.classDef)
val result = HideWatermarkFingerprint.result
?: return PatchResultError("Required parent method could not be found.")
val method = result.mutableMethod
val line = method.implementation!!.instructions.size - 5
method.removeInstruction(line)
method.addInstructions(
line, """
invoke-static {}, Lapp/revanced/integrations/patches/BrandingWaterMarkPatch;->isBrandingWatermarkShown()Z
move-result p2
"""
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.widesearchbar.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")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class WideSearchbarCompatibility

View File

@@ -0,0 +1,48 @@
package app.revanced.patches.youtube.layout.widesearchbar.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("wide-searchbar-methodone-fingerprint")
@MatchingMethod(
"Ljkg;", "i"
)
@DirectPatternScanMethod
@WideSearchbarCompatibility
@Version("0.0.1")
/*
This finds the following method:
public final View i(akrl akrlVar, adpd adpdVar) {
}
Method we search for is located in smali now.
See:
.method public final i(Lakrl;Ladpd;)Landroid/view/View;
iget-object v0, p0, Ljkg;->a:Landroid/app/Activity;
invoke-static {v0}, Landroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater;
move-result-object v0
iget-object v1, p0, Ljkg;->g:Ljis;
const/4 v2, 0x0
invoke-interface {v1, v2}, Ljis;->h(Z)V
iget-object p1, p1, Lakrl;->f:Lahnq;
if-nez p1, :cond_12
sget-object p1, Lahnq;->a:Lahnq;
:cond_12
iget-object v1, p0, Ljkg;->x:Ltxm;
invoke-static {v1}, Lfbn;->aF(Ltxm;)Z //THIS IS WHAT WE SEARCH FOR (Method fbn.aF)
move-result v1
*/
object WideSearchbarOneFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L"), listOf(Opcode.IF_NEZ, Opcode.SGET_OBJECT, Opcode.IGET_OBJECT, Opcode.INVOKE_STATIC),
null, null
)

View File

@@ -0,0 +1,47 @@
package app.revanced.patches.youtube.layout.widesearchbar.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
@Name("wide-searchbar-methodone-parent-fingerprint")
@MatchingMethod(
"Ljkg;", "l"
)
@FuzzyPatternScanMethod(3)
@WideSearchbarCompatibility
@Version("0.0.1")
/*
* This finds the following method:
private final void l(PaneDescriptor paneDescriptor) {
Class cls = null;
ahat f = paneDescriptor != null ? paneDescriptor.f() : null;
if (paneDescriptor != null) {
cls = paneDescriptor.a;
}
ftu k = k();
if ((k == null || !k.bk()) && ((!frx.k(f) && !((Boolean) aqer.S(this.n).X(new fac(this, f, 19)).K(irx.i).aH(false)).booleanValue()) || (f != null && f.qA(ReelWatchEndpointOuterClass$ReelWatchEndpoint.reelWatchEndpoint)))) {
String j = frx.j(f);
if ((j != null && ("FEhistory".equals(j) || "FEmy_videos".equals(j) || "FEpurchases".equals(j) || j.startsWith("VL"))) || cls == this.I.E() || cls == this.G.a) {
this.F = 3;
return;
} else {
this.F = 2;
return;
}
}
this.F = 1;
}
*/
object WideSearchbarOneParentFingerprint : MethodFingerprint(
"V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("L"), null,
listOf("FEhistory", "FEmy_videos", "FEpurchases")
)

View File

@@ -0,0 +1,49 @@
package app.revanced.patches.youtube.layout.widesearchbar.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("wide-searchbar-methodtwo-fingerprint")
@MatchingMethod(
"Lkrf;", "h"
)
@DirectPatternScanMethod
@WideSearchbarCompatibility
@Version("0.0.1")
/*
public static jis h(Context context, txm txmVar, uag uagVar, txp txpVar) {
return fbn.aB(txmVar) ? new jhx(context, txmVar, uagVar, txpVar) : jis.d;
}
Method we search for is located in smali now.
See:
.method public static h(Landroid/content/Context;Ltxm;Luag;Ltxp;)Ljis;
invoke-static {p1}, Lfbn;->aB(Ltxm;)Z //this is the method we want to change. fbn.aB
move-result v0
if-eqz v0, :cond_c
new-instance v0, Ljhx;
invoke-direct {v0, p0, p1, p2, p3}, Ljhx;-><init>(Landroid/content/Context;Ltxm;Luag;Ltxp;)V
goto :goto_e
:cond_c
sget-object v0, Ljis;->d:Ljis;
:goto_e
return-object v0
.end method
*/
object WideSearchbarTwoFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_EQZ, Opcode.NEW_INSTANCE
),
null, null
)

View File

@@ -0,0 +1,35 @@
package app.revanced.patches.youtube.layout.widesearchbar.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
@Name("wide-searchbar-methodtwo-parent-fingerprint")
@MatchingMethod(
"Lkrf;", "i"
)
@FuzzyPatternScanMethod(3)
@WideSearchbarCompatibility
@Version("0.0.1")
/*
This finds following method:
public static ies i(br brVar) {
bp f = brVar.getSupportFragmentManager().f("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT");
if (f != null) {
return (kga) f;
}
return new kga();
}
*/
object WideSearchbarTwoParentFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), null,
listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT")
)

View File

@@ -0,0 +1,105 @@
package app.revanced.patches.youtube.layout.widesearchbar.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarOneFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarOneParentFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch(include = false)
@Dependencies([IntegrationsPatch::class])
@Name("enable-wide-searchbar")
@Description("Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.")
@WideSearchbarCompatibility
@Version("0.0.1")
class WideSearchbarPatch : BytecodePatch(
listOf(
WideSearchbarOneParentFingerprint, WideSearchbarTwoParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
WideSearchbarOneFingerprint.resolve(data, WideSearchbarOneParentFingerprint.result!!.classDef)
WideSearchbarTwoFingerprint.resolve(data, WideSearchbarTwoParentFingerprint.result!!.classDef)
val resultOne = WideSearchbarOneFingerprint.result
//This should be the method aF in class fbn
val targetMethodOne =
data.toMethodWalker(resultOne!!.method).nextMethod(resultOne.patternScanResult!!.endIndex, true).getMethod() as MutableMethod
//Since both methods have the same smali code, inject instructions using a method.
addInstructions(targetMethodOne)
val resultTwo = WideSearchbarTwoFingerprint.result
//This should be the method aB in class fbn
val targetMethodTwo =
data.toMethodWalker(resultTwo!!.method).nextMethod(resultTwo.patternScanResult!!.startIndex, true).getMethod() as MutableMethod
//Since both methods have the same smali code, inject instructions using a method.
addInstructions(targetMethodTwo)
return PatchResultSuccess()
}
private fun addInstructions(method: MutableMethod) {
val index = method.implementation!!.instructions.size - 1
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
"""
)
}
//targetMethodOne: in class fbn
/*
.method public static aF(Ltxm;)Z
invoke-virtual {p0}, Ltxm;->b()Lahah;
move-result-object p0
iget-object p0, p0, Lahah;->e:Lakfd;
if-nez p0, :cond_a
sget-object p0, Lakfd;->a:Lakfd;
:cond_a
iget-boolean p0, p0, Lakfd;->V:Z
//added code here:
invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
//original code here:
return p0
.end method
*/
//targetMethodTwo: in class fbn
/*
.method public static aB(Ltxm;)Z
invoke-virtual {p0}, Ltxm;->b()Lahah;
move-result-object p0
iget-object p0, p0, Lahah;->e:Lakfd;
if-nez p0, :cond_a
sget-object p0, Lakfd;->a:Lakfd;
:cond_a
iget-boolean p0, p0, Lakfd;->y:Z
//added code here:
invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
//original code here:
return p0
.end method
*/
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.misc.autorepeat.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.24.35", "17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class AutoRepeatCompatibility

View File

@@ -0,0 +1,32 @@
package app.revanced.patches.youtube.misc.autorepeat.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility
import org.jf.dexlib2.AccessFlags
@Name("auto-repeat-fingerprint")
@MatchingMethod(
"Laamp;", "ae"
)
@FuzzyPatternScanMethod(2)
@AutoRepeatCompatibility
@Version("0.0.1")
//Finds method:
/*
public final void ae() {
aq(aabj.ENDED);
}
*/
object AutoRepeatFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
null,
null,
customFingerprint = { methodDef -> methodDef.implementation!!.instructions.count() == 3 && methodDef.annotations.isEmpty()}
)

View File

@@ -0,0 +1,35 @@
package app.revanced.patches.youtube.misc.autorepeat.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility
import org.jf.dexlib2.AccessFlags
@Name("auto-repeat-parent-fingerprint")
@MatchingMethod(
"Laamp;", "E"
)
@FuzzyPatternScanMethod(2)
@AutoRepeatCompatibility
@Version("0.0.1")
//This Fingerprints finds the play() method needed to be called when AutoRepeatPatch.shouldAutoRepeat() == true
/*
public final void E() {
Stuff happens
String str = "play() called when the player wasn't loaded.";
String str2 = "play() blocked because Background Playability failed";
Stuff happens again
}
*/
object AutoRepeatParentFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
null,
listOf("play() called when the player wasn't loaded.", "play() blocked because Background Playability failed"),
null
)

View File

@@ -0,0 +1,75 @@
package app.revanced.patches.youtube.misc.autorepeat.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility
import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatFingerprint
import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch(include = false)
@Dependencies([IntegrationsPatch::class])
@Name("autorepeat-by-default")
@Description("Enables auto repeating of videos by default.")
@AutoRepeatCompatibility
@Version("0.0.1")
class AutoRepeatPatch : BytecodePatch(
listOf(
AutoRepeatParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
//Get Result from the ParentFingerprint which is the playMethod we need to get.
val parentResult = AutoRepeatParentFingerprint.result
?: return PatchResultError("ParentFingerprint did not resolve.")
//this one needs to be called when app/revanced/integrations/patches/AutoRepeatPatch;->shouldAutoRepeat() returns true
val playMethod = parentResult.mutableMethod
AutoRepeatFingerprint.resolve(data, parentResult.classDef)
//String is: Laamp;->E()V
val methodToCall = playMethod.definingClass + "->" + playMethod.name + "()V";
//This is the method we search for
val result = AutoRepeatFingerprint.result
?: return PatchResultError("FingerPrint did not resolve.")
val method = result.mutableMethod
//Instructions to add to the smali code
val instructions = """
invoke-static {}, Lapp/revanced/integrations/patches/AutoRepeatPatch;->shouldAutoRepeat()Z
move-result v0
if-eqz v0, :noautorepeat
invoke-virtual {p0}, $methodToCall
:noautorepeat
return-void
"""
//Get the implementation so we can do a check for null and get instructions size.
val implementation = method.implementation
?: return PatchResultError("No Method Implementation found!")
//Since addInstructions needs an index which starts counting at 0 and size starts counting at 1,
//we have to remove 1 to get the latest instruction
val index = implementation.instructions.size - 1
//remove last instruction which is return-void
method.removeInstruction(index)
// Add our own instructions there
method.addInstructions(index, instructions)
//Everything worked as expected, return Success
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.misc.customplaybackspeed.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class CustomPlaybackSpeedCompatibility

View File

@@ -0,0 +1,33 @@
package app.revanced.patches.youtube.misc.customplaybackspeed.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("speed-array-generator-fingerprint")
@MatchingMethod(
"Lzdj;", "d"
)
@FuzzyPatternScanMethod(2)
@CustomPlaybackSpeedCompatibility
@Version("0.0.1")
object SpeedArrayGeneratorFingerprint : MethodFingerprint(
"[L",
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
listOf(
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.GOTO,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
),
listOf("0.0#")
)

View File

@@ -0,0 +1,34 @@
package app.revanced.patches.youtube.misc.customplaybackspeed.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("speed-limiter-fingerprint")
@MatchingMethod(
"Lxgy;", "y"
)
@FuzzyPatternScanMethod(2)
@CustomPlaybackSpeedCompatibility
@Version("0.0.1")
object SpeedLimiterFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("F"),
listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.CONST_HIGH16,
Opcode.GOTO,
Opcode.CONST_HIGH16,
Opcode.CONST_HIGH16,
Opcode.INVOKE_STATIC,
),
)

View File

@@ -0,0 +1,110 @@
package app.revanced.patches.youtube.misc.customplaybackspeed.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
import app.revanced.patches.youtube.misc.customplaybackspeed.fingerprints.SpeedArrayGeneratorFingerprint
import app.revanced.patches.youtube.misc.customplaybackspeed.fingerprints.SpeedLimiterFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.MethodReference
@Patch
@Name("custom-playback-speed")
@Description("Adds more video playback speed options.")
@Dependencies([IntegrationsPatch::class])
@CustomPlaybackSpeedCompatibility
@Version("0.0.1")
class CustomPlaybackSpeedPatch : BytecodePatch(
listOf(
SpeedArrayGeneratorFingerprint, SpeedLimiterFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val arrayGenMethod = SpeedArrayGeneratorFingerprint.result?.mutableMethod!!
val arrayGenMethodImpl = arrayGenMethod.implementation!!
val sizeCallIndex = arrayGenMethodImpl.instructions
.indexOfFirst { ((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "size" }
if (sizeCallIndex == -1) return PatchResultError("Couldn't find call to size()")
val sizeCallResultRegister =
(arrayGenMethodImpl.instructions.elementAt(sizeCallIndex + 1) as OneRegisterInstruction).registerA
arrayGenMethod.replaceInstruction(
sizeCallIndex + 1,
"const/4 v$sizeCallResultRegister, 0x0"
)
val (arrayLengthConstIndex, arrayLengthConst) = arrayGenMethodImpl.instructions.withIndex()
.first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 7 }
val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA
val videoSpeedsArrayType = "Lapp/revanced/integrations/patches/VideoSpeedPatch;->videoSpeeds:[F"
arrayGenMethod.addInstructions(
arrayLengthConstIndex + 1,
"""
sget-object v$arrayLengthConstDestination, $videoSpeedsArrayType
array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination
"""
)
val (originalArrayFetchIndex, originalArrayFetch) = arrayGenMethodImpl.instructions.withIndex()
.first {
val reference = ((it.value as? ReferenceInstruction)?.reference as? FieldReference)
reference?.definingClass?.contains("PlayerConfigModel") ?: false &&
reference?.type == "[F"
}
val originalArrayFetchDestination = (originalArrayFetch as OneRegisterInstruction).registerA
arrayGenMethod.replaceInstruction(
originalArrayFetchIndex,
"sget-object v$originalArrayFetchDestination, $videoSpeedsArrayType"
)
val limiterMethod = SpeedLimiterFingerprint.result?.mutableMethod!!;
val limiterMethodImpl = limiterMethod.implementation!!
val speedLimitMin = 0.25f
val speedLimitMax = 100f
val (limiterMinConstIndex, limiterMinConst) = limiterMethodImpl.instructions.withIndex()
.first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() }
val (limiterMaxConstIndex, limiterMaxConst) = limiterMethodImpl.instructions.withIndex()
.first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() }
val limiterMinConstDestination = (limiterMinConst as OneRegisterInstruction).registerA
val limiterMaxConstDestination = (limiterMaxConst as OneRegisterInstruction).registerA
fun hexFloat(float: Float): String = "0x%08x".format(float.toRawBits())
limiterMethod.replaceInstruction(
limiterMinConstIndex,
"const/high16 v$limiterMinConstDestination, ${hexFloat(speedLimitMin)}"
)
limiterMethod.replaceInstruction(
limiterMaxConstIndex,
"const/high16 v$limiterMaxConstDestination, ${hexFloat(speedLimitMax)}"
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.misc.enabledebugging.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf()
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class EnableDebuggingCompatibility

View File

@@ -0,0 +1,35 @@
package app.revanced.patches.youtube.misc.enabledebugging.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.misc.enabledebugging.annotations.EnableDebuggingCompatibility
import org.w3c.dom.Element
@Patch(false)
@Name("enable-debugging")
@Description("Enables app debugging by patching the manifest file.")
@EnableDebuggingCompatibility
@Version("0.0.1")
class EnableDebuggingPatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult {
// create an xml editor instance
data.xmlEditor["AndroidManifest.xml"].use { dom ->
// get the application node
val applicationNode = dom
.file
.getElementsByTagName("application")
.item(0) as Element
// set application as debuggable
applicationNode.setAttribute("android:debuggable", "true")
}
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,14 @@
package app.revanced.patches.youtube.misc.forcevp9.annotations;
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ForceVP9Compatibility {
}

View File

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

View File

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

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