chore: Merge branch dev to main (#3232)

This commit is contained in:
oSumAtrIX 2023-11-18 05:10:32 +01:00 committed by GitHub
commit cd18216879
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
115 changed files with 1594 additions and 384 deletions

View file

@ -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)

View file

@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
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

View file

@ -8,7 +8,10 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
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.reference.Reference
import com.android.tools.smali.dexlib2.util.MethodUtil
import org.w3c.dom.Node
@ -102,4 +105,23 @@ fun BytecodeContext.traverseClassHierarchy(targetClass: MutableClass, callback:
this.findClass(targetClass.superclass ?: return)?.mutableClass?.let {
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)

View file

@ -4,7 +4,9 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.patcher.patch.options.PatchOptionException
import org.w3c.dom.Element
import java.io.Closeable
@Patch(
name = "Change package name",
@ -12,13 +14,11 @@ import org.w3c.dom.Element
use = false
)
@Suppress("unused")
object ChangePackageNamePatch : ResourcePatch() {
private const val DEFAULT_PACKAGE_NAME_OPTION = "Default"
private var packageName by stringPatchOption(
object ChangePackageNamePatch : ResourcePatch(), Closeable {
private val packageNameOption = stringPatchOption(
key = "packageName",
default = DEFAULT_PACKAGE_NAME_OPTION,
values = mapOf("Default" to DEFAULT_PACKAGE_NAME_OPTION),
default = "Default",
values = mapOf("Default" to "Default"),
title = "Package name",
description = "The name of the package to rename the app to.",
required = true
@ -26,19 +26,37 @@ object ChangePackageNamePatch : ResourcePatch() {
it == "Default" || it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$"))
}
private lateinit var context: ResourceContext
override fun execute(context: ResourceContext) {
fun getOriginalPackageName(context: ResourceContext): String {
context.xmlEditor["AndroidManifest.xml"].use { editor ->
val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element
return manifest.getAttribute("package")
}
}
this.context = context
}
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 {
readText().replace(originalPackageName, packageName!!).let(::writeText)
}
return if (packageName == this.packageNameOption.default)
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)
}
}

View file

@ -1,14 +1,19 @@
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.util.proxy.mutableTypes.MutableMethod
import app.revanced.util.patch.AbstractTransformInstructionsPatch
import app.revanced.util.patch.IMethodCall
import app.revanced.util.patch.Instruction35cInfo
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.Method
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(
name = "Remove screenshot restriction",
@ -22,6 +27,11 @@ object RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Ins
"Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
override fun execute(context: BytecodeContext) {
super.execute(context)
ModifyLayoutParamsFlags().execute(context)
}
override fun filterMap(
classDef: ClassDef,
method: Method,
@ -46,6 +56,12 @@ object RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Ins
override val methodParams: Array<String>,
override val returnType: String
): IMethodCall {
AddFlags(
"Landroid/view/Window;",
"addFlags",
arrayOf("I"),
"V",
),
SetFlags(
"Landroid/view/Window;",
"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"
)
}
}

View file

@ -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;"
)
)
}
}

View file

@ -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
}
}

View file

@ -0,0 +1,3 @@
package app.revanced.patches.facebook.ads.story.fingerprints
object AdsInsertionFingerprint : FieldMethodFingerprint(fieldValue = "AdBucketDataSourceUtil\$attemptAdsInsertion\$1")

View file

@ -0,0 +1,3 @@
package app.revanced.patches.facebook.ads.story.fingerprints
object FetchMoreAdsFingerprint : FieldMethodFingerprint(fieldValue = "AdBucketDataSourceUtil\$attemptFetchMoreAds\$1")

View file

@ -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
}
}
)

View file

@ -4,18 +4,25 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
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.shared.Constants.MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.microg.shared.Constants.REVANCED_MUSIC_PACKAGE_NAME
import app.revanced.patches.youtube.misc.microg.shared.Constants
import app.revanced.util.microg.MicroGBytecodeHelper
@Patch(
name = "Vanced MicroG support",
description = "Allows YouTube Music to run without root and under a different package name.",
dependencies = [MicroGResourcePatch::class],
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
dependencies = [
ChangePackageNamePatch::class,
MicroGResourcePatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.apps.youtube.music"
)
]
)
@Suppress("unused")
object MicroGBytecodePatch : BytecodePatch(
@ -35,25 +42,29 @@ object MicroGBytecodePatch : BytecodePatch(
// - "com.google.android.gms.phenotype.PACKAGE_NAME",
// - "com.google.android.gms.phenotype.UPDATE",
// - "com.google.android.gms.phenotype",
override fun execute(context: BytecodeContext) = MicroGBytecodeHelper.patchBytecode(
context,
arrayOf(
MicroGBytecodeHelper.packageNameTransform(
Constants.PACKAGE_NAME,
Constants.REVANCED_PACKAGE_NAME
override fun execute(context: BytecodeContext) {
val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(REVANCED_MUSIC_PACKAGE_NAME)
MicroGBytecodeHelper.patchBytecode(
context,
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
)
)
}
}

View file

@ -3,6 +3,7 @@ package app.revanced.patches.music.misc.microg
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
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.REVANCED_MUSIC_APP_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(
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() {
override fun execute(context: ResourceContext) {
val packageName = ChangePackageNamePatch.setOrGetFallbackPackageName(REVANCED_MUSIC_PACKAGE_NAME)
// update manifest
MicroGResourceHelper.patchManifest(
context,
MUSIC_PACKAGE_NAME,
REVANCED_MUSIC_PACKAGE_NAME,
packageName,
REVANCED_MUSIC_APP_NAME
)

View file

@ -10,7 +10,7 @@ import app.revanced.patches.nyx.misc.pro.fingerprints.CheckProFingerprint
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("com.awedea.nyx")]
compatiblePackages = [CompatiblePackage("com.awedea.nyx", ["2.2.7"])]
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(setOf(CheckProFingerprint)) {

View file

@ -32,21 +32,29 @@ abstract class AbstractPreferenceScreen(
preferences: MutableList<BasePreference> = mutableListOf(),
val categories: MutableList<Category> = mutableListOf()
) : BasePreferenceCollection(key, title, preferences) {
override fun transform(): PreferenceScreen {
return PreferenceScreen(
key,
StringResource("${key}_title", title),
preferences.sortedBy { it.title.value.removePunctuation().lowercase() } +
categories.sortedBy { it.title.removePunctuation().lowercase() }.map { it.transform() },
summary?.let { summary ->
StringResource("${key}_summary", summary)
}
)
}
override fun transform() = PreferenceScreen(
key,
StringResource(
"${key}_title", title
),
preferences.sortedWith(
compareBy(
{ 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() {
// Add to screens if not yet done
if(!this@AbstractPreferenceScreen.root.contains(this))
if (!this@AbstractPreferenceScreen.root.contains(this))
this@AbstractPreferenceScreen.root.add(this)
}
@ -59,7 +67,7 @@ abstract class AbstractPreferenceScreen(
key: String,
title: String,
preferences: MutableList<BasePreference> = mutableListOf()
): BasePreferenceCollection(key, title, preferences) {
) : BasePreferenceCollection(key, title, preferences) {
override fun transform(): PreferenceCategory {
return PreferenceCategory(
key,
@ -72,7 +80,7 @@ abstract class AbstractPreferenceScreen(
ensureScreenInserted()
// 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.preferences.addAll(preferences)

View file

@ -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
"""
)
}
}
}
}

View file

@ -1,3 +0,0 @@
package app.revanced.patches.twelvewidgets.unlock.fingerprints
object AgendaDaysWidgetUnlockFingerprint : MethodUnlockFingerprint("AgendaDaysWidgetConfigureActivity")

View file

@ -1,3 +0,0 @@
package app.revanced.patches.twelvewidgets.unlock.fingerprints
object CalendarBigWidgetUnlockFingerprint : MethodUnlockFingerprint("CalendarBigWidgetConfigureActivity")

View file

@ -1,4 +0,0 @@
package app.revanced.patches.twelvewidgets.unlock.fingerprints
object CalendarWideDayEventsWidgetUnlockFingerprint :
MethodUnlockFingerprint("CalendarWideDayEventsWidgetConfigureActivity")

View file

@ -1,4 +0,0 @@
package app.revanced.patches.twelvewidgets.unlock.fingerprints
object CalendarWideTimelineWidgetUnlockFingerprint :
MethodUnlockFingerprint("CalendarWideTimelineWidgetConfigureActivity")

View file

@ -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;")
}
)

View file

@ -1,3 +0,0 @@
package app.revanced.patches.twelvewidgets.unlock.fingerprints
object ScreentimeSmallWidgetUnlockFingerprint : MethodUnlockFingerprint("ScreentimeSmallWidgetConfigureActivity")

View file

@ -1,3 +0,0 @@
package app.revanced.patches.twelvewidgets.unlock.fingerprints
object WeatherWidgetUnlockFingerprint : MethodUnlockFingerprint("WeatherWidgetConfigureActivity")

View file

@ -17,7 +17,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
name = "Block audio ads",
description = "Blocks audio ads in streams and VODs.",
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")
object AudioAdsPatch : BytecodePatch(

View file

@ -18,7 +18,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
name = "Block embedded ads",
description = "Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.",
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")
object EmbeddedAdsPatch : BytecodePatch(

View file

@ -21,7 +21,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
name = "Block video ads",
description = "Blocks video ads in streams and VODs.",
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(
"Lapp/revanced/twitch/patches/VideoAdsPatch;->shouldBlockVideoAds()Z",

View file

@ -22,7 +22,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
name = "Show deleted messages",
description = "Shows deleted chat messages behind a clickable spoiler.",
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")
object ShowDeletedMessagesPatch : BytecodePatch(

View file

@ -17,7 +17,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
name = "Auto claim channel points",
description = "Automatically claim Channel Points.",
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")
object AutoClaimChannelPointPatch : BytecodePatch(

View file

@ -33,7 +33,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -27,7 +27,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -31,7 +31,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -26,7 +26,10 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -26,7 +26,10 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
),
]

View file

@ -24,7 +24,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
[
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -27,14 +27,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
CompatiblePackage(
"com.google.android.youtube",
[
"18.16.37",
"18.19.35",
"18.20.39",
"18.23.35",
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]
@ -64,8 +59,8 @@ object EnableSeekbarTappingPatch : BytecodePatch(
.reference as MethodReference
buildMap {
put("O", getReference(patternScanResult.endIndex))
put("N", getReference(patternScanResult.startIndex))
put("O", getReference(patternScanResult.endIndex))
}
}

View file

@ -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
"""
)
}
}
}
}

View file

@ -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 }
)

View file

@ -4,6 +4,10 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
object IsSwipingUpFingerprint : MethodFingerprint(
returnType = "Z",
parameters = listOf("Landroid/view/MotionEvent;", "J"),
opcodes = listOf(Opcode.SGET_OBJECT)
opcodes = listOf(
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT
)
)

View file

@ -1,8 +1,8 @@
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
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.Opcode
@ -12,7 +12,7 @@ object OnTouchEventHandlerFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.PUBLIC,
parameters = listOf("L"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL, // oMethodReference
Opcode.INVOKE_VIRTUAL, // nMethodReference
Opcode.RETURN,
Opcode.IGET_OBJECT,
Opcode.IGET_BOOLEAN,
@ -23,10 +23,9 @@ object OnTouchEventHandlerFingerprint : MethodFingerprint(
Opcode.INT_TO_FLOAT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.RETURN,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL, // pMethodReference
Opcode.INVOKE_VIRTUAL, // oMethodReference
),
customFingerprint = { methodDef, _ -> methodDef.name == "onTouchEvent" }
)

View file

@ -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 }
)

View file

@ -33,7 +33,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -31,7 +31,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
],

View file

@ -29,7 +29,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -39,7 +39,10 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -30,7 +30,10 @@ import com.android.tools.smali.dexlib2.Opcode
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -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.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@ -37,7 +36,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.29.38",
"18.32.39",
"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 {
val insertIndex = mutableMethod.implementation!!.instructions.let {
val scanStart = scanResult.patternScanResult!!.endIndex
scanStart + it.subList(scanStart, it.size - 1).indexOfFirst { instruction ->
instruction.opcode == Opcode.INVOKE_STATIC
}
}
val insertIndex = scanResult.patternScanResult!!.endIndex
/*
* Inject hooks

View file

@ -5,7 +5,9 @@ import com.android.tools.smali.dexlib2.Opcode
object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.MOVE_OBJECT,
Opcode.INVOKE_DIRECT_RANGE, // unique instruction anchor
Opcode.INVOKE_DIRECT_RANGE,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC
)
)

View file

@ -34,7 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -28,7 +28,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -32,7 +32,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -29,7 +29,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -25,7 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -20,7 +20,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
CompatiblePackage(
"com.google.android.youtube", [
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -11,10 +11,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.settings.preference.impl.InputType
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.shared.settings.preference.impl.TextPreference
import app.revanced.patches.shared.settings.preference.impl.*
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.ShowWatermarkFingerprint
@ -23,6 +20,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch.PreferenceScreen
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@Patch(
name = "Hide layout components",
@ -36,7 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"com.google.android.youtube", [
"18.32.39",
"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(
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint)
) {
private const val FILTER_CLASS_DESCRIPTOR =
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
"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) {
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_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",
StringResource("revanced_custom_filter_preference_screen_title", "Custom filter"),
listOf(
@ -313,11 +404,16 @@ object HideLayoutComponentsPatch : BytecodePatch(
),
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
@ -327,12 +423,15 @@ object HideLayoutComponentsPatch : BytecodePatch(
result.mutableMethod.apply {
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(
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.
if-nez v0, :return_empty_component
""",
@ -355,7 +454,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
addInstructions(
index,
"""
invoke-static {}, $FILTER_CLASS_DESCRIPTOR->showWatermark()Z
invoke-static {}, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->showWatermark()Z
move-result p2
"""
)

View file

@ -36,7 +36,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -25,7 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -25,7 +25,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -28,7 +28,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41",
])
]
)

View file

@ -33,7 +33,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -37,7 +37,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -19,7 +19,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
CompatiblePackage(
"com.google.android.youtube", [
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -26,7 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -1,24 +1,25 @@
package app.revanced.patches.youtube.layout.hide.time.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
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.Opcode
@FuzzyPatternScanMethod(1)
object TimeCounterFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
Opcode.IGET_OBJECT,
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
emptyList(),
listOf(
Opcode.SUB_LONG_2ADDR,
Opcode.IGET_WIDE,
Opcode.CONST_WIDE_16,
Opcode.CMP_LONG,
Opcode.IF_LEZ,
Opcode.SUB_LONG_2ADDR,
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.GOTO,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_WIDE,
Opcode.IGET_WIDE,
Opcode.SUB_LONG_2ADDR
)
)

View file

@ -26,7 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -20,7 +20,10 @@ import org.w3c.dom.Element
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
],

View file

@ -1,6 +1,8 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike
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.extensions.InstructionExtensions.addInstruction
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.fingerprint.MethodFingerprint
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.Patch
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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch(
name = "Return YouTube Dislike",
@ -32,7 +36,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
PlayerTypeHookPatch::class,
],
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")
@ -44,6 +54,8 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
LikeFingerprint,
DislikeFingerprint,
RemoveLikeFingerprint,
RollingNumberSetterFingerprint,
RollingNumberTextViewFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
@ -138,7 +150,77 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
// 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 {
it.mutableMethod.apply {
@ -167,7 +249,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
move-result v0
if-eqz v0, :ryd_disabled
return-void
:is_like
:ryd_disabled
nop

View file

@ -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.")
)

View file

@ -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;"
}
)

View file

@ -12,7 +12,7 @@ object ShortsTextViewFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_SUPER, // first instruction of method
Opcode.IF_NEZ,
Opcode.RETURN_VOID,
null,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,

View file

@ -18,7 +18,7 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
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.MOVE_RESULT_OBJECT, // Register A is char sequence
Opcode.CHECK_CAST,

View file

@ -21,6 +21,7 @@ object TextComponentContextFingerprint : MethodFingerprint(
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT, // conversion context field name
)
)

View file

@ -29,7 +29,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"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.
* @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 {
toMethodWalker(it.method).nextMethod(index, true).getMethod() as MutableMethod
} ?: throw fromFingerprint.exception
@ -78,7 +80,7 @@ object WideSearchbarPatch : BytecodePatch(
/**
* Injects instructions required for certain methods.
*/
fun MutableMethod.injectSearchBarHook() {
private fun MutableMethod.injectSearchBarHook() {
addInstructions(
implementation!!.instructions.size - 1,
"""

View file

@ -9,56 +9,59 @@ 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.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.settings.SettingsPatch
@Patch(
name = "Enable old seekbar thumbnails",
description = "Enables the old seekbar thumbnails that appear above the seekbar instead of in fullscreen.",
name = "Restore old seekbar thumbnails",
description = "Restores the old seekbar thumbnails that appear above the seekbar instead of fullscreen thumbnails.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]
)
@Suppress("unused")
object EnableOldSeekbarThumbnailsPatch : BytecodePatch(
setOf(EnableNewSeekbarThumbnailsFingerprint)
object RestoreOldSeekbarThumbnailsPatch : BytecodePatch(
setOf(FullscreenSeekbarThumbnailsFingerprint)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/EnableOldSeekbarThumbnailsPatch;"
"Lapp/revanced/integrations/patches/RestoreOldSeekbarThumbnailsPatch;"
override fun execute(context: BytecodeContext) {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_enable_old_seekbar_thumbnails",
"revanced_restore_old_seekbar_thumbnails",
StringResource(
"revanced_enable_old_seekbar_thumbnails_title",
"Enable old seekbar thumbnails"
"revanced_restore_old_seekbar_thumbnails_title",
"Restore old seekbar thumbnails"
),
StringResource(
"revanced_enable_old_seekbar_thumbnails_summary_on",
"revanced_restore_old_seekbar_thumbnails_summary_on",
"Seekbar thumbnails will appear above the seekbar"
),
StringResource(
"revanced_enable_old_seekbar_thumbnails_summary_off",
"revanced_restore_old_seekbar_thumbnails_summary_off",
"Seekbar thumbnails will appear in fullscreen"
),
)
)
EnableNewSeekbarThumbnailsFingerprint.result?.mutableMethod?.apply {
FullscreenSeekbarThumbnailsFingerprint.result?.mutableMethod?.apply {
val moveResultIndex = getInstructions().lastIndex - 1
addInstruction(
moveResultIndex,
"invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->enableOldSeekbarThumbnails()Z"
"invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->useFullscreenSeekbarThumbnails()Z"
)
} ?: throw EnableNewSeekbarThumbnailsFingerprint.exception
} ?: throw FullscreenSeekbarThumbnailsFingerprint.exception
}
}

View file

@ -22,8 +22,12 @@ object SeekbarPreferencesPatch : ResourcePatch(), Closeable {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
PreferenceScreen(
"revanced_seekbar_preference_screen",
StringResource("revanced_seekbar_preference_screen_title", "Seekbar settings"),
seekbarPreferences
StringResource("revanced_seekbar_preference_screen_title", "Seekbar"),
seekbarPreferences,
StringResource(
"revanced_seekbar_preference_screen_summary",
"Settings for the seekbar."
)
)
)
}

View file

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object EnableNewSeekbarThumbnailsFingerprint : LiteralValueFingerprint(
object FullscreenSeekbarThumbnailsFingerprint : LiteralValueFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View file

@ -12,7 +12,6 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
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.mapping.misc.ResourceMappingPatch
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.playercontrols.PlayerControlsBytecodePatch
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.videoid.VideoIdPatch
import com.android.tools.smali.dexlib2.Opcode
@ -45,7 +45,10 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
],

View file

@ -30,7 +30,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.startupshortsreset
import app.revanced.extensions.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
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
@Patch(
name = "Disable Shorts on startup",
description = "Disables playing YouTube Shorts when launching YouTube.",
name = "Disable resuming Shorts on startup",
description = "Disables resuming the Shorts player on app startup if a Short was last opened.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
compatiblePackages = [
CompatiblePackage(
@ -25,39 +26,46 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]
)
@Suppress("unused")
object DisableShortsOnStartupPatch : BytecodePatch(
object DisableResumingShortsOnStartupPatch : BytecodePatch(
setOf(UserWasInShortsFingerprint)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/DisableResumingStartupShortsPlayerPatch;"
override fun execute(context: BytecodeContext) {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_disable_resuming_shorts_player",
StringResource("revanced_disable_resuming_shorts_player_title", "Disable Shorts player at app startup"),
StringResource("revanced_disable_resuming_shorts_player_summary_on", "Shorts player is disabled at app startup"),
StringResource("revanced_disable_resuming_shorts_player_summary_off", "Shorts player is enabled at app startup")
StringResource("revanced_disable_resuming_shorts_player_title", "Disable resuming Shorts player"),
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 will resume on app startup")
)
)
val userWasInShortsResult = UserWasInShortsFingerprint.result!!
val userWasInShortsMethod = userWasInShortsResult.mutableMethod
val moveResultIndex = userWasInShortsResult.scanResult.patternScanResult!!.endIndex
UserWasInShortsFingerprint.result?.apply {
val moveResultIndex = scanResult.patternScanResult!!.endIndex
userWasInShortsMethod.addInstructionsWithLabels(
moveResultIndex + 1,
"""
invoke-static { }, Lapp/revanced/integrations/patches/DisableStartupShortsPlayerPatch;->disableStartupShortsPlayer()Z
mutableMethod.addInstructionsWithLabels(
moveResultIndex + 1,
"""
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
move-result v5
if-eqz v5, :disable_shorts_player
return-void
:disable_shorts_player
nop
"""
)
)
} ?: throw UserWasInShortsFingerprint.exception
}
}

View file

@ -34,7 +34,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
)
)
]

View file

@ -32,7 +32,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"com.google.android.youtube",
[
"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"
),
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) {

View file

@ -26,7 +26,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -30,7 +30,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -21,7 +21,10 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
CompatiblePackage(
"com.google.android.youtube",
[
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -26,7 +26,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -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.playerresponse.PlayerResponseMethodHookPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@Patch(
description = "Spoofs the signature to prevent playback issues.",
@ -26,14 +27,19 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
PlayerTypeHookPatch::class,
PlayerResponseMethodHookPatch::class,
VideoInformationPatch::class,
SpoofSignatureResourcePatch::class
]
)
object SpoofSignaturePatch : BytecodePatch(
setOf(
PlayerResponseModelImplFingerprint,
StoryboardThumbnailParentFingerprint,
PlayerResponseModelImplGeneralFingerprint,
PlayerResponseModelImplLiveStreamFingerprint,
PlayerResponseModelImplRecommendedLevel,
StoryboardRendererSpecFingerprint,
StoryboardRendererInitFingerprint
StoryboardRendererDecoderSpecFingerprint,
StoryboardRendererDecoderRecommendedLevelFingerprint,
StoryboardThumbnailParentFingerprint,
ScrubbedPreviewLayoutFingerprint,
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
@ -42,12 +48,12 @@ object SpoofSignaturePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
PreferenceScreen(
key = "revanced_spoof_signature_verification",
title = StringResource(
"revanced_spoof_signature_verification",
StringResource(
"revanced_spoof_signature_verification_title",
"Spoof app signature"
),
preferences = listOf(
listOf(
SwitchPreference(
"revanced_spoof_signature_verification_enabled",
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"
+ "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.
// 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 ->
StoryboardThumbnailFingerprint.also {
it.resolve(
@ -124,23 +147,74 @@ object SpoofSignaturePatch : BytecodePatch(
} ?: throw StoryboardThumbnailFingerprint.exception
}
/**
* Hook StoryBoard renderer url
*/
PlayerResponseModelImplFingerprint.result?.let {
it.mutableMethod.apply {
val getStoryBoardIndex = it.scanResult.patternScanResult!!.endIndex
val getStoryBoardRegister = getInstruction<OneRegisterInstruction>(getStoryBoardIndex).registerA
// If storyboard spoofing is turned off, then hide the empty seekbar thumbnail view.
ScrubbedPreviewLayoutFingerprint.result?.apply {
val endIndex = scanResult.patternScanResult!!.endIndex
mutableMethod.apply {
val imageViewFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
addInstructions(
getStoryBoardIndex,
implementation!!.instructions.lastIndex,
"""
invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$getStoryBoardRegister
iget-object v0, p0, $imageViewFieldName # copy imageview field to a register
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 {
it.mutableMethod.apply {
@ -158,22 +232,18 @@ object SpoofSignaturePatch : BytecodePatch(
}
} ?: throw StoryboardRendererSpecFingerprint.exception
// Hook recommended value
StoryboardRendererInitFingerprint.result?.let {
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex
// Hook the seekbar thumbnail decoder and use a NULL spec for live streams.
StoryboardRendererDecoderSpecFingerprint.result?.let {
val storyBoardUrlIndex = it.scanResult.patternScanResult!!.startIndex + 1
val storyboardUrlRegister =
it.mutableMethod.getInstruction<OneRegisterInstruction>(storyBoardUrlIndex).registerA
val originalValueRegister = it.mutableMethod
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
it.mutableMethod.apply {
addInstructions(
moveOriginalRecommendedValueIndex + 1,
"""
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
move-result v$originalValueRegister
"""
)
}
} ?: throw StoryboardRendererInitFingerprint.exception
it.mutableMethod.addInstructions(
storyBoardUrlIndex + 1, """
invoke-static { v$storyboardUrlRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardDecoderRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$storyboardUrlRegister
"""
)
} ?: throw StoryboardRendererDecoderSpecFingerprint.exception
}
}

View file

@ -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
}
}

View file

@ -6,7 +6,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object PlayerResponseModelImplFingerprint : MethodFingerprint(
object PlayerResponseModelImplGeneralFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),

View file

@ -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)
}
)

View file

@ -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)
}
)

View file

@ -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 }
)

View file

@ -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#")
)

View file

@ -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#")
)

View file

@ -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
)
)

View file

@ -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.SwitchPreference
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.OpenLinksDirectlySecondaryFingerprint
import app.revanced.patches.youtube.misc.links.fingerprints.ABUriParserFingerprint
import app.revanced.patches.youtube.misc.links.fingerprints.HTTPUriParserFingerprint
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@ -23,20 +23,15 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
CompatiblePackage(
"com.google.android.youtube",
[
"18.16.37",
"18.19.35",
"18.20.39",
"18.23.35",
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]
)
object BypassURLRedirectsPatch : BytecodePatch(
setOf(OpenLinksDirectlyPrimaryFingerprint, OpenLinksDirectlySecondaryFingerprint)
setOf(ABUriParserFingerprint, HTTPUriParserFingerprint)
) {
override fun execute(context: BytecodeContext) {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
@ -48,14 +43,14 @@ object BypassURLRedirectsPatch : BytecodePatch(
)
)
arrayOf(
OpenLinksDirectlyPrimaryFingerprint,
OpenLinksDirectlySecondaryFingerprint
).map {
it.result ?: throw it.exception
}.forEach { result ->
mapOf(
ABUriParserFingerprint to 7, // Offset to Uri.parse.
HTTPUriParserFingerprint to 0 // Offset to Uri.parse.
).map { (fingerprint, offset) ->
(fingerprint.result ?: throw fingerprint.exception) to offset
}.forEach { (result, offset) ->
result.mutableMethod.apply {
val insertIndex = result.scanResult.patternScanResult!!.startIndex
val insertIndex = result.scanResult.patternScanResult!!.startIndex + offset
val uriStringRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
replaceInstruction(

View file

@ -30,7 +30,10 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"18.29.38",
"18.32.39",
"18.37.36",
"18.38.44"
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.41"
]
)
]

View file

@ -5,16 +5,25 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object OpenLinksDirectlyPrimaryFingerprint : MethodFingerprint(
object ABUriParserFingerprint : MethodFingerprint(
returnType = "Ljava/lang/Object",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/Object"),
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.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST,
Opcode.SGET,
Opcode.SGET_OBJECT
)
Opcode.CHECK_CAST
),
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
}
)

View file

@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object OpenLinksDirectlySecondaryFingerprint : MethodFingerprint(
object HTTPUriParserFingerprint : MethodFingerprint(
returnType = "Landroid/net/Uri",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Ljava/lang/String"),

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