chore: Merge branch dev
to main
(#3232)
This commit is contained in:
commit
cd18216879
244
CHANGELOG.md
244
CHANGELOG.md
|
@ -1,3 +1,247 @@
|
||||||
|
# [2.197.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.4...v2.197.0-dev.5) (2023-11-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Use a checked cast by reifying the generic type parameter ([f7a296e](https://github.com/ReVanced/revanced-patches/commit/f7a296e1f17d7bfb5fd303ee83cabd8d625781b9))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Client spoof:** Add description to preference screen ([843a568](https://github.com/ReVanced/revanced-patches/commit/843a56854465fe2052977cd2a8f24ecb839f8d2a))
|
||||||
|
* **YouTube - Hide layout components:** Add description to preference screen ([cc85441](https://github.com/ReVanced/revanced-patches/commit/cc854415e2311d4a06805a49a052fc8a16924739))
|
||||||
|
* **YouTube - Hide layout components:** Hide description components ([38b8e44](https://github.com/ReVanced/revanced-patches/commit/38b8e44ec494e7dea24066dc2f5af578e01d58dc))
|
||||||
|
* **YouTube - Navigation buttons:** Add description to preference screen ([14ea967](https://github.com/ReVanced/revanced-patches/commit/14ea9674c4e65ff2a92962222860b8035c7cda3f))
|
||||||
|
* **YouTube - Seekbar:** Add description to preference screen ([ea6de49](https://github.com/ReVanced/revanced-patches/commit/ea6de498e3b002feeabf72d20059090db0be7f94))
|
||||||
|
* **YouTube - Settings:** Sort preference screens below other types of preference ([9561db5](https://github.com/ReVanced/revanced-patches/commit/9561db50a82b0eeed07fe6541bc29a37f85b7caa))
|
||||||
|
* **YouTube:** Support version `18.45.41` ([7c4f021](https://github.com/ReVanced/revanced-patches/commit/7c4f021f8c849dfc448c18ffc800da39576be617))
|
||||||
|
|
||||||
|
# [2.197.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.3...v2.197.0-dev.4) (2023-11-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Return YouTube Dislike:** Support version `18.43.45` and `18.44.41` ([#3260](https://github.com/ReVanced/revanced-patches/issues/3260)) ([70dee58](https://github.com/ReVanced/revanced-patches/commit/70dee584ed91b8f3dc7fe63c3d77fef6ed1dc745))
|
||||||
|
|
||||||
|
# [2.197.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.2...v2.197.0-dev.3) (2023-11-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Android Widgets (Material U):** Remove `Unlock paid widgets` patch ([#3286](https://github.com/ReVanced/revanced-patches/issues/3286)) ([b44da1c](https://github.com/ReVanced/revanced-patches/commit/b44da1c7018c88d30be0849569837b4e17c68e0f))
|
||||||
|
|
||||||
|
# [2.197.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.1...v2.197.0-dev.2) (2023-11-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Disable resuming Shorts on startup:** Adjust patch name ([#3281](https://github.com/ReVanced/revanced-patches/issues/3281)) ([c332952](https://github.com/ReVanced/revanced-patches/commit/c3329527db739e6777fe8e77828e1226e4057b80))
|
||||||
|
* **YouTube - Hide layout components:** Reduce false positives when hiding mix playlists ([fb173e1](https://github.com/ReVanced/revanced-patches/commit/fb173e18afd5566a4ccdbb613810fa9646da9334))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Spoof SIM country` patch ([#3116](https://github.com/ReVanced/revanced-patches/issues/3116)) ([304a0d4](https://github.com/ReVanced/revanced-patches/commit/304a0d46bfee5ae96aaefee8f508eedd16004e36))
|
||||||
|
* **Facebook:** Add `Hide story ads` patch ([#3257](https://github.com/ReVanced/revanced-patches/issues/3257)) ([1408c2e](https://github.com/ReVanced/revanced-patches/commit/1408c2e6283f4c48020d4305008a45f53b96b5cc))
|
||||||
|
* **Twitch:** Support version `17.1.0` ([#3269](https://github.com/ReVanced/revanced-patches/issues/3269)) ([d88373b](https://github.com/ReVanced/revanced-patches/commit/d88373bf43a50198dec275301418435179bc822e))
|
||||||
|
* **YouTube - Bypass URL redirects:** Support version `18.43.45` ([e205ac7](https://github.com/ReVanced/revanced-patches/commit/e205ac761d836047c52a4862132b6ea7d5a10b1b))
|
||||||
|
* **YouTube - Hide timestamp:** Support version `18.43.45` ([9180d4f](https://github.com/ReVanced/revanced-patches/commit/9180d4f5c3d4a50f412b37af69d61aafce5ffc07))
|
||||||
|
* **YouTube - Navigation buttons:** Support version `18.43.45` ([e21286e](https://github.com/ReVanced/revanced-patches/commit/e21286e4d76323adb24ca8112a4ce03bfab98d60))
|
||||||
|
* **YouTube - Player flyout menu:** Support version `18.43.45` and `18.44.41` ([#3263](https://github.com/ReVanced/revanced-patches/issues/3263)) ([fcbebf9](https://github.com/ReVanced/revanced-patches/commit/fcbebf90f350cb7653e14da33b703eb25098dd55))
|
||||||
|
* **YouTube - Seekbar tapping:** Support version `18.43.45` ([eee51a8](https://github.com/ReVanced/revanced-patches/commit/eee51a863a059c5073b2817e57059e072b72155d))
|
||||||
|
* **YouTube - Vanced MicroG support:** Allow changing package name ([0c7490c](https://github.com/ReVanced/revanced-patches/commit/0c7490cbaf367d5029373096c41661c5112bfe53))
|
||||||
|
* **YouTube Music - Vanced MicroG support:** Allow changing package name ([ede2d67](https://github.com/ReVanced/revanced-patches/commit/ede2d67b921480fbe496b551e43b190836d6bb72))
|
||||||
|
* **YouTube:** Add `Enable slide to seek` patch ([68d10d4](https://github.com/ReVanced/revanced-patches/commit/68d10d4779d3545177fcf48f0aec237a2359b8b1))
|
||||||
|
* **YouTube:** Add `Remove tracking query parameter` patch ([ddda3f6](https://github.com/ReVanced/revanced-patches/commit/ddda3f6e8cd919edaa891baee6597d2566e18e50))
|
||||||
|
* **YouTube:** Bump compatibility to `18.38.45` ([9f19869](https://github.com/ReVanced/revanced-patches/commit/9f1986960cbaab84519d0685d1950764c16d08a5))
|
||||||
|
* **YouTube:** Bump compatibility to `18.44.41` ([384a0a6](https://github.com/ReVanced/revanced-patches/commit/384a0a67c52d7d342afae491388199aca6b78b4d))
|
||||||
|
* **YouTube:** Support version `18.43.45` for `Playback speed` and `Restore old video quality menu` ([c5236f8](https://github.com/ReVanced/revanced-patches/commit/c5236f812e1e362e4d03885b0950385e360bbff8))
|
||||||
|
|
||||||
|
# [2.197.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.1...v2.197.0-dev.2) (2023-11-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Reduce false positives when hiding mix playlists ([fb173e1](https://github.com/ReVanced/revanced-patches/commit/fb173e18afd5566a4ccdbb613810fa9646da9334))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Spoof SIM country` patch ([#3116](https://github.com/ReVanced/revanced-patches/issues/3116)) ([304a0d4](https://github.com/ReVanced/revanced-patches/commit/304a0d46bfee5ae96aaefee8f508eedd16004e36))
|
||||||
|
* **Facebook:** Add `Hide story ads` patch ([#3257](https://github.com/ReVanced/revanced-patches/issues/3257)) ([1408c2e](https://github.com/ReVanced/revanced-patches/commit/1408c2e6283f4c48020d4305008a45f53b96b5cc))
|
||||||
|
* **Twitch:** Support version `17.1.0` ([#3269](https://github.com/ReVanced/revanced-patches/issues/3269)) ([d88373b](https://github.com/ReVanced/revanced-patches/commit/d88373bf43a50198dec275301418435179bc822e))
|
||||||
|
* **YouTube - Bypass URL redirects:** Support version `18.43.45` ([e205ac7](https://github.com/ReVanced/revanced-patches/commit/e205ac761d836047c52a4862132b6ea7d5a10b1b))
|
||||||
|
* **YouTube - Hide timestamp:** Support version `18.43.45` ([9180d4f](https://github.com/ReVanced/revanced-patches/commit/9180d4f5c3d4a50f412b37af69d61aafce5ffc07))
|
||||||
|
* **YouTube - Navigation buttons:** Support version `18.43.45` ([e21286e](https://github.com/ReVanced/revanced-patches/commit/e21286e4d76323adb24ca8112a4ce03bfab98d60))
|
||||||
|
* **YouTube - Player flyout menu:** Support version `18.43.45` and `18.44.41` ([#3263](https://github.com/ReVanced/revanced-patches/issues/3263)) ([fcbebf9](https://github.com/ReVanced/revanced-patches/commit/fcbebf90f350cb7653e14da33b703eb25098dd55))
|
||||||
|
* **YouTube - Seekbar tapping:** Support version `18.43.45` ([eee51a8](https://github.com/ReVanced/revanced-patches/commit/eee51a863a059c5073b2817e57059e072b72155d))
|
||||||
|
* **YouTube - Vanced MicroG support:** Allow changing package name ([0c7490c](https://github.com/ReVanced/revanced-patches/commit/0c7490cbaf367d5029373096c41661c5112bfe53))
|
||||||
|
* **YouTube Music - Vanced MicroG support:** Allow changing package name ([ede2d67](https://github.com/ReVanced/revanced-patches/commit/ede2d67b921480fbe496b551e43b190836d6bb72))
|
||||||
|
* **YouTube:** Add `Enable slide to seek` patch ([68d10d4](https://github.com/ReVanced/revanced-patches/commit/68d10d4779d3545177fcf48f0aec237a2359b8b1))
|
||||||
|
* **YouTube:** Add `Remove tracking query parameter` patch ([ddda3f6](https://github.com/ReVanced/revanced-patches/commit/ddda3f6e8cd919edaa891baee6597d2566e18e50))
|
||||||
|
* **YouTube:** Bump compatibility to `18.38.45` ([9f19869](https://github.com/ReVanced/revanced-patches/commit/9f1986960cbaab84519d0685d1950764c16d08a5))
|
||||||
|
* **YouTube:** Bump compatibility to `18.44.41` ([384a0a6](https://github.com/ReVanced/revanced-patches/commit/384a0a67c52d7d342afae491388199aca6b78b4d))
|
||||||
|
* **YouTube:** Support version `18.43.45` for `Playback speed` and `Restore old video quality menu` ([c5236f8](https://github.com/ReVanced/revanced-patches/commit/c5236f812e1e362e4d03885b0950385e360bbff8))
|
||||||
|
|
||||||
|
# [2.197.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.1...v2.197.0-dev.2) (2023-11-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Reduce false positives when hiding mix playlists ([fb173e1](https://github.com/ReVanced/revanced-patches/commit/fb173e18afd5566a4ccdbb613810fa9646da9334))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Spoof SIM country` patch ([#3116](https://github.com/ReVanced/revanced-patches/issues/3116)) ([304a0d4](https://github.com/ReVanced/revanced-patches/commit/304a0d46bfee5ae96aaefee8f508eedd16004e36))
|
||||||
|
* **Facebook:** Add `Hide story ads` patch ([#3257](https://github.com/ReVanced/revanced-patches/issues/3257)) ([1408c2e](https://github.com/ReVanced/revanced-patches/commit/1408c2e6283f4c48020d4305008a45f53b96b5cc))
|
||||||
|
* **Twitch:** Support version `17.1.0` ([#3269](https://github.com/ReVanced/revanced-patches/issues/3269)) ([d88373b](https://github.com/ReVanced/revanced-patches/commit/d88373bf43a50198dec275301418435179bc822e))
|
||||||
|
* **YouTube - Bypass URL redirects:** Support version `18.43.45` ([e205ac7](https://github.com/ReVanced/revanced-patches/commit/e205ac761d836047c52a4862132b6ea7d5a10b1b))
|
||||||
|
* **YouTube - Hide timestamp:** Support version `18.43.45` ([9180d4f](https://github.com/ReVanced/revanced-patches/commit/9180d4f5c3d4a50f412b37af69d61aafce5ffc07))
|
||||||
|
* **YouTube - Navigation buttons:** Support version `18.43.45` ([e21286e](https://github.com/ReVanced/revanced-patches/commit/e21286e4d76323adb24ca8112a4ce03bfab98d60))
|
||||||
|
* **YouTube - Player flyout menu:** Support version `18.43.45` and `18.44.41` ([#3263](https://github.com/ReVanced/revanced-patches/issues/3263)) ([fcbebf9](https://github.com/ReVanced/revanced-patches/commit/fcbebf90f350cb7653e14da33b703eb25098dd55))
|
||||||
|
* **YouTube - Seekbar tapping:** Support version `18.43.45` ([eee51a8](https://github.com/ReVanced/revanced-patches/commit/eee51a863a059c5073b2817e57059e072b72155d))
|
||||||
|
* **YouTube:** Add `Enable slide to seek` patch ([68d10d4](https://github.com/ReVanced/revanced-patches/commit/68d10d4779d3545177fcf48f0aec237a2359b8b1))
|
||||||
|
* **YouTube:** Add `Remove tracking query parameter` patch ([ddda3f6](https://github.com/ReVanced/revanced-patches/commit/ddda3f6e8cd919edaa891baee6597d2566e18e50))
|
||||||
|
* **YouTube:** Bump compatibility to `18.38.45` ([9f19869](https://github.com/ReVanced/revanced-patches/commit/9f1986960cbaab84519d0685d1950764c16d08a5))
|
||||||
|
* **YouTube:** Bump compatibility to `18.44.41` ([384a0a6](https://github.com/ReVanced/revanced-patches/commit/384a0a67c52d7d342afae491388199aca6b78b4d))
|
||||||
|
* **YouTube:** Support version `18.43.45` for `Playback speed` and `Restore old video quality menu` ([c5236f8](https://github.com/ReVanced/revanced-patches/commit/c5236f812e1e362e4d03885b0950385e360bbff8))
|
||||||
|
|
||||||
|
# [2.197.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.1...v2.197.0-dev.2) (2023-11-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Reduce false positives when hiding mix playlists ([fb173e1](https://github.com/ReVanced/revanced-patches/commit/fb173e18afd5566a4ccdbb613810fa9646da9334))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Spoof SIM country` patch ([#3116](https://github.com/ReVanced/revanced-patches/issues/3116)) ([304a0d4](https://github.com/ReVanced/revanced-patches/commit/304a0d46bfee5ae96aaefee8f508eedd16004e36))
|
||||||
|
* **Facebook:** Add `Hide story ads` patch ([#3257](https://github.com/ReVanced/revanced-patches/issues/3257)) ([1408c2e](https://github.com/ReVanced/revanced-patches/commit/1408c2e6283f4c48020d4305008a45f53b96b5cc))
|
||||||
|
* **YouTube - Bypass URL redirects:** Support version `18.43.45` ([e205ac7](https://github.com/ReVanced/revanced-patches/commit/e205ac761d836047c52a4862132b6ea7d5a10b1b))
|
||||||
|
* **YouTube - Hide timestamp:** Support version `18.43.45` ([9180d4f](https://github.com/ReVanced/revanced-patches/commit/9180d4f5c3d4a50f412b37af69d61aafce5ffc07))
|
||||||
|
* **YouTube - Navigation buttons:** Support version `18.43.45` ([e21286e](https://github.com/ReVanced/revanced-patches/commit/e21286e4d76323adb24ca8112a4ce03bfab98d60))
|
||||||
|
* **YouTube - Player flyout menu:** Support version `18.43.45` and `18.44.41` ([#3263](https://github.com/ReVanced/revanced-patches/issues/3263)) ([fcbebf9](https://github.com/ReVanced/revanced-patches/commit/fcbebf90f350cb7653e14da33b703eb25098dd55))
|
||||||
|
* **YouTube - Seekbar tapping:** Support version `18.43.45` ([eee51a8](https://github.com/ReVanced/revanced-patches/commit/eee51a863a059c5073b2817e57059e072b72155d))
|
||||||
|
* **YouTube:** Add `Enable slide to seek` patch ([68d10d4](https://github.com/ReVanced/revanced-patches/commit/68d10d4779d3545177fcf48f0aec237a2359b8b1))
|
||||||
|
* **YouTube:** Add `Remove tracking query parameter` patch ([ddda3f6](https://github.com/ReVanced/revanced-patches/commit/ddda3f6e8cd919edaa891baee6597d2566e18e50))
|
||||||
|
* **YouTube:** Bump compatibility to `18.38.45` ([9f19869](https://github.com/ReVanced/revanced-patches/commit/9f1986960cbaab84519d0685d1950764c16d08a5))
|
||||||
|
* **YouTube:** Bump compatibility to `18.44.41` ([384a0a6](https://github.com/ReVanced/revanced-patches/commit/384a0a67c52d7d342afae491388199aca6b78b4d))
|
||||||
|
* **YouTube:** Support version `18.43.45` for `Playback speed` and `Restore old video quality menu` ([c5236f8](https://github.com/ReVanced/revanced-patches/commit/c5236f812e1e362e4d03885b0950385e360bbff8))
|
||||||
|
|
||||||
|
# [2.197.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.1...v2.197.0-dev.2) (2023-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Reduce false positives when hiding mix playlists ([fb173e1](https://github.com/ReVanced/revanced-patches/commit/fb173e18afd5566a4ccdbb613810fa9646da9334))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Spoof SIM country` patch ([#3116](https://github.com/ReVanced/revanced-patches/issues/3116)) ([304a0d4](https://github.com/ReVanced/revanced-patches/commit/304a0d46bfee5ae96aaefee8f508eedd16004e36))
|
||||||
|
* **Facebook:** Add `Hide story ads` patch ([#3257](https://github.com/ReVanced/revanced-patches/issues/3257)) ([1408c2e](https://github.com/ReVanced/revanced-patches/commit/1408c2e6283f4c48020d4305008a45f53b96b5cc))
|
||||||
|
* **YouTube - Bypass URL redirects:** Support version `18.43.45` ([e205ac7](https://github.com/ReVanced/revanced-patches/commit/e205ac761d836047c52a4862132b6ea7d5a10b1b))
|
||||||
|
* **YouTube - Hide timestamp:** Support version `18.43.45` ([9180d4f](https://github.com/ReVanced/revanced-patches/commit/9180d4f5c3d4a50f412b37af69d61aafce5ffc07))
|
||||||
|
* **YouTube - Navigation buttons:** Support version `18.43.45` ([e21286e](https://github.com/ReVanced/revanced-patches/commit/e21286e4d76323adb24ca8112a4ce03bfab98d60))
|
||||||
|
* **YouTube - Seekbar tapping:** Support version `18.43.45` ([eee51a8](https://github.com/ReVanced/revanced-patches/commit/eee51a863a059c5073b2817e57059e072b72155d))
|
||||||
|
* **YouTube:** Add `Enable slide to seek` patch ([68d10d4](https://github.com/ReVanced/revanced-patches/commit/68d10d4779d3545177fcf48f0aec237a2359b8b1))
|
||||||
|
* **YouTube:** Add `Remove tracking query parameter` patch ([ddda3f6](https://github.com/ReVanced/revanced-patches/commit/ddda3f6e8cd919edaa891baee6597d2566e18e50))
|
||||||
|
* **YouTube:** Bump compatibility to `18.38.45` ([9f19869](https://github.com/ReVanced/revanced-patches/commit/9f1986960cbaab84519d0685d1950764c16d08a5))
|
||||||
|
* **YouTube:** Bump compatibility to `18.44.41` ([384a0a6](https://github.com/ReVanced/revanced-patches/commit/384a0a67c52d7d342afae491388199aca6b78b4d))
|
||||||
|
* **YouTube:** Support version `18.43.45` for `Playback speed` and `Restore old video quality menu` ([c5236f8](https://github.com/ReVanced/revanced-patches/commit/c5236f812e1e362e4d03885b0950385e360bbff8))
|
||||||
|
|
||||||
|
# [2.197.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.1...v2.197.0-dev.2) (2023-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Reduce false positives when hiding mix playlists ([fb173e1](https://github.com/ReVanced/revanced-patches/commit/fb173e18afd5566a4ccdbb613810fa9646da9334))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Spoof SIM country` patch ([#3116](https://github.com/ReVanced/revanced-patches/issues/3116)) ([304a0d4](https://github.com/ReVanced/revanced-patches/commit/304a0d46bfee5ae96aaefee8f508eedd16004e36))
|
||||||
|
* **YouTube - Bypass URL redirects:** Support version `18.43.45` ([e205ac7](https://github.com/ReVanced/revanced-patches/commit/e205ac761d836047c52a4862132b6ea7d5a10b1b))
|
||||||
|
* **YouTube - Hide timestamp:** Support version `18.43.45` ([9180d4f](https://github.com/ReVanced/revanced-patches/commit/9180d4f5c3d4a50f412b37af69d61aafce5ffc07))
|
||||||
|
* **YouTube - Navigation buttons:** Support version `18.43.45` ([e21286e](https://github.com/ReVanced/revanced-patches/commit/e21286e4d76323adb24ca8112a4ce03bfab98d60))
|
||||||
|
* **YouTube - Seekbar tapping:** Support version `18.43.45` ([eee51a8](https://github.com/ReVanced/revanced-patches/commit/eee51a863a059c5073b2817e57059e072b72155d))
|
||||||
|
* **YouTube:** Add `Enable slide to seek` patch ([68d10d4](https://github.com/ReVanced/revanced-patches/commit/68d10d4779d3545177fcf48f0aec237a2359b8b1))
|
||||||
|
* **YouTube:** Add `Remove tracking query parameter` patch ([ddda3f6](https://github.com/ReVanced/revanced-patches/commit/ddda3f6e8cd919edaa891baee6597d2566e18e50))
|
||||||
|
* **YouTube:** Bump compatibility to `18.38.45` ([9f19869](https://github.com/ReVanced/revanced-patches/commit/9f1986960cbaab84519d0685d1950764c16d08a5))
|
||||||
|
* **YouTube:** Bump compatibility to `18.44.41` ([384a0a6](https://github.com/ReVanced/revanced-patches/commit/384a0a67c52d7d342afae491388199aca6b78b4d))
|
||||||
|
* **YouTube:** Support version `18.43.45` for `Playback speed` and `Restore old video quality menu` ([c5236f8](https://github.com/ReVanced/revanced-patches/commit/c5236f812e1e362e4d03885b0950385e360bbff8))
|
||||||
|
|
||||||
|
# [2.197.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.197.0-dev.1...v2.197.0-dev.2) (2023-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Reduce false positives when hiding mix playlists ([aac30ad](https://github.com/ReVanced/revanced-patches/commit/aac30ad717df02af87f2d65edddac8119cb262e9))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Bypass URL redirects:** Support version `18.43.45` ([8935955](https://github.com/ReVanced/revanced-patches/commit/89359550c087e457a3fa5ad924daae0735cfad55))
|
||||||
|
* **YouTube - Hide timestamp:** Support version `18.43.45` ([9180d4f](https://github.com/ReVanced/revanced-patches/commit/9180d4f5c3d4a50f412b37af69d61aafce5ffc07))
|
||||||
|
* **YouTube - Navigation buttons:** Support version `18.43.45` ([e21286e](https://github.com/ReVanced/revanced-patches/commit/e21286e4d76323adb24ca8112a4ce03bfab98d60))
|
||||||
|
* **YouTube - Seekbar tapping:** Support version `18.43.45` ([7828b14](https://github.com/ReVanced/revanced-patches/commit/7828b1425bd766db79fa8b28f002c75ff8d62cdd))
|
||||||
|
* **YouTube:** Add `Enable slide to seek` patch ([a82fa35](https://github.com/ReVanced/revanced-patches/commit/a82fa35dd8dff30fabdc5f91c48a95234ed5d055))
|
||||||
|
* **YouTube:** Add `Remove tracking query parameter` patch ([a353934](https://github.com/ReVanced/revanced-patches/commit/a3539348ce488f1effc88e62a1e0bd1a3635a2bd))
|
||||||
|
* **YouTube:** Bump compatibility to `18.38.45` ([f743491](https://github.com/ReVanced/revanced-patches/commit/f7434910ad860e92f6c8d71a1fcd063ae075b704))
|
||||||
|
* **YouTube:** Bump compatibility to `18.44.41` ([5490f58](https://github.com/ReVanced/revanced-patches/commit/5490f58974b6d5a0af145f3518756d736566adc7))
|
||||||
|
* **YouTube:** Support version `18.43.45` for `Playback speed failed` and `Restore old video quality menu` ([b5e3263](https://github.com/ReVanced/revanced-patches/commit/b5e326348a581f343a4f05ae7a8c822bc6c90313))
|
||||||
|
|
||||||
|
# [2.197.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.196.1-dev.6...v2.197.0-dev.1) (2023-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Twitch:** Support version `17.0.0` ([#3250](https://github.com/ReVanced/revanced-patches/issues/3250)) ([9c103ac](https://github.com/ReVanced/revanced-patches/commit/9c103acb94b8d7d2858441300bd297fedbacbb40))
|
||||||
|
|
||||||
|
## [2.196.1-dev.6](https://github.com/ReVanced/revanced-patches/compare/v2.196.1-dev.5...v2.196.1-dev.6) (2023-11-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Client spoof:** Fix low resolution precise seeking thumbnails ([#3249](https://github.com/ReVanced/revanced-patches/issues/3249)) ([0cb41ef](https://github.com/ReVanced/revanced-patches/commit/0cb41efa067d74b873167718b25893cb2e1dd240))
|
||||||
|
|
||||||
|
## [2.196.1-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.196.1-dev.4...v2.196.1-dev.5) (2023-11-10)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Remove screenshot restriction:** Improve reliability ([#2938](https://github.com/ReVanced/revanced-patches/issues/2938)) ([6b7cb7b](https://github.com/ReVanced/revanced-patches/commit/6b7cb7bd38348dbe4a56385356df6ed97e81c319))
|
||||||
|
|
||||||
|
## [2.196.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.196.1-dev.3...v2.196.1-dev.4) (2023-11-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - SponsorBlock:** Rename "Preview/Recap" category to "Preview/Recap/Hook" ([#3245](https://github.com/ReVanced/revanced-patches/issues/3245)) ([2cd2453](https://github.com/ReVanced/revanced-patches/commit/2cd2453658622f369b6449d5c8c33326384c2679))
|
||||||
|
|
||||||
|
## [2.196.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.196.1-dev.2...v2.196.1-dev.3) (2023-11-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Nyx Music Plaer - Unlock pro:** Constrain to last working version ([96d24a3](https://github.com/ReVanced/revanced-patches/commit/96d24a3e2ef6bd323aa44a05aaf122683898e90a))
|
||||||
|
|
||||||
|
## [2.196.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.196.1-dev.1...v2.196.1-dev.2) (2023-11-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube:** Rename `Restore old seekbar thumbnails` and `Restore old quality menu` ([#3235](https://github.com/ReVanced/revanced-patches/issues/3235)) ([7e3ffc8](https://github.com/ReVanced/revanced-patches/commit/7e3ffc88631da47a032cb29a4a30fd8f5679542d))
|
||||||
|
|
||||||
|
## [2.196.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.196.0...v2.196.1-dev.1) (2023-11-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Theme:** Use consistent patch option descriptions ([#3231](https://github.com/ReVanced/revanced-patches/issues/3231)) ([c84a940](https://github.com/ReVanced/revanced-patches/commit/c84a94075ecba11e826f0b311283ef530563fe93))
|
||||||
|
|
||||||
# [2.196.0](https://github.com/ReVanced/revanced-patches/compare/v2.195.0...v2.196.0) (2023-11-04)
|
# [2.196.0](https://github.com/ReVanced/revanced-patches/compare/v2.195.0...v2.196.0) (2023-11-04)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
org.gradle.caching = true
|
org.gradle.caching = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 2.196.0
|
version = 2.197.0-dev.5
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -8,7 +8,10 @@ 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.patches.shared.mapping.misc.ResourceMappingPatch
|
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
|
|
||||||
|
@ -102,4 +105,23 @@ fun BytecodeContext.traverseClassHierarchy(targetClass: MutableClass, callback:
|
||||||
this.findClass(targetClass.superclass ?: return)?.mutableClass?.let {
|
this.findClass(targetClass.superclass ?: return)?.mutableClass?.let {
|
||||||
traverseClassHierarchy(it, callback)
|
traverseClassHierarchy(it, callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the [Reference] of an [Instruction] as [T].
|
||||||
|
*
|
||||||
|
* @param T The type of [Reference] to cast to.
|
||||||
|
* @return The [Reference] as [T] or null
|
||||||
|
* if the [Instruction] is not a [ReferenceInstruction] or the [Reference] is not of type [T].
|
||||||
|
* @see ReferenceInstruction
|
||||||
|
*/
|
||||||
|
inline fun <reified T : Reference> Instruction.getReference() = (this as? ReferenceInstruction)?.reference as? T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the index of the first [Instruction] that matches the predicate.
|
||||||
|
*
|
||||||
|
* @param predicate The predicate to match.
|
||||||
|
* @return The index of the first [Instruction] that matches the predicate.
|
||||||
|
*/
|
||||||
|
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) =
|
||||||
|
this.implementation!!.instructions.indexOfFirst(predicate)
|
|
@ -4,7 +4,9 @@ import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||||
|
import app.revanced.patcher.patch.options.PatchOptionException
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
import java.io.Closeable
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Change package name",
|
name = "Change package name",
|
||||||
|
@ -12,13 +14,11 @@ import org.w3c.dom.Element
|
||||||
use = false
|
use = false
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object ChangePackageNamePatch : ResourcePatch() {
|
object ChangePackageNamePatch : ResourcePatch(), Closeable {
|
||||||
private const val DEFAULT_PACKAGE_NAME_OPTION = "Default"
|
private val packageNameOption = stringPatchOption(
|
||||||
|
|
||||||
private var packageName by stringPatchOption(
|
|
||||||
key = "packageName",
|
key = "packageName",
|
||||||
default = DEFAULT_PACKAGE_NAME_OPTION,
|
default = "Default",
|
||||||
values = mapOf("Default" to DEFAULT_PACKAGE_NAME_OPTION),
|
values = mapOf("Default" to "Default"),
|
||||||
title = "Package name",
|
title = "Package name",
|
||||||
description = "The name of the package to rename the app to.",
|
description = "The name of the package to rename the app to.",
|
||||||
required = true
|
required = true
|
||||||
|
@ -26,19 +26,37 @@ object ChangePackageNamePatch : ResourcePatch() {
|
||||||
it == "Default" || it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$"))
|
it == "Default" || it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private lateinit var context: ResourceContext
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
fun getOriginalPackageName(context: ResourceContext): String {
|
this.context = context
|
||||||
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
}
|
||||||
val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element
|
|
||||||
return manifest.getAttribute("package")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val originalPackageName = getOriginalPackageName(context)
|
/**
|
||||||
if (packageName == DEFAULT_PACKAGE_NAME_OPTION) packageName = "$originalPackageName.revanced"
|
* Set the package name to use.
|
||||||
|
* If this is called multiple times, the first call will set the package name.
|
||||||
|
*
|
||||||
|
* @param fallbackPackageName The package name to use if the user has not already specified a package name.
|
||||||
|
* @return The package name that was set.
|
||||||
|
* @throws PatchOptionException.ValueValidationException If the package name is invalid.
|
||||||
|
*/
|
||||||
|
fun setOrGetFallbackPackageName(fallbackPackageName: String): String {
|
||||||
|
val packageName = this.packageNameOption.value!!
|
||||||
|
|
||||||
context["AndroidManifest.xml"].apply {
|
return if (packageName == this.packageNameOption.default)
|
||||||
readText().replace(originalPackageName, packageName!!).let(::writeText)
|
fallbackPackageName.also { this.packageNameOption.value = it }
|
||||||
}
|
else
|
||||||
|
packageName
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun close() = context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||||
|
val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element
|
||||||
|
val originalPackageName = manifest.getAttribute("package")
|
||||||
|
|
||||||
|
var replacementPackageName = this.packageNameOption.value
|
||||||
|
if (replacementPackageName == this.packageNameOption.default)
|
||||||
|
replacementPackageName = "$originalPackageName.revanced"
|
||||||
|
|
||||||
|
manifest.setAttribute("package", replacementPackageName)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,14 +1,19 @@
|
||||||
package app.revanced.patches.all.screenshot.removerestriction
|
package app.revanced.patches.all.screenshot.removerestriction
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.util.patch.AbstractTransformInstructionsPatch
|
import app.revanced.util.patch.AbstractTransformInstructionsPatch
|
||||||
import app.revanced.util.patch.IMethodCall
|
import app.revanced.util.patch.IMethodCall
|
||||||
import app.revanced.util.patch.Instruction35cInfo
|
import app.revanced.util.patch.Instruction35cInfo
|
||||||
import app.revanced.util.patch.filterMapInstruction35c
|
import app.revanced.util.patch.filterMapInstruction35c
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Remove screenshot restriction",
|
name = "Remove screenshot restriction",
|
||||||
|
@ -22,6 +27,11 @@ object RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Ins
|
||||||
"Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
|
"Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
|
||||||
|
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
super.execute(context)
|
||||||
|
ModifyLayoutParamsFlags().execute(context)
|
||||||
|
}
|
||||||
|
|
||||||
override fun filterMap(
|
override fun filterMap(
|
||||||
classDef: ClassDef,
|
classDef: ClassDef,
|
||||||
method: Method,
|
method: Method,
|
||||||
|
@ -46,6 +56,12 @@ object RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Ins
|
||||||
override val methodParams: Array<String>,
|
override val methodParams: Array<String>,
|
||||||
override val returnType: String
|
override val returnType: String
|
||||||
): IMethodCall {
|
): IMethodCall {
|
||||||
|
AddFlags(
|
||||||
|
"Landroid/view/Window;",
|
||||||
|
"addFlags",
|
||||||
|
arrayOf("I"),
|
||||||
|
"V",
|
||||||
|
),
|
||||||
SetFlags(
|
SetFlags(
|
||||||
"Landroid/view/Window;",
|
"Landroid/view/Window;",
|
||||||
"setFlags",
|
"setFlags",
|
||||||
|
@ -54,3 +70,37 @@ object RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Ins
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ModifyLayoutParamsFlags : AbstractTransformInstructionsPatch<Pair<Instruction22c, Int>>() {
|
||||||
|
override fun filterMap(
|
||||||
|
classDef: ClassDef,
|
||||||
|
method: Method,
|
||||||
|
instruction: Instruction,
|
||||||
|
instructionIndex: Int
|
||||||
|
): Pair<Instruction22c, Int>? {
|
||||||
|
if (instruction.opcode != Opcode.IPUT) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val instruction22c = instruction as Instruction22c
|
||||||
|
val fieldReference = instruction22c.reference as FieldReference
|
||||||
|
|
||||||
|
if (fieldReference.definingClass != "Landroid/view/WindowManager\$LayoutParams;"
|
||||||
|
|| fieldReference.name != "flags"
|
||||||
|
|| fieldReference.type != "I") {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair(instruction22c, instructionIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transform(mutableMethod: MutableMethod, entry: Pair<Instruction22c, Int>) {
|
||||||
|
val (instruction, index) = entry
|
||||||
|
val register = instruction.registerA
|
||||||
|
|
||||||
|
mutableMethod.addInstructions(
|
||||||
|
index,
|
||||||
|
"and-int/lit16 v$register, v$register, -0x2001"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package app.revanced.patches.all.telephony.sim.spoof
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patcher.patch.options.PatchOption
|
||||||
|
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.util.patch.AbstractTransformInstructionsPatch
|
||||||
|
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||||
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
||||||
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Spoof SIM country",
|
||||||
|
description = "Spoofs country information returned by the SIM card provider.",
|
||||||
|
use = false,
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object SpoofSimCountryPatch : AbstractTransformInstructionsPatch<Pair<Int, String>>() {
|
||||||
|
private val isoValidator: PatchOption<String>.(String?) -> Boolean =
|
||||||
|
{ it: String? -> it?.uppercase() in Locale.getISOCountries() || it == null }
|
||||||
|
|
||||||
|
private val networkCountryIso by stringPatchOption(
|
||||||
|
"networkCountryIso",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"Network ISO Country Code",
|
||||||
|
"ISO-3166-1 alpha-2 country code equivalent of the MCC (Mobile Country Code) " +
|
||||||
|
"of the current registered operator or the cell nearby.",
|
||||||
|
validator = isoValidator
|
||||||
|
)
|
||||||
|
|
||||||
|
private val simCountryIso by stringPatchOption(
|
||||||
|
"simCountryIso",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"Sim ISO Country Code",
|
||||||
|
"ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.",
|
||||||
|
validator = isoValidator
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun filterMap(
|
||||||
|
classDef: ClassDef,
|
||||||
|
method: Method,
|
||||||
|
instruction: Instruction,
|
||||||
|
instructionIndex: Int
|
||||||
|
): Pair<Int, String>? {
|
||||||
|
if (instruction !is ReferenceInstruction) return null
|
||||||
|
|
||||||
|
val reference = instruction.reference as? MethodReference ?: return null
|
||||||
|
|
||||||
|
val match = MethodCall.entries.firstOrNull { search ->
|
||||||
|
MethodUtil.methodSignaturesMatch(reference, search.reference)
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
|
val iso = when (match) {
|
||||||
|
MethodCall.NetworkCountryIso -> networkCountryIso
|
||||||
|
MethodCall.SimCountryIso -> simCountryIso
|
||||||
|
}?.lowercase()
|
||||||
|
|
||||||
|
return iso?.let { instructionIndex to it }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transform(
|
||||||
|
mutableMethod: MutableMethod,
|
||||||
|
entry: Pair<Int, String>
|
||||||
|
) = transformMethodCall(entry, mutableMethod)
|
||||||
|
|
||||||
|
private fun transformMethodCall(
|
||||||
|
entry: Pair<Int, String>,
|
||||||
|
mutableMethod: MutableMethod
|
||||||
|
) {
|
||||||
|
val (instructionIndex, methodCallValue) = entry
|
||||||
|
|
||||||
|
val register = mutableMethod.getInstruction<OneRegisterInstruction>(instructionIndex + 1).registerA
|
||||||
|
|
||||||
|
mutableMethod.replaceInstruction(
|
||||||
|
instructionIndex + 1,
|
||||||
|
"const-string v$register, \"$methodCallValue\""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class MethodCall(
|
||||||
|
val reference: MethodReference
|
||||||
|
) {
|
||||||
|
NetworkCountryIso(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getNetworkCountryIso",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SimCountryIso(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getSimCountryIso",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package app.revanced.patches.facebook.ads.story
|
||||||
|
|
||||||
|
import app.revanced.extensions.exception
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.facebook.ads.story.fingerprints.AdsInsertionFingerprint
|
||||||
|
import app.revanced.patches.facebook.ads.story.fingerprints.FetchMoreAdsFingerprint
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Hide story ads",
|
||||||
|
description = "Hides the ads in the Facebook app stories.",
|
||||||
|
compatiblePackages = [CompatiblePackage("com.facebook.katana")]
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object HideStoryAdsPatch : BytecodePatch(
|
||||||
|
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint)
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) =
|
||||||
|
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint).forEach { fingerprint ->
|
||||||
|
fingerprint.result?.mutableMethod?.replaceInstruction(0, "return-void")
|
||||||
|
?: throw fingerprint.exception
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package app.revanced.patches.facebook.ads.story.fingerprints
|
||||||
|
|
||||||
|
object AdsInsertionFingerprint : FieldMethodFingerprint(fieldValue = "AdBucketDataSourceUtil\$attemptAdsInsertion\$1")
|
|
@ -0,0 +1,3 @@
|
||||||
|
package app.revanced.patches.facebook.ads.story.fingerprints
|
||||||
|
|
||||||
|
object FetchMoreAdsFingerprint : FieldMethodFingerprint(fieldValue = "AdBucketDataSourceUtil\$attemptFetchMoreAds\$1")
|
|
@ -0,0 +1,15 @@
|
||||||
|
package app.revanced.patches.facebook.ads.story.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue
|
||||||
|
|
||||||
|
abstract class FieldMethodFingerprint(fieldValue: String) : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf(),
|
||||||
|
customFingerprint = { methodDef, classDef ->
|
||||||
|
methodDef.name == "run" && classDef.fields.any any@{ field ->
|
||||||
|
if (field.name != "__redex_internal_original_name") return@any false
|
||||||
|
(field.initialValue as? StringEncodedValue)?.value == fieldValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
|
@ -4,18 +4,25 @@ import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.all.misc.packagename.ChangePackageNamePatch
|
||||||
import app.revanced.patches.music.misc.microg.fingerprints.*
|
import app.revanced.patches.music.misc.microg.fingerprints.*
|
||||||
import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME
|
import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME
|
||||||
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
||||||
import app.revanced.patches.youtube.misc.microg.shared.Constants
|
|
||||||
import app.revanced.util.microg.MicroGBytecodeHelper
|
import app.revanced.util.microg.MicroGBytecodeHelper
|
||||||
|
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Vanced MicroG support",
|
name = "Vanced MicroG support",
|
||||||
description = "Allows YouTube Music to run without root and under a different package name.",
|
description = "Allows YouTube Music to run without root and under a different package name.",
|
||||||
dependencies = [MicroGResourcePatch::class],
|
dependencies = [
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
ChangePackageNamePatch::class,
|
||||||
|
MicroGResourcePatch::class,
|
||||||
|
],
|
||||||
|
compatiblePackages = [
|
||||||
|
CompatiblePackage(
|
||||||
|
"com.google.android.apps.youtube.music"
|
||||||
|
)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object MicroGBytecodePatch : BytecodePatch(
|
object MicroGBytecodePatch : BytecodePatch(
|
||||||
|
@ -35,25 +42,29 @@ object MicroGBytecodePatch : BytecodePatch(
|
||||||
// - "com.google.android.gms.phenotype.PACKAGE_NAME",
|
// - "com.google.android.gms.phenotype.PACKAGE_NAME",
|
||||||
// - "com.google.android.gms.phenotype.UPDATE",
|
// - "com.google.android.gms.phenotype.UPDATE",
|
||||||
// - "com.google.android.gms.phenotype",
|
// - "com.google.android.gms.phenotype",
|
||||||
override fun execute(context: BytecodeContext) = MicroGBytecodeHelper.patchBytecode(
|
override fun execute(context: BytecodeContext) {
|
||||||
context,
|
val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(REVANCED_MUSIC_PACKAGE_NAME)
|
||||||
arrayOf(
|
|
||||||
MicroGBytecodeHelper.packageNameTransform(
|
MicroGBytecodeHelper.patchBytecode(
|
||||||
Constants.PACKAGE_NAME,
|
context,
|
||||||
Constants.REVANCED_PACKAGE_NAME
|
arrayOf(
|
||||||
|
MicroGBytecodeHelper.packageNameTransform(
|
||||||
|
MUSIC_PACKAGE_NAME,
|
||||||
|
packageName
|
||||||
|
)
|
||||||
|
),
|
||||||
|
MicroGBytecodeHelper.PrimeMethodTransformationData(
|
||||||
|
PrimeFingerprint,
|
||||||
|
MUSIC_PACKAGE_NAME,
|
||||||
|
packageName
|
||||||
|
),
|
||||||
|
listOf(
|
||||||
|
ServiceCheckFingerprint,
|
||||||
|
GooglePlayUtilityFingerprint,
|
||||||
|
CastDynamiteModuleFingerprint,
|
||||||
|
CastDynamiteModuleV2Fingerprint,
|
||||||
|
CastContextFetchFingerprint
|
||||||
)
|
)
|
||||||
),
|
|
||||||
MicroGBytecodeHelper.PrimeMethodTransformationData(
|
|
||||||
PrimeFingerprint,
|
|
||||||
MUSIC_PACKAGE_NAME,
|
|
||||||
REVANCED_MUSIC_PACKAGE_NAME
|
|
||||||
),
|
|
||||||
listOf(
|
|
||||||
ServiceCheckFingerprint,
|
|
||||||
GooglePlayUtilityFingerprint,
|
|
||||||
CastDynamiteModuleFingerprint,
|
|
||||||
CastDynamiteModuleV2Fingerprint,
|
|
||||||
CastContextFetchFingerprint
|
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package app.revanced.patches.music.misc.microg
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.all.misc.packagename.ChangePackageNamePatch
|
||||||
import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME
|
import app.revanced.patches.music.misc.microg.shared.Constants.MUSIC_PACKAGE_NAME
|
||||||
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_APP_NAME
|
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_APP_NAME
|
||||||
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
||||||
|
@ -14,15 +15,18 @@ import app.revanced.util.microg.MicroGResourceHelper
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
description = "Resource patch to allow YouTube Music ReVanced to run without root " +
|
description = "Resource patch to allow YouTube Music ReVanced to run without root " +
|
||||||
"and under a different package name."
|
"and under a different package name.",
|
||||||
|
dependencies = [ChangePackageNamePatch::class]
|
||||||
)
|
)
|
||||||
object MicroGResourcePatch : ResourcePatch() {
|
object MicroGResourcePatch : ResourcePatch() {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
|
val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(REVANCED_MUSIC_PACKAGE_NAME)
|
||||||
|
|
||||||
// update manifest
|
// update manifest
|
||||||
MicroGResourceHelper.patchManifest(
|
MicroGResourceHelper.patchManifest(
|
||||||
context,
|
context,
|
||||||
MUSIC_PACKAGE_NAME,
|
MUSIC_PACKAGE_NAME,
|
||||||
REVANCED_MUSIC_PACKAGE_NAME,
|
packageName,
|
||||||
REVANCED_MUSIC_APP_NAME
|
REVANCED_MUSIC_APP_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import app.revanced.patches.nyx.misc.pro.fingerprints.CheckProFingerprint
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Unlock pro",
|
name = "Unlock pro",
|
||||||
compatiblePackages = [CompatiblePackage("com.awedea.nyx")]
|
compatiblePackages = [CompatiblePackage("com.awedea.nyx", ["2.2.7"])]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object UnlockProPatch : BytecodePatch(setOf(CheckProFingerprint)) {
|
object UnlockProPatch : BytecodePatch(setOf(CheckProFingerprint)) {
|
||||||
|
|
|
@ -32,21 +32,29 @@ abstract class AbstractPreferenceScreen(
|
||||||
preferences: MutableList<BasePreference> = mutableListOf(),
|
preferences: MutableList<BasePreference> = mutableListOf(),
|
||||||
val categories: MutableList<Category> = mutableListOf()
|
val categories: MutableList<Category> = mutableListOf()
|
||||||
) : BasePreferenceCollection(key, title, preferences) {
|
) : BasePreferenceCollection(key, title, preferences) {
|
||||||
override fun transform(): PreferenceScreen {
|
override fun transform() = PreferenceScreen(
|
||||||
return PreferenceScreen(
|
key,
|
||||||
key,
|
StringResource(
|
||||||
StringResource("${key}_title", title),
|
"${key}_title", title
|
||||||
preferences.sortedBy { it.title.value.removePunctuation().lowercase() } +
|
),
|
||||||
categories.sortedBy { it.title.removePunctuation().lowercase() }.map { it.transform() },
|
preferences.sortedWith(
|
||||||
summary?.let { summary ->
|
compareBy(
|
||||||
StringResource("${key}_summary", summary)
|
{ it is PreferenceScreen },
|
||||||
}
|
{ it.title.value.removePunctuation().lowercase() }
|
||||||
)
|
)
|
||||||
}
|
) + categories.sortedBy {
|
||||||
|
it.title.removePunctuation().lowercase()
|
||||||
|
}.map {
|
||||||
|
it.transform()
|
||||||
|
},
|
||||||
|
summary?.let { summary ->
|
||||||
|
StringResource("${key}_summary", summary)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
private fun ensureScreenInserted() {
|
private fun ensureScreenInserted() {
|
||||||
// Add to screens if not yet done
|
// Add to screens if not yet done
|
||||||
if(!this@AbstractPreferenceScreen.root.contains(this))
|
if (!this@AbstractPreferenceScreen.root.contains(this))
|
||||||
this@AbstractPreferenceScreen.root.add(this)
|
this@AbstractPreferenceScreen.root.add(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +67,7 @@ abstract class AbstractPreferenceScreen(
|
||||||
key: String,
|
key: String,
|
||||||
title: String,
|
title: String,
|
||||||
preferences: MutableList<BasePreference> = mutableListOf()
|
preferences: MutableList<BasePreference> = mutableListOf()
|
||||||
): BasePreferenceCollection(key, title, preferences) {
|
) : BasePreferenceCollection(key, title, preferences) {
|
||||||
override fun transform(): PreferenceCategory {
|
override fun transform(): PreferenceCategory {
|
||||||
return PreferenceCategory(
|
return PreferenceCategory(
|
||||||
key,
|
key,
|
||||||
|
@ -72,7 +80,7 @@ abstract class AbstractPreferenceScreen(
|
||||||
ensureScreenInserted()
|
ensureScreenInserted()
|
||||||
|
|
||||||
// Add to categories if not yet done
|
// Add to categories if not yet done
|
||||||
if(!this@Screen.categories.contains(this))
|
if (!this@Screen.categories.contains(this))
|
||||||
this@Screen.categories.add(this)
|
this@Screen.categories.add(this)
|
||||||
|
|
||||||
this.preferences.addAll(preferences)
|
this.preferences.addAll(preferences)
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock
|
|
||||||
|
|
||||||
import app.revanced.extensions.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
import app.revanced.patches.twelvewidgets.unlock.fingerprints.*
|
|
||||||
|
|
||||||
@Patch(
|
|
||||||
name = "Unlock paid widgets",
|
|
||||||
description = "Unlocks paid widgets of the app",
|
|
||||||
compatiblePackages = [CompatiblePackage("com.dci.dev.androidtwelvewidgets")]
|
|
||||||
)
|
|
||||||
@Suppress("unused")
|
|
||||||
object UnlockPaidWidgetsPatch : BytecodePatch(
|
|
||||||
setOf(
|
|
||||||
AgendaDaysWidgetUnlockFingerprint,
|
|
||||||
CalendarBigWidgetUnlockFingerprint,
|
|
||||||
CalendarWideDayEventsWidgetUnlockFingerprint,
|
|
||||||
CalendarWideTimelineWidgetUnlockFingerprint,
|
|
||||||
ScreentimeSmallWidgetUnlockFingerprint,
|
|
||||||
WeatherWidgetUnlockFingerprint
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
listOf(
|
|
||||||
AgendaDaysWidgetUnlockFingerprint,
|
|
||||||
CalendarBigWidgetUnlockFingerprint,
|
|
||||||
CalendarWideDayEventsWidgetUnlockFingerprint,
|
|
||||||
CalendarWideTimelineWidgetUnlockFingerprint,
|
|
||||||
ScreentimeSmallWidgetUnlockFingerprint,
|
|
||||||
WeatherWidgetUnlockFingerprint
|
|
||||||
).map { fingerprint ->
|
|
||||||
fingerprint.result?.mutableMethod ?: throw fingerprint.exception
|
|
||||||
}.forEach { method ->
|
|
||||||
method.apply {
|
|
||||||
removeInstructions(4, 3)
|
|
||||||
addInstructions(
|
|
||||||
implementation?.instructions?.size!!,
|
|
||||||
"""
|
|
||||||
const/4 v1, 0x0
|
|
||||||
invoke-virtual {v0, v1}, Landroid/view/View;->setVisibility(I)V
|
|
||||||
return-object v0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock.fingerprints
|
|
||||||
|
|
||||||
object AgendaDaysWidgetUnlockFingerprint : MethodUnlockFingerprint("AgendaDaysWidgetConfigureActivity")
|
|
|
@ -1,3 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock.fingerprints
|
|
||||||
|
|
||||||
object CalendarBigWidgetUnlockFingerprint : MethodUnlockFingerprint("CalendarBigWidgetConfigureActivity")
|
|
|
@ -1,4 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock.fingerprints
|
|
||||||
|
|
||||||
object CalendarWideDayEventsWidgetUnlockFingerprint :
|
|
||||||
MethodUnlockFingerprint("CalendarWideDayEventsWidgetConfigureActivity")
|
|
|
@ -1,4 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock.fingerprints
|
|
||||||
|
|
||||||
object CalendarWideTimelineWidgetUnlockFingerprint :
|
|
||||||
MethodUnlockFingerprint("CalendarWideTimelineWidgetConfigureActivity")
|
|
|
@ -1,12 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
|
|
||||||
abstract class MethodUnlockFingerprint(private val className: String) : MethodFingerprint(
|
|
||||||
"L",
|
|
||||||
strings = listOf("binding.addButton"),
|
|
||||||
customFingerprint = { methodDef, _ ->
|
|
||||||
methodDef.definingClass.endsWith("/$className;")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock.fingerprints
|
|
||||||
|
|
||||||
object ScreentimeSmallWidgetUnlockFingerprint : MethodUnlockFingerprint("ScreentimeSmallWidgetConfigureActivity")
|
|
|
@ -1,3 +0,0 @@
|
||||||
package app.revanced.patches.twelvewidgets.unlock.fingerprints
|
|
||||||
|
|
||||||
object WeatherWidgetUnlockFingerprint : MethodUnlockFingerprint("WeatherWidgetConfigureActivity")
|
|
|
@ -17,7 +17,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
|
||||||
name = "Block audio ads",
|
name = "Block audio ads",
|
||||||
description = "Blocks audio ads in streams and VODs.",
|
description = "Blocks audio ads in streams and VODs.",
|
||||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||||
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0"])],
|
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0", "17.0.0", "17.1.0"])],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object AudioAdsPatch : BytecodePatch(
|
object AudioAdsPatch : BytecodePatch(
|
||||||
|
|
|
@ -18,7 +18,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
|
||||||
name = "Block embedded ads",
|
name = "Block embedded ads",
|
||||||
description = "Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.",
|
description = "Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.",
|
||||||
dependencies = [VideoAdsPatch::class, IntegrationsPatch::class, SettingsPatch::class],
|
dependencies = [VideoAdsPatch::class, IntegrationsPatch::class, SettingsPatch::class],
|
||||||
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0"])]
|
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0", "17.0.0", "17.1.0"])]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object EmbeddedAdsPatch : BytecodePatch(
|
object EmbeddedAdsPatch : BytecodePatch(
|
||||||
|
|
|
@ -21,7 +21,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
|
||||||
name = "Block video ads",
|
name = "Block video ads",
|
||||||
description = "Blocks video ads in streams and VODs.",
|
description = "Blocks video ads in streams and VODs.",
|
||||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||||
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0"])]
|
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0", "17.0.0", "17.1.0"])]
|
||||||
)
|
)
|
||||||
object VideoAdsPatch : AbstractAdPatch(
|
object VideoAdsPatch : AbstractAdPatch(
|
||||||
"Lapp/revanced/twitch/patches/VideoAdsPatch;->shouldBlockVideoAds()Z",
|
"Lapp/revanced/twitch/patches/VideoAdsPatch;->shouldBlockVideoAds()Z",
|
||||||
|
|
|
@ -22,7 +22,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
|
||||||
name = "Show deleted messages",
|
name = "Show deleted messages",
|
||||||
description = "Shows deleted chat messages behind a clickable spoiler.",
|
description = "Shows deleted chat messages behind a clickable spoiler.",
|
||||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||||
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0"])]
|
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0", "17.0.0", "17.1.0"])]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object ShowDeletedMessagesPatch : BytecodePatch(
|
object ShowDeletedMessagesPatch : BytecodePatch(
|
||||||
|
|
|
@ -17,7 +17,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
|
||||||
name = "Auto claim channel points",
|
name = "Auto claim channel points",
|
||||||
description = "Automatically claim Channel Points.",
|
description = "Automatically claim Channel Points.",
|
||||||
dependencies = [SettingsPatch::class],
|
dependencies = [SettingsPatch::class],
|
||||||
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0"])]
|
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0", "17.0.0", "17.1.0"])]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object AutoClaimChannelPointPatch : BytecodePatch(
|
object AutoClaimChannelPointPatch : BytecodePatch(
|
||||||
|
|
|
@ -33,7 +33,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -27,7 +27,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -31,7 +31,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,7 +26,10 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,7 +26,10 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -24,7 +24,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
[
|
[
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -27,14 +27,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube",
|
"com.google.android.youtube",
|
||||||
[
|
[
|
||||||
"18.16.37",
|
"18.43.45",
|
||||||
"18.19.35",
|
"18.44.41",
|
||||||
"18.20.39",
|
"18.45.41"
|
||||||
"18.23.35",
|
|
||||||
"18.29.38",
|
|
||||||
"18.32.39",
|
|
||||||
"18.37.36",
|
|
||||||
"18.38.44"
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -64,8 +59,8 @@ object EnableSeekbarTappingPatch : BytecodePatch(
|
||||||
.reference as MethodReference
|
.reference as MethodReference
|
||||||
|
|
||||||
buildMap {
|
buildMap {
|
||||||
put("O", getReference(patternScanResult.endIndex))
|
|
||||||
put("N", getReference(patternScanResult.startIndex))
|
put("N", getReference(patternScanResult.startIndex))
|
||||||
|
put("O", getReference(patternScanResult.endIndex))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
package app.revanced.patches.youtube.interaction.seekbar
|
||||||
|
|
||||||
|
import app.revanced.extensions.exception
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
|
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.DoubleSpeedSeekNoticeFingerprint
|
||||||
|
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SlideToSeekFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Enable slide to seek",
|
||||||
|
description = "Enable slide to seek instead of playing at 2x speed.",
|
||||||
|
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||||
|
compatiblePackages = [
|
||||||
|
CompatiblePackage(
|
||||||
|
"com.google.android.youtube",
|
||||||
|
[
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object EnableSlideToSeekPatch : BytecodePatch(
|
||||||
|
setOf(
|
||||||
|
SlideToSeekFingerprint,
|
||||||
|
DoubleSpeedSeekNoticeFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SlideToSeekPatch;"
|
||||||
|
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_slide_to_seek",
|
||||||
|
StringResource(
|
||||||
|
"revanced_slide_to_seek_title",
|
||||||
|
"Enable slide to seek"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_slide_to_seek_summary_on",
|
||||||
|
"Slide to seek is enabled"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_slide_to_seek_summary_off",
|
||||||
|
"Slide to seek is not enabled"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
arrayOf(
|
||||||
|
// Restore the behaviour to slide to seek.
|
||||||
|
SlideToSeekFingerprint,
|
||||||
|
// Disable the double speed seek notice.
|
||||||
|
DoubleSpeedSeekNoticeFingerprint
|
||||||
|
).map {
|
||||||
|
it.result ?: throw it.exception
|
||||||
|
}.forEach {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
||||||
|
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val isEnabledRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"""
|
||||||
|
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->isSlideToSeekDisabled()Z
|
||||||
|
move-result v$isEnabledRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
object DoubleSpeedSeekNoticeFingerprint : LiteralValueFingerprint(
|
||||||
|
returnType = "Z",
|
||||||
|
parameters = emptyList(),
|
||||||
|
opcodes = listOf(Opcode.MOVE_RESULT),
|
||||||
|
literalSupplier = { 45411330 }
|
||||||
|
)
|
|
@ -4,6 +4,10 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
object IsSwipingUpFingerprint : MethodFingerprint(
|
object IsSwipingUpFingerprint : MethodFingerprint(
|
||||||
|
returnType = "Z",
|
||||||
parameters = listOf("Landroid/view/MotionEvent;", "J"),
|
parameters = listOf("Landroid/view/MotionEvent;", "J"),
|
||||||
opcodes = listOf(Opcode.SGET_OBJECT)
|
opcodes = listOf(
|
||||||
|
Opcode.SGET_OBJECT,
|
||||||
|
Opcode.IGET_OBJECT
|
||||||
|
)
|
||||||
)
|
)
|
|
@ -1,8 +1,8 @@
|
||||||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ object OnTouchEventHandlerFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.PUBLIC,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.PUBLIC,
|
||||||
parameters = listOf("L"),
|
parameters = listOf("L"),
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.INVOKE_VIRTUAL, // oMethodReference
|
Opcode.INVOKE_VIRTUAL, // nMethodReference
|
||||||
Opcode.RETURN,
|
Opcode.RETURN,
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
Opcode.IGET_BOOLEAN,
|
Opcode.IGET_BOOLEAN,
|
||||||
|
@ -23,10 +23,9 @@ object OnTouchEventHandlerFingerprint : MethodFingerprint(
|
||||||
Opcode.INT_TO_FLOAT,
|
Opcode.INT_TO_FLOAT,
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.MOVE_RESULT,
|
Opcode.MOVE_RESULT,
|
||||||
Opcode.IF_NEZ,
|
Opcode.IF_EQZ,
|
||||||
Opcode.RETURN,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.INVOKE_VIRTUAL, // pMethodReference
|
Opcode.INVOKE_VIRTUAL, // oMethodReference
|
||||||
),
|
),
|
||||||
customFingerprint = { methodDef, _ -> methodDef.name == "onTouchEvent" }
|
customFingerprint = { methodDef, _ -> methodDef.name == "onTouchEvent" }
|
||||||
)
|
)
|
|
@ -0,0 +1,11 @@
|
||||||
|
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
object SlideToSeekFingerprint : LiteralValueFingerprint(
|
||||||
|
returnType = "Z",
|
||||||
|
parameters = emptyList(),
|
||||||
|
opcodes = listOf(Opcode.MOVE_RESULT),
|
||||||
|
literalSupplier = { 45411329 }
|
||||||
|
)
|
|
@ -33,7 +33,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -31,7 +31,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -29,7 +29,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -39,7 +39,10 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -30,7 +30,10 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -15,7 +15,6 @@ import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUti
|
||||||
import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.injectHook
|
import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.injectHook
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
|
@ -37,7 +36,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -98,6 +100,10 @@ object NavigationButtonsPatch : BytecodePatch(
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_navigation_buttons_preference_screen_summary",
|
||||||
|
"Hide or change buttons in the navigation bar"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -177,13 +183,7 @@ object NavigationButtonsPatch : BytecodePatch(
|
||||||
}
|
}
|
||||||
|
|
||||||
PivotBarCreateButtonViewFingerprint.result!!.apply {
|
PivotBarCreateButtonViewFingerprint.result!!.apply {
|
||||||
val insertIndex = mutableMethod.implementation!!.instructions.let {
|
val insertIndex = scanResult.patternScanResult!!.endIndex
|
||||||
val scanStart = scanResult.patternScanResult!!.endIndex
|
|
||||||
|
|
||||||
scanStart + it.subList(scanStart, it.size - 1).indexOfFirst { instruction ->
|
|
||||||
instruction.opcode == Opcode.INVOKE_STATIC
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inject hooks
|
* Inject hooks
|
||||||
|
|
|
@ -5,7 +5,9 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
|
object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.MOVE_OBJECT,
|
Opcode.INVOKE_DIRECT_RANGE,
|
||||||
Opcode.INVOKE_DIRECT_RANGE, // unique instruction anchor
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.INVOKE_STATIC
|
||||||
)
|
)
|
||||||
)
|
)
|
|
@ -34,7 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,7 +28,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -32,7 +32,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -25,7 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -20,7 +20,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube", [
|
"com.google.android.youtube", [
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,10 +11,7 @@ import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.shared.settings.preference.impl.InputType
|
import app.revanced.patches.shared.settings.preference.impl.*
|
||||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
|
||||||
import app.revanced.patches.shared.settings.preference.impl.TextPreference
|
|
||||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
|
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
|
||||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
|
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
|
||||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
|
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
|
||||||
|
@ -23,6 +20,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch.PreferenceScreen
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Hide layout components",
|
name = "Hide layout components",
|
||||||
|
@ -36,7 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
"com.google.android.youtube", [
|
"com.google.android.youtube", [
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -45,8 +46,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
object HideLayoutComponentsPatch : BytecodePatch(
|
object HideLayoutComponentsPatch : BytecodePatch(
|
||||||
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint)
|
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint)
|
||||||
) {
|
) {
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/integrations/patches/components/LayoutComponentsFilter;"
|
"Lapp/revanced/integrations/patches/components/LayoutComponentsFilter;"
|
||||||
|
private const val DESCRIPTION_COMPONENTS_FILTER_CLASS_NAME =
|
||||||
|
"Lapp/revanced/integrations/patches/components/DescriptionComponentsFilter;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
PreferenceScreen.LAYOUT.addPreferences(
|
PreferenceScreen.LAYOUT.addPreferences(
|
||||||
|
@ -284,7 +287,95 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||||
StringResource("revanced_hide_chips_shelf_on", "Chips shelf is hidden"),
|
StringResource("revanced_hide_chips_shelf_on", "Chips shelf is hidden"),
|
||||||
StringResource("revanced_hide_chips_shelf_off", "Chips shelf is shown")
|
StringResource("revanced_hide_chips_shelf_off", "Chips shelf is shown")
|
||||||
),
|
),
|
||||||
app.revanced.patches.shared.settings.preference.impl.PreferenceScreen(
|
PreferenceScreen(
|
||||||
|
"revanced_hide_description_components_preference_screen",
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_description_components_preference_screen_title",
|
||||||
|
"Hide components in the video description"
|
||||||
|
),
|
||||||
|
listOf(
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_info_cards_section",
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_info_cards_section_title",
|
||||||
|
"Hide info cards section"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_info_cards_section_summary_on",
|
||||||
|
"Info cards section is hidden"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_info_cards_section_summary_off",
|
||||||
|
"Info cards section is shown"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_game_section",
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_game_section_title",
|
||||||
|
"Hide game section"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_game_section_summary_on",
|
||||||
|
"Game section is hidden"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_game_section_summary_off",
|
||||||
|
"Game section is shown"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_music_section",
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_music_section_title",
|
||||||
|
"Hide music section"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_music_section_summary_on",
|
||||||
|
"Music section is hidden"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_music_section_summary_off",
|
||||||
|
"Music section is shown"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_podcast_section",
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_podcast_section_title",
|
||||||
|
"Hide podcast section"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_podcast_section_summary_on",
|
||||||
|
"Podcast section is hidden"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_podcast_section_summary_off",
|
||||||
|
"Podcast section is shown"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_hide_transcript_section",
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_transcript_section_title",
|
||||||
|
"Hide transcript section"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_transcript_section_summary_on",
|
||||||
|
"Transcript section is hidden"
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_transcript_section_summary_off",
|
||||||
|
"Transcript section is shown"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_hide_description_components_preference_screen_summary",
|
||||||
|
"Hide components under the video description"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
PreferenceScreen(
|
||||||
"revanced_custom_filter_preference_screen",
|
"revanced_custom_filter_preference_screen",
|
||||||
StringResource("revanced_custom_filter_preference_screen_title", "Custom filter"),
|
StringResource("revanced_custom_filter_preference_screen_title", "Custom filter"),
|
||||||
listOf(
|
listOf(
|
||||||
|
@ -313,11 +404,16 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||||
),
|
),
|
||||||
inputType = InputType.TEXT_MULTI_LINE
|
inputType = InputType.TEXT_MULTI_LINE
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_custom_filter_preference_screen_summary",
|
||||||
|
"Hide components using custom filters"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
LithoFilterPatch.addFilter(DESCRIPTION_COMPONENTS_FILTER_CLASS_NAME)
|
||||||
|
|
||||||
// region Mix playlists
|
// region Mix playlists
|
||||||
|
|
||||||
|
@ -327,12 +423,15 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||||
|
|
||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
|
val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
|
||||||
val byteBufferRegister = getInstruction<FiveRegisterInstruction>(consumeByteBufferIndex).registerD
|
val conversionContextRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(consumeByteBufferIndex - 2).registerA
|
||||||
|
val byteBufferRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(consumeByteBufferIndex).registerD
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
result.scanResult.patternScanResult!!.startIndex,
|
consumeByteBufferIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static {v$byteBufferRegister}, $FILTER_CLASS_DESCRIPTOR->filterMixPlaylists([B)Z
|
invoke-static {v$conversionContextRegister, v$byteBufferRegister}, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->filterMixPlaylists(Ljava/lang/Object;[B)Z
|
||||||
move-result v0 # Conveniently same register happens to be free.
|
move-result v0 # Conveniently same register happens to be free.
|
||||||
if-nez v0, :return_empty_component
|
if-nez v0, :return_empty_component
|
||||||
""",
|
""",
|
||||||
|
@ -355,7 +454,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||||
addInstructions(
|
addInstructions(
|
||||||
index,
|
index,
|
||||||
"""
|
"""
|
||||||
invoke-static {}, $FILTER_CLASS_DESCRIPTOR->showWatermark()Z
|
invoke-static {}, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->showWatermark()Z
|
||||||
move-result p2
|
move-result p2
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,7 +36,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -25,7 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -25,7 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,7 +28,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41",
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,7 +33,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -37,7 +37,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,7 +19,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube", [
|
"com.google.android.youtube", [
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,7 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
package app.revanced.patches.youtube.layout.hide.time.fingerprints
|
package app.revanced.patches.youtube.layout.hide.time.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
@FuzzyPatternScanMethod(1)
|
@FuzzyPatternScanMethod(1)
|
||||||
object TimeCounterFingerprint : MethodFingerprint(
|
object TimeCounterFingerprint : MethodFingerprint(
|
||||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
|
"V",
|
||||||
Opcode.IGET_OBJECT,
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
emptyList(),
|
||||||
|
listOf(
|
||||||
|
Opcode.SUB_LONG_2ADDR,
|
||||||
Opcode.IGET_WIDE,
|
Opcode.IGET_WIDE,
|
||||||
Opcode.CONST_WIDE_16,
|
Opcode.SUB_LONG_2ADDR,
|
||||||
Opcode.CMP_LONG,
|
|
||||||
Opcode.IF_LEZ,
|
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
Opcode.IF_EQZ,
|
Opcode.INVOKE_STATIC,
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.MOVE_RESULT,
|
Opcode.IGET_WIDE,
|
||||||
Opcode.IF_EQZ,
|
Opcode.IGET_WIDE,
|
||||||
Opcode.GOTO,
|
Opcode.SUB_LONG_2ADDR
|
||||||
)
|
)
|
||||||
)
|
)
|
|
@ -26,7 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -20,7 +20,10 @@ import org.w3c.dom.Element
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package app.revanced.patches.youtube.layout.returnyoutubedislike
|
package app.revanced.patches.youtube.layout.returnyoutubedislike
|
||||||
|
|
||||||
import app.revanced.extensions.exception
|
import app.revanced.extensions.exception
|
||||||
|
import app.revanced.extensions.getReference
|
||||||
|
import app.revanced.extensions.indexOfFirstInstruction
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
@ -9,6 +11,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.*
|
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.*
|
||||||
|
@ -20,6 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Return YouTube Dislike",
|
name = "Return YouTube Dislike",
|
||||||
|
@ -32,7 +36,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
PlayerTypeHookPatch::class,
|
PlayerTypeHookPatch::class,
|
||||||
],
|
],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage("com.google.android.youtube", ["18.37.36", "18.38.44"])
|
CompatiblePackage(
|
||||||
|
"com.google.android.youtube", [
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
|
]
|
||||||
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@ -44,6 +54,8 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||||
LikeFingerprint,
|
LikeFingerprint,
|
||||||
DislikeFingerprint,
|
DislikeFingerprint,
|
||||||
RemoveLikeFingerprint,
|
RemoveLikeFingerprint,
|
||||||
|
RollingNumberSetterFingerprint,
|
||||||
|
RollingNumberTextViewFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
|
@ -138,7 +150,77 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Hook for non litho Short videos.
|
// region Hook rolling numbers.
|
||||||
|
|
||||||
|
RollingNumberSetterFingerprint.result?.let {
|
||||||
|
val dislikesIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val insertIndex = 1
|
||||||
|
|
||||||
|
val charSequenceInstanceRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(0).registerA
|
||||||
|
val charSequenceFieldReference =
|
||||||
|
getInstruction<ReferenceInstruction>(dislikesIndex).reference.toString()
|
||||||
|
|
||||||
|
val registerCount = implementation!!.registerCount
|
||||||
|
|
||||||
|
// This register is being overwritten, so it is free to use.
|
||||||
|
val freeRegister = registerCount - 1
|
||||||
|
val conversionContextRegister = registerCount - parameters.size + 1
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
insertIndex,
|
||||||
|
"""
|
||||||
|
iget-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference
|
||||||
|
invoke-static {v$conversionContextRegister, v$freeRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onRollingNumberLoaded(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;
|
||||||
|
move-result-object v$freeRegister
|
||||||
|
iput-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw RollingNumberSetterFingerprint.exception
|
||||||
|
|
||||||
|
// The rolling number Span is missing styling since it's initially set as a String.
|
||||||
|
// Modify the UI text view and use the styled like/dislike Span.
|
||||||
|
RollingNumberTextViewFingerprint.result?.let {
|
||||||
|
// Initial TextView is set in this method.
|
||||||
|
val initiallyCreatedTextViewMethod = it.mutableMethod
|
||||||
|
|
||||||
|
// Videos less than 24 hours after uploaded, like counts will be updated in real time.
|
||||||
|
// Whenever like counts are updated, TextView is set in this method.
|
||||||
|
val realTimeUpdateTextViewMethod = it.mutableClass.methods.find { method ->
|
||||||
|
method.parameterTypes.first() == "Landroid/graphics/Bitmap;"
|
||||||
|
} ?: throw PatchException("Failed to find realTimeUpdateTextViewMethod")
|
||||||
|
|
||||||
|
arrayOf(
|
||||||
|
initiallyCreatedTextViewMethod,
|
||||||
|
realTimeUpdateTextViewMethod
|
||||||
|
).forEach { insertMethod ->
|
||||||
|
insertMethod.apply {
|
||||||
|
val setTextIndex = indexOfFirstInstruction {
|
||||||
|
getReference<MethodReference>()?.name == "setText"
|
||||||
|
}
|
||||||
|
|
||||||
|
val textViewRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setTextIndex).registerC
|
||||||
|
val textSpanRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setTextIndex).registerD
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
setTextIndex,
|
||||||
|
"""
|
||||||
|
invoke-static {v$textViewRegister, v$textSpanRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||||
|
move-result-object v$textSpanRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: throw RollingNumberTextViewFingerprint.exception
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Hook for non-litho Short videos.
|
||||||
|
|
||||||
ShortsTextViewFingerprint.result?.let {
|
ShortsTextViewFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
|
@ -167,7 +249,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||||
move-result v0
|
move-result v0
|
||||||
if-eqz v0, :ryd_disabled
|
if-eqz v0, :ryd_disabled
|
||||||
return-void
|
return-void
|
||||||
|
|
||||||
:is_like
|
:is_like
|
||||||
:ryd_disabled
|
:ryd_disabled
|
||||||
nop
|
nop
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
object RollingNumberSetterFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.INVOKE_DIRECT,
|
||||||
|
Opcode.IGET_OBJECT
|
||||||
|
),
|
||||||
|
strings = listOf("RollingNumberType required properties missing! Need updateCount, fontName, color and fontSize.")
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
object RollingNumberTextViewFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = listOf("L", "F", "F"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IPUT,
|
||||||
|
null, // invoke-direct or invoke-virtual
|
||||||
|
Opcode.IPUT_OBJECT,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.RETURN_VOID
|
||||||
|
),
|
||||||
|
customFingerprint = custom@{ _, classDef ->
|
||||||
|
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;"
|
||||||
|
}
|
||||||
|
)
|
|
@ -12,7 +12,7 @@ object ShortsTextViewFingerprint : MethodFingerprint(
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.INVOKE_SUPER, // first instruction of method
|
Opcode.INVOKE_SUPER, // first instruction of method
|
||||||
Opcode.IF_NEZ,
|
Opcode.IF_NEZ,
|
||||||
Opcode.RETURN_VOID,
|
null,
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.CHECK_CAST,
|
Opcode.CHECK_CAST,
|
||||||
|
|
|
@ -18,7 +18,7 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
null,
|
||||||
Opcode.INVOKE_VIRTUAL, // Register C is atomic reference
|
Opcode.INVOKE_VIRTUAL, // Register C is atomic reference
|
||||||
Opcode.MOVE_RESULT_OBJECT, // Register A is char sequence
|
Opcode.MOVE_RESULT_OBJECT, // Register A is char sequence
|
||||||
Opcode.CHECK_CAST,
|
Opcode.CHECK_CAST,
|
||||||
|
|
|
@ -21,6 +21,7 @@ object TextComponentContextFingerprint : MethodFingerprint(
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
Opcode.IGET_OBJECT, // conversion context field name
|
Opcode.IGET_OBJECT, // conversion context field name
|
||||||
)
|
)
|
||||||
)
|
)
|
|
@ -29,7 +29,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -69,7 +71,7 @@ object WideSearchbarPatch : BytecodePatch(
|
||||||
* @param fromFingerprint The fingerprint to walk the method on.
|
* @param fromFingerprint The fingerprint to walk the method on.
|
||||||
* @return The [MutableMethod] which was walked on.
|
* @return The [MutableMethod] which was walked on.
|
||||||
*/
|
*/
|
||||||
fun BytecodeContext.walkMutable(index: Int, fromFingerprint: MethodFingerprint) =
|
private fun BytecodeContext.walkMutable(index: Int, fromFingerprint: MethodFingerprint) =
|
||||||
fromFingerprint.result?.let {
|
fromFingerprint.result?.let {
|
||||||
toMethodWalker(it.method).nextMethod(index, true).getMethod() as MutableMethod
|
toMethodWalker(it.method).nextMethod(index, true).getMethod() as MutableMethod
|
||||||
} ?: throw fromFingerprint.exception
|
} ?: throw fromFingerprint.exception
|
||||||
|
@ -78,7 +80,7 @@ object WideSearchbarPatch : BytecodePatch(
|
||||||
/**
|
/**
|
||||||
* Injects instructions required for certain methods.
|
* Injects instructions required for certain methods.
|
||||||
*/
|
*/
|
||||||
fun MutableMethod.injectSearchBarHook() {
|
private fun MutableMethod.injectSearchBarHook() {
|
||||||
addInstructions(
|
addInstructions(
|
||||||
implementation!!.instructions.size - 1,
|
implementation!!.instructions.size - 1,
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -9,56 +9,59 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.EnableNewSeekbarThumbnailsFingerprint
|
import app.revanced.patches.youtube.layout.seekbar.fingerprints.FullscreenSeekbarThumbnailsFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Enable old seekbar thumbnails",
|
name = "Restore old seekbar thumbnails",
|
||||||
description = "Enables the old seekbar thumbnails that appear above the seekbar instead of in fullscreen.",
|
description = "Restores the old seekbar thumbnails that appear above the seekbar instead of fullscreen thumbnails.",
|
||||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube", [
|
"com.google.android.youtube", [
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object EnableOldSeekbarThumbnailsPatch : BytecodePatch(
|
object RestoreOldSeekbarThumbnailsPatch : BytecodePatch(
|
||||||
setOf(EnableNewSeekbarThumbnailsFingerprint)
|
setOf(FullscreenSeekbarThumbnailsFingerprint)
|
||||||
) {
|
) {
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/integrations/patches/EnableOldSeekbarThumbnailsPatch;"
|
"Lapp/revanced/integrations/patches/RestoreOldSeekbarThumbnailsPatch;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
"revanced_enable_old_seekbar_thumbnails",
|
"revanced_restore_old_seekbar_thumbnails",
|
||||||
StringResource(
|
StringResource(
|
||||||
"revanced_enable_old_seekbar_thumbnails_title",
|
"revanced_restore_old_seekbar_thumbnails_title",
|
||||||
"Enable old seekbar thumbnails"
|
"Restore old seekbar thumbnails"
|
||||||
),
|
),
|
||||||
StringResource(
|
StringResource(
|
||||||
"revanced_enable_old_seekbar_thumbnails_summary_on",
|
"revanced_restore_old_seekbar_thumbnails_summary_on",
|
||||||
"Seekbar thumbnails will appear above the seekbar"
|
"Seekbar thumbnails will appear above the seekbar"
|
||||||
),
|
),
|
||||||
StringResource(
|
StringResource(
|
||||||
"revanced_enable_old_seekbar_thumbnails_summary_off",
|
"revanced_restore_old_seekbar_thumbnails_summary_off",
|
||||||
"Seekbar thumbnails will appear in fullscreen"
|
"Seekbar thumbnails will appear in fullscreen"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
EnableNewSeekbarThumbnailsFingerprint.result?.mutableMethod?.apply {
|
FullscreenSeekbarThumbnailsFingerprint.result?.mutableMethod?.apply {
|
||||||
val moveResultIndex = getInstructions().lastIndex - 1
|
val moveResultIndex = getInstructions().lastIndex - 1
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
moveResultIndex,
|
moveResultIndex,
|
||||||
"invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->enableOldSeekbarThumbnails()Z"
|
"invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->useFullscreenSeekbarThumbnails()Z"
|
||||||
)
|
)
|
||||||
} ?: throw EnableNewSeekbarThumbnailsFingerprint.exception
|
} ?: throw FullscreenSeekbarThumbnailsFingerprint.exception
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,8 +22,12 @@ object SeekbarPreferencesPatch : ResourcePatch(), Closeable {
|
||||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
PreferenceScreen(
|
PreferenceScreen(
|
||||||
"revanced_seekbar_preference_screen",
|
"revanced_seekbar_preference_screen",
|
||||||
StringResource("revanced_seekbar_preference_screen_title", "Seekbar settings"),
|
StringResource("revanced_seekbar_preference_screen_title", "Seekbar"),
|
||||||
seekbarPreferences
|
seekbarPreferences,
|
||||||
|
StringResource(
|
||||||
|
"revanced_seekbar_preference_screen_summary",
|
||||||
|
"Settings for the seekbar."
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.util.patch.LiteralValueFingerprint
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
object EnableNewSeekbarThumbnailsFingerprint : LiteralValueFingerprint(
|
object FullscreenSeekbarThumbnailsFingerprint : LiteralValueFingerprint(
|
||||||
returnType = "Z",
|
returnType = "Z",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
|
@ -12,7 +12,6 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
|
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
|
||||||
import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
|
|
||||||
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
|
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
|
||||||
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
|
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
|
||||||
import app.revanced.patches.youtube.layout.sponsorblock.fingerprints.AppendTimeFingerprint
|
import app.revanced.patches.youtube.layout.sponsorblock.fingerprints.AppendTimeFingerprint
|
||||||
|
@ -23,6 +22,7 @@ import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParen
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
|
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
|
||||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||||
|
import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
|
||||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
@ -45,7 +45,10 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -30,7 +30,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package app.revanced.patches.youtube.layout.startupshortsreset
|
package app.revanced.patches.youtube.layout.startupshortsreset
|
||||||
|
|
||||||
|
import app.revanced.extensions.exception
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
@ -12,8 +13,8 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Disable Shorts on startup",
|
name = "Disable resuming Shorts on startup",
|
||||||
description = "Disables playing YouTube Shorts when launching YouTube.",
|
description = "Disables resuming the Shorts player on app startup if a Short was last opened.",
|
||||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
|
@ -25,39 +26,46 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object DisableShortsOnStartupPatch : BytecodePatch(
|
object DisableResumingShortsOnStartupPatch : BytecodePatch(
|
||||||
setOf(UserWasInShortsFingerprint)
|
setOf(UserWasInShortsFingerprint)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/patches/DisableResumingStartupShortsPlayerPatch;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
"revanced_disable_resuming_shorts_player",
|
"revanced_disable_resuming_shorts_player",
|
||||||
StringResource("revanced_disable_resuming_shorts_player_title", "Disable Shorts player at app startup"),
|
StringResource("revanced_disable_resuming_shorts_player_title", "Disable resuming Shorts player"),
|
||||||
StringResource("revanced_disable_resuming_shorts_player_summary_on", "Shorts player is disabled at app startup"),
|
StringResource("revanced_disable_resuming_shorts_player_summary_on", "Shorts player will not resume on app startup"),
|
||||||
StringResource("revanced_disable_resuming_shorts_player_summary_off", "Shorts player is enabled at app startup")
|
StringResource("revanced_disable_resuming_shorts_player_summary_off", "Shorts player will resume on app startup")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val userWasInShortsResult = UserWasInShortsFingerprint.result!!
|
UserWasInShortsFingerprint.result?.apply {
|
||||||
val userWasInShortsMethod = userWasInShortsResult.mutableMethod
|
val moveResultIndex = scanResult.patternScanResult!!.endIndex
|
||||||
val moveResultIndex = userWasInShortsResult.scanResult.patternScanResult!!.endIndex
|
|
||||||
|
|
||||||
userWasInShortsMethod.addInstructionsWithLabels(
|
mutableMethod.addInstructionsWithLabels(
|
||||||
moveResultIndex + 1,
|
moveResultIndex + 1,
|
||||||
"""
|
"""
|
||||||
invoke-static { }, Lapp/revanced/integrations/patches/DisableStartupShortsPlayerPatch;->disableStartupShortsPlayer()Z
|
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
|
||||||
move-result v5
|
move-result v5
|
||||||
if-eqz v5, :disable_shorts_player
|
if-eqz v5, :disable_shorts_player
|
||||||
return-void
|
return-void
|
||||||
:disable_shorts_player
|
:disable_shorts_player
|
||||||
nop
|
nop
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
} ?: throw UserWasInShortsFingerprint.exception
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,7 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -32,7 +32,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
"com.google.android.youtube",
|
"com.google.android.youtube",
|
||||||
[
|
[
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -82,7 +85,7 @@ object ThemeBytecodePatch : BytecodePatch(
|
||||||
"Light red" to "#FFFFD6D6"
|
"Light red" to "#FFFFD6D6"
|
||||||
),
|
),
|
||||||
title = "Light theme background color",
|
title = "Light theme background color",
|
||||||
description = "Can be a hex color or a color resource reference.",
|
description = "Can be a hex color (#AARRGGBB) or a color resource reference.",
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
|
@ -26,7 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -30,7 +30,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -21,7 +21,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube",
|
"com.google.android.youtube",
|
||||||
[
|
[
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,7 +26,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -18,6 +18,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
|
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
description = "Spoofs the signature to prevent playback issues.",
|
description = "Spoofs the signature to prevent playback issues.",
|
||||||
|
@ -26,14 +27,19 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
PlayerTypeHookPatch::class,
|
PlayerTypeHookPatch::class,
|
||||||
PlayerResponseMethodHookPatch::class,
|
PlayerResponseMethodHookPatch::class,
|
||||||
VideoInformationPatch::class,
|
VideoInformationPatch::class,
|
||||||
|
SpoofSignatureResourcePatch::class
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
object SpoofSignaturePatch : BytecodePatch(
|
object SpoofSignaturePatch : BytecodePatch(
|
||||||
setOf(
|
setOf(
|
||||||
PlayerResponseModelImplFingerprint,
|
PlayerResponseModelImplGeneralFingerprint,
|
||||||
StoryboardThumbnailParentFingerprint,
|
PlayerResponseModelImplLiveStreamFingerprint,
|
||||||
|
PlayerResponseModelImplRecommendedLevel,
|
||||||
StoryboardRendererSpecFingerprint,
|
StoryboardRendererSpecFingerprint,
|
||||||
StoryboardRendererInitFingerprint
|
StoryboardRendererDecoderSpecFingerprint,
|
||||||
|
StoryboardRendererDecoderRecommendedLevelFingerprint,
|
||||||
|
StoryboardThumbnailParentFingerprint,
|
||||||
|
ScrubbedPreviewLayoutFingerprint,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
|
@ -42,12 +48,12 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||||
PreferenceScreen(
|
PreferenceScreen(
|
||||||
key = "revanced_spoof_signature_verification",
|
"revanced_spoof_signature_verification",
|
||||||
title = StringResource(
|
StringResource(
|
||||||
"revanced_spoof_signature_verification_title",
|
"revanced_spoof_signature_verification_title",
|
||||||
"Spoof app signature"
|
"Spoof app signature"
|
||||||
),
|
),
|
||||||
preferences = listOf(
|
listOf(
|
||||||
SwitchPreference(
|
SwitchPreference(
|
||||||
"revanced_spoof_signature_verification_enabled",
|
"revanced_spoof_signature_verification_enabled",
|
||||||
StringResource("revanced_spoof_signature_verification_enabled_title", "Spoof app signature"),
|
StringResource("revanced_spoof_signature_verification_enabled_title", "Spoof app signature"),
|
||||||
|
@ -83,7 +89,23 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||||
"App signature not spoofed for feed videos\\n\\n"
|
"App signature not spoofed for feed videos\\n\\n"
|
||||||
+ "Feed videos will play for less than 1 minute before encountering playback issues"
|
+ "Feed videos will play for less than 1 minute before encountering playback issues"
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
SwitchPreference(
|
||||||
|
"revanced_spoof_storyboard",
|
||||||
|
StringResource("revanced_spoof_storyboard_title", "Spoof storyboard"),
|
||||||
|
StringResource("revanced_spoof_storyboard_summary_on", "Storyboard spoofed"),
|
||||||
|
StringResource(
|
||||||
|
"revanced_spoof_storyboard_summary_off",
|
||||||
|
"Storyboard not spoofed\\n\\n"
|
||||||
|
+ "Side effects include:\\n"
|
||||||
|
+ "• No ambient mode\\n"
|
||||||
|
+ "• Seekbar thumbnails are hidden"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
StringResource(
|
||||||
|
"revanced_spoof_signature_verification_summary",
|
||||||
|
"Spoof the app signature to prevent playback issues"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -94,7 +116,8 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||||
)
|
)
|
||||||
|
|
||||||
// Force the seekbar time and chapters to always show up.
|
// Force the seekbar time and chapters to always show up.
|
||||||
// This is used only if the storyboard spec fetch fails, or when viewing paid videos.
|
// This is used if the storyboard spec fetch fails, for viewing paid videos,
|
||||||
|
// or if storyboard spoofing is turned off.
|
||||||
StoryboardThumbnailParentFingerprint.result?.classDef?.let { classDef ->
|
StoryboardThumbnailParentFingerprint.result?.classDef?.let { classDef ->
|
||||||
StoryboardThumbnailFingerprint.also {
|
StoryboardThumbnailFingerprint.also {
|
||||||
it.resolve(
|
it.resolve(
|
||||||
|
@ -124,23 +147,74 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||||
} ?: throw StoryboardThumbnailFingerprint.exception
|
} ?: throw StoryboardThumbnailFingerprint.exception
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// If storyboard spoofing is turned off, then hide the empty seekbar thumbnail view.
|
||||||
* Hook StoryBoard renderer url
|
ScrubbedPreviewLayoutFingerprint.result?.apply {
|
||||||
*/
|
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||||
PlayerResponseModelImplFingerprint.result?.let {
|
mutableMethod.apply {
|
||||||
it.mutableMethod.apply {
|
val imageViewFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||||
val getStoryBoardIndex = it.scanResult.patternScanResult!!.endIndex
|
|
||||||
val getStoryBoardRegister = getInstruction<OneRegisterInstruction>(getStoryBoardIndex).registerA
|
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
getStoryBoardIndex,
|
implementation!!.instructions.lastIndex,
|
||||||
"""
|
"""
|
||||||
invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
|
iget-object v0, p0, $imageViewFieldName # copy imageview field to a register
|
||||||
move-result-object v$getStoryBoardRegister
|
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->seekbarImageViewCreated(Landroid/widget/ImageView;)V
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} ?: throw PlayerResponseModelImplFingerprint.exception
|
} ?: throw ScrubbedPreviewLayoutFingerprint.exception
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook StoryBoard renderer url
|
||||||
|
*/
|
||||||
|
arrayOf(
|
||||||
|
PlayerResponseModelImplGeneralFingerprint,
|
||||||
|
PlayerResponseModelImplLiveStreamFingerprint
|
||||||
|
).forEach { fingerprint ->
|
||||||
|
fingerprint.result?.let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val getStoryBoardIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val getStoryBoardRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(getStoryBoardIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
getStoryBoardIndex,
|
||||||
|
"""
|
||||||
|
invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
|
||||||
|
move-result-object v$getStoryBoardRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw fingerprint.exception
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook recommended seekbar thumbnails quality level.
|
||||||
|
StoryboardRendererDecoderRecommendedLevelFingerprint.result?.let {
|
||||||
|
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val originalValueRegister = it.mutableMethod
|
||||||
|
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
|
||||||
|
|
||||||
|
it.mutableMethod.addInstructions(
|
||||||
|
moveOriginalRecommendedValueIndex + 1, """
|
||||||
|
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
|
||||||
|
move-result v$originalValueRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
} ?: throw StoryboardRendererDecoderRecommendedLevelFingerprint.exception
|
||||||
|
|
||||||
|
// Hook the recommended precise seeking thumbnails quality level.
|
||||||
|
PlayerResponseModelImplRecommendedLevel.result?.let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val originalValueRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
moveOriginalRecommendedValueIndex, """
|
||||||
|
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
|
||||||
|
move-result v$originalValueRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw PlayerResponseModelImplRecommendedLevel.exception
|
||||||
|
|
||||||
StoryboardRendererSpecFingerprint.result?.let {
|
StoryboardRendererSpecFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
|
@ -158,22 +232,18 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||||
}
|
}
|
||||||
} ?: throw StoryboardRendererSpecFingerprint.exception
|
} ?: throw StoryboardRendererSpecFingerprint.exception
|
||||||
|
|
||||||
// Hook recommended value
|
// Hook the seekbar thumbnail decoder and use a NULL spec for live streams.
|
||||||
StoryboardRendererInitFingerprint.result?.let {
|
StoryboardRendererDecoderSpecFingerprint.result?.let {
|
||||||
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex
|
val storyBoardUrlIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
||||||
|
val storyboardUrlRegister =
|
||||||
|
it.mutableMethod.getInstruction<OneRegisterInstruction>(storyBoardUrlIndex).registerA
|
||||||
|
|
||||||
val originalValueRegister = it.mutableMethod
|
it.mutableMethod.addInstructions(
|
||||||
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
|
storyBoardUrlIndex + 1, """
|
||||||
|
invoke-static { v$storyboardUrlRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardDecoderRendererSpec(Ljava/lang/String;)Ljava/lang/String;
|
||||||
it.mutableMethod.apply {
|
move-result-object v$storyboardUrlRegister
|
||||||
addInstructions(
|
"""
|
||||||
moveOriginalRecommendedValueIndex + 1,
|
)
|
||||||
"""
|
} ?: throw StoryboardRendererDecoderSpecFingerprint.exception
|
||||||
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
|
|
||||||
move-result v$originalValueRegister
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} ?: throw StoryboardRendererInitFingerprint.exception
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package app.revanced.patches.youtube.misc.fix.playback
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
|
||||||
|
@Patch(dependencies = [SettingsPatch::class, ResourceMappingPatch::class])
|
||||||
|
object SpoofSignatureResourcePatch : ResourcePatch() {
|
||||||
|
internal var scrubbedPreviewThumbnailResourceId: Long = -1
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext) {
|
||||||
|
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
|
||||||
|
it.type == "id" && it.name == "thumbnail"
|
||||||
|
}.id
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
object PlayerResponseModelImplFingerprint : MethodFingerprint(
|
object PlayerResponseModelImplGeneralFingerprint : MethodFingerprint(
|
||||||
returnType = "Ljava/lang/String;",
|
returnType = "Ljava/lang/String;",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
|
@ -0,0 +1,23 @@
|
||||||
|
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.extensions.containsWideLiteralInstructionValue
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
object PlayerResponseModelImplLiveStreamFingerprint : MethodFingerprint(
|
||||||
|
returnType = "Ljava/lang/String;",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = emptyList(),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.RETURN_OBJECT,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.RETURN_OBJECT
|
||||||
|
),
|
||||||
|
customFingerprint = handler@{ methodDef, _ ->
|
||||||
|
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||||
|
|
||||||
|
methodDef.containsWideLiteralInstructionValue(70276274)
|
||||||
|
}
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.extensions.containsWideLiteralInstructionValue
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
object PlayerResponseModelImplRecommendedLevel : MethodFingerprint(
|
||||||
|
returnType = "I",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = emptyList(),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.SGET_OBJECT,
|
||||||
|
Opcode.IGET,
|
||||||
|
Opcode.RETURN
|
||||||
|
),
|
||||||
|
customFingerprint = handler@{ methodDef, _ ->
|
||||||
|
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||||
|
|
||||||
|
methodDef.containsWideLiteralInstructionValue(55735497)
|
||||||
|
}
|
||||||
|
)
|
|
@ -0,0 +1,27 @@
|
||||||
|
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patches.youtube.misc.fix.playback.SpoofSignatureResourcePatch
|
||||||
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
object ScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
|
||||||
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf("Landroid/content/Context;", "Landroid/util/AttributeSet;", "I", "I"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
Opcode.IPUT_OBJECT, // preview imageview
|
||||||
|
),
|
||||||
|
// This resource is used in ~ 40 different locations, but this method has a distinct list of parameters to match to.
|
||||||
|
literalSupplier = { SpoofSignatureResourcePatch.scrubbedPreviewThumbnailResourceId }
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves to the same method as [StoryboardRendererDecoderSpecFingerprint].
|
||||||
|
*/
|
||||||
|
object StoryboardRendererDecoderRecommendedLevelFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.IPUT_OBJECT,
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
Opcode.MOVE_RESULT
|
||||||
|
),
|
||||||
|
strings = listOf("#-1#")
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves to the same method as [StoryboardRendererDecoderRecommendedLevelFingerprint].
|
||||||
|
*/
|
||||||
|
object StoryboardRendererDecoderSpecFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.INVOKE_INTERFACE, // First instruction of the method.
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.IF_NEZ,
|
||||||
|
),
|
||||||
|
strings = listOf("#-1#")
|
||||||
|
)
|
|
@ -1,15 +0,0 @@
|
||||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
object StoryboardRendererInitFingerprint : MethodFingerprint(
|
|
||||||
strings = listOf("#-1#"),
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.INVOKE_INTERFACE,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.IPUT_OBJECT,
|
|
||||||
Opcode.INVOKE_INTERFACE,
|
|
||||||
Opcode.MOVE_RESULT
|
|
||||||
)
|
|
||||||
)
|
|
|
@ -10,8 +10,8 @@ import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.links.fingerprints.OpenLinksDirectlyPrimaryFingerprint
|
import app.revanced.patches.youtube.misc.links.fingerprints.ABUriParserFingerprint
|
||||||
import app.revanced.patches.youtube.misc.links.fingerprints.OpenLinksDirectlySecondaryFingerprint
|
import app.revanced.patches.youtube.misc.links.fingerprints.HTTPUriParserFingerprint
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
|
||||||
|
@ -23,20 +23,15 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube",
|
"com.google.android.youtube",
|
||||||
[
|
[
|
||||||
"18.16.37",
|
"18.43.45",
|
||||||
"18.19.35",
|
"18.44.41",
|
||||||
"18.20.39",
|
"18.45.41"
|
||||||
"18.23.35",
|
|
||||||
"18.29.38",
|
|
||||||
"18.32.39",
|
|
||||||
"18.37.36",
|
|
||||||
"18.38.44"
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
object BypassURLRedirectsPatch : BytecodePatch(
|
object BypassURLRedirectsPatch : BytecodePatch(
|
||||||
setOf(OpenLinksDirectlyPrimaryFingerprint, OpenLinksDirectlySecondaryFingerprint)
|
setOf(ABUriParserFingerprint, HTTPUriParserFingerprint)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||||
|
@ -48,14 +43,14 @@ object BypassURLRedirectsPatch : BytecodePatch(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
arrayOf(
|
mapOf(
|
||||||
OpenLinksDirectlyPrimaryFingerprint,
|
ABUriParserFingerprint to 7, // Offset to Uri.parse.
|
||||||
OpenLinksDirectlySecondaryFingerprint
|
HTTPUriParserFingerprint to 0 // Offset to Uri.parse.
|
||||||
).map {
|
).map { (fingerprint, offset) ->
|
||||||
it.result ?: throw it.exception
|
(fingerprint.result ?: throw fingerprint.exception) to offset
|
||||||
}.forEach { result ->
|
}.forEach { (result, offset) ->
|
||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
val insertIndex = result.scanResult.patternScanResult!!.startIndex
|
val insertIndex = result.scanResult.patternScanResult!!.startIndex + offset
|
||||||
val uriStringRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
val uriStringRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||||
|
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
|
|
|
@ -30,7 +30,10 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||||
"18.29.38",
|
"18.29.38",
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44"
|
"18.38.44",
|
||||||
|
"18.43.45",
|
||||||
|
"18.44.41",
|
||||||
|
"18.45.41"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,16 +5,25 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
object OpenLinksDirectlyPrimaryFingerprint : MethodFingerprint(
|
object ABUriParserFingerprint : MethodFingerprint(
|
||||||
returnType = "Ljava/lang/Object",
|
returnType = "Ljava/lang/Object",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf("Ljava/lang/Object"),
|
parameters = listOf("Ljava/lang/Object"),
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
|
Opcode.RETURN_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
Opcode.RETURN_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
Opcode.INVOKE_STATIC,
|
Opcode.INVOKE_STATIC,
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.RETURN_OBJECT,
|
Opcode.RETURN_OBJECT,
|
||||||
Opcode.CHECK_CAST,
|
Opcode.CHECK_CAST
|
||||||
Opcode.SGET,
|
),
|
||||||
Opcode.SGET_OBJECT
|
customFingerprint = { methodDef, classDef ->
|
||||||
)
|
// This method is always called "a" because this kind of class always has a single method.
|
||||||
|
methodDef.name == "a" && classDef.methods.count() == 3
|
||||||
|
}
|
||||||
)
|
)
|
|
@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
object OpenLinksDirectlySecondaryFingerprint : MethodFingerprint(
|
object HTTPUriParserFingerprint : MethodFingerprint(
|
||||||
returnType = "Landroid/net/Uri",
|
returnType = "Landroid/net/Uri",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
parameters = listOf("Ljava/lang/String"),
|
parameters = listOf("Ljava/lang/String"),
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue