Compare commits

...

39 Commits

Author SHA1 Message Date
semantic-release-bot
df57b1acdd chore(release): 2.187.0-dev.2 [skip ci]
# [2.187.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.187.0-dev.1...v2.187.0-dev.2) (2023-07-26)

### Features

* **YouTube - Hide layout components:** Hide `chips shelf` ([#2699](https://github.com/ReVanced/revanced-patches/issues/2699)) ([44107c2](44107c2b07))
2023-07-26 13:50:42 +00:00
johnconner122
44107c2b07 feat(YouTube - Hide layout components): Hide chips shelf (#2699) 2023-07-26 15:48:04 +02:00
semantic-release-bot
4680f1dc61 chore(release): 2.187.0-dev.1 [skip ci]
# [2.187.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.186.1-dev.1...v2.187.0-dev.1) (2023-07-24)

### Features

* **Sync for Reddit:** add `Disable Sync for Lemmy bottom sheet` patch ([70da6d8](70da6d8971))
2023-07-24 23:41:28 +00:00
oSumAtrIX
70da6d8971 feat(Sync for Reddit): add Disable Sync for Lemmy bottom sheet patch 2023-07-25 01:36:28 +02:00
semantic-release-bot
1df7df2841 chore(release): 2.186.1-dev.1 [skip ci]
## [2.186.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.186.0...v2.186.1-dev.1) (2023-07-21)

### Bug Fixes

* **YouTube - Theme:** only set splash screen color if background colors are set ([c14a7fb](c14a7fb66f))
2023-07-21 22:11:35 +00:00
oSumAtrIX
c14a7fb66f fix(YouTube - Theme): only set splash screen color if background colors are set 2023-07-22 00:08:25 +02:00
oSumAtrIX
6af4e47947 ci: clean after building 2023-07-21 19:17:06 +02:00
semantic-release-bot
ef704fcf7a chore(release): 2.186.0 [skip ci]
# [2.186.0](https://github.com/ReVanced/revanced-patches/compare/v2.185.0...v2.186.0) (2023-07-21)

### Bug Fixes

* **Tiktok - Settings:** get instruction registers dynamically ([#2676](https://github.com/ReVanced/revanced-patches/issues/2676)) ([b3ff7ef](b3ff7efdb2))
* **YouTube - Spoof app version:** update target app version description ([#2666](https://github.com/ReVanced/revanced-patches/issues/2666)) ([ae990ea](ae990eac6a))
* **YouTube - Theme:** allow setting no background color ([82e3ebe](82e3ebeeff))
* **YouTube - Theme:** apply custom seekbar color to shorts ([#2670](https://github.com/ReVanced/revanced-patches/issues/2670)) ([a19fa4e](a19fa4e087))

### Features

* **Twitter:** remove `Hide view stats` patch ([4e1c9b9](4e1c9b9ec2))
* **Youtube - Theme:** add a switch to enable/disable custom seekbar color ([#2663](https://github.com/ReVanced/revanced-patches/issues/2663)) ([dd7c663](dd7c663df6))
2023-07-21 15:08:14 +00:00
oSumAtrIX
eefa677b1a chore: merge branch dev to main (#2674) 2023-07-21 17:04:32 +02:00
oSumAtrIX
2bf6d693ec ci: do not cache build directory 2023-07-21 16:57:20 +02:00
semantic-release-bot
acc55fff89 chore(release): 2.186.0-dev.5 [skip ci]
# [2.186.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.4...v2.186.0-dev.5) (2023-07-20)

### Bug Fixes

* **YouTube - Theme:** allow setting no background color ([82e3ebe](82e3ebeeff))
2023-07-20 22:13:30 +00:00
oSumAtrIX
82e3ebeeff fix(YouTube - Theme): allow setting no background color 2023-07-21 00:10:48 +02:00
semantic-release-bot
47d096399a chore(release): 2.186.0-dev.4 [skip ci]
# [2.186.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.3...v2.186.0-dev.4) (2023-07-20)

### Bug Fixes

* **YouTube - Spoof app version:** update target app version description ([#2666](https://github.com/ReVanced/revanced-patches/issues/2666)) ([ae990ea](ae990eac6a))
2023-07-20 20:37:36 +00:00
LisoUseInAIKyrios
ae990eac6a fix(YouTube - Spoof app version): update target app version description (#2666) 2023-07-21 00:34:17 +04:00
LisoUseInAIKyrios
b7f40c3955 chore: delete empty file 2023-07-20 23:09:44 +04:00
semantic-release-bot
807a7b01d3 chore(release): 2.186.0-dev.3 [skip ci]
# [2.186.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.2...v2.186.0-dev.3) (2023-07-20)

### Bug Fixes

* **Tiktok - Settings:** get instruction registers dynamically ([#2676](https://github.com/ReVanced/revanced-patches/issues/2676)) ([b3ff7ef](b3ff7efdb2))
2023-07-20 17:39:14 +00:00
Vu Hoan Huy
b3ff7efdb2 fix(Tiktok - Settings): get instruction registers dynamically (#2676) 2023-07-20 19:36:41 +02:00
semantic-release-bot
098162173f chore(release): 2.186.0-dev.2 [skip ci]
# [2.186.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.1...v2.186.0-dev.2) (2023-07-20)

### Bug Fixes

* **YouTube - Theme:** apply custom seekbar color to shorts ([#2670](https://github.com/ReVanced/revanced-patches/issues/2670)) ([a19fa4e](a19fa4e087))

### Features

* **Youtube - Theme:** add a switch to enable/disable custom seekbar color ([#2663](https://github.com/ReVanced/revanced-patches/issues/2663)) ([dd7c663](dd7c663df6))
2023-07-20 17:31:06 +00:00
LisoUseInAIKyrios
a19fa4e087 fix(YouTube - Theme): apply custom seekbar color to shorts (#2670) 2023-07-20 21:28:22 +04:00
LisoUseInAIKyrios
dd7c663df6 feat(Youtube - Theme): add a switch to enable/disable custom seekbar color (#2663) 2023-07-20 21:27:44 +04:00
semantic-release-bot
9bd7773af2 chore(release): 2.186.0-dev.1 [skip ci]
# [2.186.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.185.0...v2.186.0-dev.1) (2023-07-20)

### Features

* **Twitter:** remove `Hide view stats` patch ([4e1c9b9](4e1c9b9ec2))
2023-07-20 16:47:25 +00:00
oSumAtrIX
4e1c9b9ec2 feat(Twitter): remove Hide view stats patch
The patch is constrained on a version that is not working properly anymore.
2023-07-20 18:44:08 +02:00
semantic-release-bot
96a6f3f93e chore(release): 2.185.0 [skip ci]
# [2.185.0](https://github.com/ReVanced/revanced-patches/compare/v2.184.0...v2.185.0) (2023-07-20)

### Bug Fixes

* allocate for more than eight `LithoFilter` array items ([#2643](https://github.com/ReVanced/revanced-patches/issues/2643)) ([5de8ee5](5de8ee51c1))
* **Sync for Reddit - Disable ads:** fix compatibility with latest version ([6b2f786](6b2f7862d1))
* **Tiktok - Settings:** bump compatibility ([#2656](https://github.com/ReVanced/revanced-patches/issues/2656)) ([90e32ea](90e32eac54))
* **TikTok - Show seekbar:** fix seekbar not always showing ([#2660](https://github.com/ReVanced/revanced-patches/issues/2660)) ([e4adaeb](e4adaebad4))
* **Trakt - Unlock pro:** constraint to last known working version ([#2662](https://github.com/ReVanced/revanced-patches/issues/2662)) ([9da2bc3](9da2bc32a1))
* **YouTube - Spoof client:** show video time and chapters while using seekbar ([#2607](https://github.com/ReVanced/revanced-patches/issues/2607)) ([7fdc0d2](7fdc0d2a70))
* **youtube/sponsorblock:** fix some segments skipping slightly too late ([#2634](https://github.com/ReVanced/revanced-patches/issues/2634)) ([180c777](180c7775e6))

### Features

* **youtube:** rename `video-speed` to `playback-speed` ([#2642](https://github.com/ReVanced/revanced-patches/issues/2642)) ([75fd96f](75fd96f4c3))
2023-07-20 00:04:46 +00:00
oSumAtrIX
b74611a6ae chore: merge branch dev to main (#2641) 2023-07-20 02:02:15 +02:00
semantic-release-bot
ae40d87bb3 chore(release): 2.185.0-dev.7 [skip ci]
# [2.185.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.6...v2.185.0-dev.7) (2023-07-19)

### Bug Fixes

* **YouTube - Spoof client:** show video time and chapters while using seekbar ([#2607](https://github.com/ReVanced/revanced-patches/issues/2607)) ([7fdc0d2](7fdc0d2a70))
2023-07-19 23:20:29 +00:00
LisoUseInAIKyrios
7fdc0d2a70 fix(YouTube - Spoof client): show video time and chapters while using seekbar (#2607) 2023-07-20 01:17:47 +02:00
semantic-release-bot
1fade09694 chore(release): 2.185.0-dev.6 [skip ci]
# [2.185.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.5...v2.185.0-dev.6) (2023-07-19)

### Bug Fixes

* **Tiktok - Settings:** bump compatibility ([#2656](https://github.com/ReVanced/revanced-patches/issues/2656)) ([90e32ea](90e32eac54))
2023-07-19 23:16:57 +00:00
Vu Hoan Huy
90e32eac54 fix(Tiktok - Settings): bump compatibility (#2656) 2023-07-20 01:13:33 +02:00
semantic-release-bot
a0632c8a92 chore(release): 2.185.0-dev.5 [skip ci]
# [2.185.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.4...v2.185.0-dev.5) (2023-07-19)

### Bug Fixes

* **Trakt - Unlock pro:** constraint to last known working version ([#2662](https://github.com/ReVanced/revanced-patches/issues/2662)) ([9da2bc3](9da2bc32a1))
2023-07-19 22:52:54 +00:00
johnconner122
9da2bc32a1 fix(Trakt - Unlock pro): constraint to last known working version (#2662) 2023-07-20 00:50:16 +02:00
semantic-release-bot
89fed3874f chore(release): 2.185.0-dev.4 [skip ci]
# [2.185.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.3...v2.185.0-dev.4) (2023-07-19)

### Bug Fixes

* **TikTok - Show seekbar:** fix seekbar not always showing ([#2660](https://github.com/ReVanced/revanced-patches/issues/2660)) ([e4adaeb](e4adaebad4))
2023-07-19 12:58:39 +00:00
Vu Hoan Huy
e4adaebad4 fix(TikTok - Show seekbar): fix seekbar not always showing (#2660) 2023-07-19 14:55:17 +02:00
semantic-release-bot
0b78e8377b chore(release): 2.185.0-dev.3 [skip ci]
# [2.185.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.2...v2.185.0-dev.3) (2023-07-17)

### Bug Fixes

* **Sync for Reddit - Disable ads:** fix compatibility with latest version ([6b2f786](6b2f7862d1))
2023-07-17 22:39:26 +00:00
oSumAtrIX
6b2f7862d1 fix(Sync for Reddit - Disable ads): fix compatibility with latest version 2023-07-18 00:36:37 +02:00
Aaronjamt
4668861d65 chore: fix typos (fingereprints -> fingerprints) (#2650) 2023-07-17 15:21:07 +04:00
semantic-release-bot
c5c63537ff chore(release): 2.185.0-dev.2 [skip ci]
# [2.185.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.1...v2.185.0-dev.2) (2023-07-15)

### Bug Fixes

* allocate for more than eight `LithoFilter` array items ([#2643](https://github.com/ReVanced/revanced-patches/issues/2643)) ([5de8ee5](5de8ee51c1))
2023-07-15 21:27:19 +00:00
johnconner122
5de8ee51c1 fix: allocate for more than eight LithoFilter array items (#2643) 2023-07-15 23:24:34 +02:00
semantic-release-bot
65087833b0 chore(release): 2.185.0-dev.1 [skip ci]
# [2.185.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.1-dev.1...v2.185.0-dev.1) (2023-07-15)

### Features

* **youtube:** rename `video-speed` to `playback-speed` ([#2642](https://github.com/revanced/revanced-patches/issues/2642)) ([75fd96f](75fd96f4c3))
2023-07-15 12:36:34 +00:00
KAZI MMT
75fd96f4c3 feat(youtube): rename video-speed to playback-speed (#2642) 2023-07-15 16:32:39 +04:00
50 changed files with 636 additions and 525 deletions

View File

@@ -30,13 +30,12 @@ jobs:
${{ runner.home }}/.gradle/caches ${{ runner.home }}/.gradle/caches
${{ runner.home }}/.gradle/wrapper ${{ runner.home }}/.gradle/wrapper
.gradle .gradle
build
node_modules node_modules
key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }} key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }}
- name: Build with Gradle - name: Build with Gradle
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew generateMeta clean --no-daemon run: ./gradlew generateMeta clean
- name: Setup semantic-release - name: Setup semantic-release
run: npm install run: npm install
- name: Release - name: Release

View File

@@ -1,3 +1,147 @@
# [2.187.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.187.0-dev.1...v2.187.0-dev.2) (2023-07-26)
### Features
* **YouTube - Hide layout components:** Hide `chips shelf` ([#2699](https://github.com/ReVanced/revanced-patches/issues/2699)) ([8e6058b](https://github.com/ReVanced/revanced-patches/commit/8e6058b62350b3d14d79e6fe52b0ad781b66b5de))
# [2.187.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.186.1-dev.1...v2.187.0-dev.1) (2023-07-24)
### Features
* **Sync for Reddit:** add `Disable Sync for Lemmy bottom sheet` patch ([56b535b](https://github.com/ReVanced/revanced-patches/commit/56b535b2a136d4b0afbddf2c8e251889c2555056))
## [2.186.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.186.0...v2.186.1-dev.1) (2023-07-21)
### Bug Fixes
* **YouTube - Theme:** only set splash screen color if background colors are set ([f058db4](https://github.com/ReVanced/revanced-patches/commit/f058db4ba4300400ac92b4a9790708eb8bde7092))
# [2.186.0](https://github.com/ReVanced/revanced-patches/compare/v2.185.0...v2.186.0) (2023-07-21)
### Bug Fixes
* **Tiktok - Settings:** get instruction registers dynamically ([#2676](https://github.com/ReVanced/revanced-patches/issues/2676)) ([b34e45b](https://github.com/ReVanced/revanced-patches/commit/b34e45b6dafad8e9d567ad65f58a182b8cc04676))
* **YouTube - Spoof app version:** update target app version description ([#2666](https://github.com/ReVanced/revanced-patches/issues/2666)) ([307442e](https://github.com/ReVanced/revanced-patches/commit/307442e654ff5486656319d91e4a5f5fb2b92651))
* **YouTube - Theme:** allow setting no background color ([8a4e77a](https://github.com/ReVanced/revanced-patches/commit/8a4e77a290a61a1caf93eb8bccaf728c84a3ef53))
* **YouTube - Theme:** apply custom seekbar color to shorts ([#2670](https://github.com/ReVanced/revanced-patches/issues/2670)) ([1f6fe3d](https://github.com/ReVanced/revanced-patches/commit/1f6fe3da4284fd768057ef068c7ddf88d3a11049))
### Features
* **Twitter:** remove `Hide view stats` patch ([f0d3800](https://github.com/ReVanced/revanced-patches/commit/f0d38001b34db63f212209afb91eebf59dad2b24))
* **Youtube - Theme:** add a switch to enable/disable custom seekbar color ([#2663](https://github.com/ReVanced/revanced-patches/issues/2663)) ([5c39985](https://github.com/ReVanced/revanced-patches/commit/5c39985888cdfe3acfdd8811ff9b6f80e243704e))
# [2.186.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.4...v2.186.0-dev.5) (2023-07-20)
### Bug Fixes
* **YouTube - Theme:** allow setting no background color ([8a4e77a](https://github.com/ReVanced/revanced-patches/commit/8a4e77a290a61a1caf93eb8bccaf728c84a3ef53))
# [2.186.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.3...v2.186.0-dev.4) (2023-07-20)
### Bug Fixes
* **YouTube - Spoof app version:** update target app version description ([#2666](https://github.com/ReVanced/revanced-patches/issues/2666)) ([307442e](https://github.com/ReVanced/revanced-patches/commit/307442e654ff5486656319d91e4a5f5fb2b92651))
# [2.186.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.2...v2.186.0-dev.3) (2023-07-20)
### Bug Fixes
* **Tiktok - Settings:** get instruction registers dynamically ([#2676](https://github.com/ReVanced/revanced-patches/issues/2676)) ([b34e45b](https://github.com/ReVanced/revanced-patches/commit/b34e45b6dafad8e9d567ad65f58a182b8cc04676))
# [2.186.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.186.0-dev.1...v2.186.0-dev.2) (2023-07-20)
### Bug Fixes
* **YouTube - Theme:** apply custom seekbar color to shorts ([#2670](https://github.com/ReVanced/revanced-patches/issues/2670)) ([1f6fe3d](https://github.com/ReVanced/revanced-patches/commit/1f6fe3da4284fd768057ef068c7ddf88d3a11049))
### Features
* **Youtube - Theme:** add a switch to enable/disable custom seekbar color ([#2663](https://github.com/ReVanced/revanced-patches/issues/2663)) ([5c39985](https://github.com/ReVanced/revanced-patches/commit/5c39985888cdfe3acfdd8811ff9b6f80e243704e))
# [2.186.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.185.0...v2.186.0-dev.1) (2023-07-20)
### Features
* **Twitter:** remove `Hide view stats` patch ([f0d3800](https://github.com/ReVanced/revanced-patches/commit/f0d38001b34db63f212209afb91eebf59dad2b24))
# [2.185.0](https://github.com/ReVanced/revanced-patches/compare/v2.184.0...v2.185.0) (2023-07-20)
### Bug Fixes
* allocate for more than eight `LithoFilter` array items ([#2643](https://github.com/ReVanced/revanced-patches/issues/2643)) ([fc8660b](https://github.com/ReVanced/revanced-patches/commit/fc8660b740bec2747e5f82b7321027bb8a51e0cf))
* **Sync for Reddit - Disable ads:** fix compatibility with latest version ([1456577](https://github.com/ReVanced/revanced-patches/commit/1456577f11c4a7e49d6c1ba0103b919dc487f4cf))
* **Tiktok - Settings:** bump compatibility ([#2656](https://github.com/ReVanced/revanced-patches/issues/2656)) ([6641356](https://github.com/ReVanced/revanced-patches/commit/6641356d41813a20c77faac67c37ea517690d25b))
* **TikTok - Show seekbar:** fix seekbar not always showing ([#2660](https://github.com/ReVanced/revanced-patches/issues/2660)) ([f2742f1](https://github.com/ReVanced/revanced-patches/commit/f2742f1ba117809971a10780823fca99c19a4f34))
* **Trakt - Unlock pro:** constraint to last known working version ([#2662](https://github.com/ReVanced/revanced-patches/issues/2662)) ([324bbde](https://github.com/ReVanced/revanced-patches/commit/324bbde92a851e855c11f266e92fa14c39d88160))
* **YouTube - Spoof client:** show video time and chapters while using seekbar ([#2607](https://github.com/ReVanced/revanced-patches/issues/2607)) ([9546d12](https://github.com/ReVanced/revanced-patches/commit/9546d126430870d1abd8f43bb687b31b9fcb6fb5))
* **youtube/sponsorblock:** fix some segments skipping slightly too late ([#2634](https://github.com/ReVanced/revanced-patches/issues/2634)) ([3175431](https://github.com/ReVanced/revanced-patches/commit/31754311870324b1e245b12965d7486878e9eba4))
### Features
* **youtube:** rename `video-speed` to `playback-speed` ([#2642](https://github.com/ReVanced/revanced-patches/issues/2642)) ([77e8639](https://github.com/ReVanced/revanced-patches/commit/77e8639b71048f2795f8f32fe18d052b335e3ce4))
# [2.185.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.6...v2.185.0-dev.7) (2023-07-19)
### Bug Fixes
* **YouTube - Spoof client:** show video time and chapters while using seekbar ([#2607](https://github.com/ReVanced/revanced-patches/issues/2607)) ([9546d12](https://github.com/ReVanced/revanced-patches/commit/9546d126430870d1abd8f43bb687b31b9fcb6fb5))
# [2.185.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.5...v2.185.0-dev.6) (2023-07-19)
### Bug Fixes
* **Tiktok - Settings:** bump compatibility ([#2656](https://github.com/ReVanced/revanced-patches/issues/2656)) ([6641356](https://github.com/ReVanced/revanced-patches/commit/6641356d41813a20c77faac67c37ea517690d25b))
# [2.185.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.4...v2.185.0-dev.5) (2023-07-19)
### Bug Fixes
* **Trakt - Unlock pro:** constraint to last known working version ([#2662](https://github.com/ReVanced/revanced-patches/issues/2662)) ([324bbde](https://github.com/ReVanced/revanced-patches/commit/324bbde92a851e855c11f266e92fa14c39d88160))
# [2.185.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.3...v2.185.0-dev.4) (2023-07-19)
### Bug Fixes
* **TikTok - Show seekbar:** fix seekbar not always showing ([#2660](https://github.com/ReVanced/revanced-patches/issues/2660)) ([f2742f1](https://github.com/ReVanced/revanced-patches/commit/f2742f1ba117809971a10780823fca99c19a4f34))
# [2.185.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.2...v2.185.0-dev.3) (2023-07-17)
### Bug Fixes
* **Sync for Reddit - Disable ads:** fix compatibility with latest version ([1456577](https://github.com/ReVanced/revanced-patches/commit/1456577f11c4a7e49d6c1ba0103b919dc487f4cf))
# [2.185.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.185.0-dev.1...v2.185.0-dev.2) (2023-07-15)
### Bug Fixes
* allocate for more than eight `LithoFilter` array items ([#2643](https://github.com/ReVanced/revanced-patches/issues/2643)) ([fc8660b](https://github.com/ReVanced/revanced-patches/commit/fc8660b740bec2747e5f82b7321027bb8a51e0cf))
# [2.185.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.1-dev.1...v2.185.0-dev.1) (2023-07-15)
### Features
* **youtube:** rename `video-speed` to `playback-speed` ([#2642](https://github.com/revanced/revanced-patches/issues/2642)) ([77e8639](https://github.com/revanced/revanced-patches/commit/77e8639b71048f2795f8f32fe18d052b335e3ce4))
## [2.184.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.0...v2.184.1-dev.1) (2023-07-14) ## [2.184.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.184.0...v2.184.1-dev.1) (2023-07-14)

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 2.184.1-dev.1 version = 2.187.0-dev.2

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.reddit.customclients.syncforreddit.annoyances.startup.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object MainActivityOnCreate : MethodFingerprint(
customFingerprint = custom@{ method, classDef ->
classDef.type.endsWith("MainActivity;") && method.name == "onCreate"
}
)

View File

@@ -0,0 +1,35 @@
package app.revanced.patches.reddit.customclients.syncforreddit.annoyances.startup.patch
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.reddit.customclients.syncforreddit.annoyances.startup.fingerprints.MainActivityOnCreate
@Patch
@Name("Disable Sync for Lemmy bottom sheet")
@Description("Disables the bottom sheet at the startup that asks you to signup to \"Sync for Lemmy\".")
@Compatibility(
[
Package("com.laurencedawson.reddit_sync", ["v23.06.30-13:39"]),
Package("com.laurencedawson.reddit_sync.pro"), // Version unknown.
Package("com.laurencedawson.reddit_sync.dev") // Version unknown.
]
)
class DisableSyncForLemmyBottomSheetPatch : BytecodePatch(listOf(MainActivityOnCreate)) {
override fun execute(context: BytecodeContext): PatchResult {
MainActivityOnCreate.result?.mutableMethod?.apply {
val showBottomSheetIndex = implementation!!.instructions.lastIndex - 1
removeInstruction(showBottomSheetIndex)
}
return PatchResultSuccess()
}
}

View File

@@ -1,11 +1,10 @@
package app.revanced.patches.syncforreddit.detection.piracy.fingerprints package app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.TypeReference
object PiracyDetectionFingerprint : MethodFingerprint( object PiracyDetectionFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",

View File

@@ -1,19 +1,18 @@
package app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.patch package app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.syncforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint
@Description("Disables detection of modified versions.") @Description("Disables detection of modified versions.")
@Version("0.0.1")
class DisablePiracyDetectionPatch : BytecodePatch(listOf(PiracyDetectionFingerprint)) { class DisablePiracyDetectionPatch : BytecodePatch(listOf(PiracyDetectionFingerprint)) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
// Do not return an error if the fingerprint is not resolved.
// This is fine because new versions of the target app do not need this patch.
PiracyDetectionFingerprint.result?.mutableMethod?.apply { PiracyDetectionFingerprint.result?.mutableMethod?.apply {
addInstruction( addInstruction(
0, 0,
@@ -21,7 +20,7 @@ class DisablePiracyDetectionPatch : BytecodePatch(listOf(PiracyDetectionFingerpr
return-void return-void
""" """
) )
} ?: return PiracyDetectionFingerprint.toErrorResult() }
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.tiktok.interaction.seekbar.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object AwemeGetVideoControlFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/Aweme;") && methodDef.name == "getVideoControl"
}
)

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.tiktok.interaction.seekbar.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SetSeekBarShowTypeFingerprint : MethodFingerprint(
strings = listOf(
"seekbar show type change, change to:"
),
)

View File

@@ -6,17 +6,14 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions 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.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.tiktok.interaction.seekbar.annotations.ShowSeekbarCompatibility import app.revanced.patches.tiktok.interaction.seekbar.annotations.ShowSeekbarCompatibility
import app.revanced.patches.tiktok.interaction.seekbar.fingerprints.AwemeGetVideoControlFingerprint import app.revanced.patches.tiktok.interaction.seekbar.fingerprints.SetSeekBarShowTypeFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.formats.Instruction22t
import org.jf.dexlib2.builder.instruction.BuilderInstruction11n
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
import org.jf.dexlib2.builder.instruction.BuilderInstruction22c
@Patch @Patch
@Name("Show seekbar") @Name("Show seekbar")
@@ -25,27 +22,20 @@ import org.jf.dexlib2.builder.instruction.BuilderInstruction22c
@Version("0.0.1") @Version("0.0.1")
class ShowSeekbarPatch : BytecodePatch( class ShowSeekbarPatch : BytecodePatch(
listOf( listOf(
AwemeGetVideoControlFingerprint SetSeekBarShowTypeFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
//Get VideoControl FieldReference SetSeekBarShowTypeFingerprint.result?.mutableMethod?.apply {
val videoControl = context.findClass { it.type.endsWith("/VideoControl;") } val typeRegister = getInstruction<Instruction22t>(1).registerB
?: return PatchResultError("Can not find target class")
val fieldList = videoControl.immutableClass.fields.associateBy { field -> field.name }
AwemeGetVideoControlFingerprint.result?.mutableMethod?.implementation?.apply {
val ifNullLabel = newLabelForIndex(1)
addInstructions( addInstructions(
1, 0,
listOf( """
BuilderInstruction11n(Opcode.CONST_4, 1, 1), const/16 v$typeRegister, 0x64
BuilderInstruction21t(Opcode.IF_EQZ, 0, ifNullLabel), """
BuilderInstruction22c(Opcode.IPUT, 1, 0, fieldList["showProgressBar"]!!),
BuilderInstruction22c(Opcode.IPUT, 1, 0, fieldList["draftProgressBar"]!!)
)
) )
} ?: return AwemeGetVideoControlFingerprint.toErrorResult() } ?: return SetSeekBarShowTypeFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -1,17 +0,0 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object AboutPageFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST, // copyrightPolicyLabel resource id
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_STRING
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/ss/android/ugc/aweme/setting/page/AboutPage;" &&
methodDef.name == "onViewCreated"
}
)

View File

@@ -0,0 +1,22 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object AddSettingsEntryFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST_CLASS,
Opcode.APUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SettingNewVersionFragment;") &&
methodDef.name == "onViewCreated"
}
)

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsEntryFingerprint : MethodFingerprint(
strings = listOf(
"pls pass item or extends the EventUnit"
)
)

View File

@@ -0,0 +1,10 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsEntryInfoFingerprint : MethodFingerprint(
strings = listOf(
"ExposeItem(title=",
", icon="
)
)

View File

@@ -1,10 +0,0 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsOnViewCreatedFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SettingNewVersionFragment;") &&
methodDef.name == "onViewCreated"
}
)

View File

@@ -6,24 +6,20 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.tiktok.misc.settings.annotations.SettingsCompatibility import app.revanced.patches.tiktok.misc.settings.annotations.SettingsCompatibility
import app.revanced.patches.tiktok.misc.settings.fingerprints.AboutPageFingerprint import app.revanced.patches.tiktok.misc.settings.fingerprints.*
import app.revanced.patches.tiktok.misc.settings.fingerprints.AdPersonalizationActivityOnCreateFingerprint
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsOnViewCreatedFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Patch @Patch
@DependsOn([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
@@ -33,65 +29,46 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Version("0.0.1") @Version("0.0.1")
class SettingsPatch : BytecodePatch( class SettingsPatch : BytecodePatch(
listOf( listOf(
AboutPageFingerprint,
AdPersonalizationActivityOnCreateFingerprint, AdPersonalizationActivityOnCreateFingerprint,
SettingsOnViewCreatedFingerprint, AddSettingsEntryFingerprint,
SettingsEntryFingerprint,
SettingsEntryInfoFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
SettingsOnViewCreatedFingerprint.result?.mutableMethod?.apply { // Find the class name of classes which construct a settings entry
val instructions = implementation!!.instructions val settingsButtonClass = SettingsEntryFingerprint.result?.classDef?.type?.toClassName()
?: return SettingsEntryFingerprint.toErrorResult()
val settingsButtonInfoClass = SettingsEntryInfoFingerprint.result?.classDef?.type?.toClassName()
?: return SettingsEntryInfoFingerprint.toErrorResult()
// Find the indices that need to be patched. // Create a settings entry for 'revanced settings' and add it to settings fragment
val copyrightPolicyLabelId = AboutPageFingerprint.result?.let { AddSettingsEntryFingerprint.result?.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex scanResult.patternScanResult?.startIndex?.let {
it.mutableMethod.getInstruction<WideLiteralInstruction>(startIndex).wideLiteral val settingsEntries = mutableMethod.getInstruction(it + 3)
} ?: return AboutPageFingerprint.toErrorResult() val addEntry = mutableMethod.getInstruction<BuilderInstruction35c>(it + 5)
val register1 = addEntry.registerC
val copyrightIndex = instructions.indexOfFirst { val register2 = addEntry.registerD
(it as? ReferenceInstruction)?.reference.toString() == "copyright_policy" // Add the settings entry created to the settings fragment
} - 6 mutableMethod.addInstructions(
it + 6,
listOf(
// fixme: instead use Method.indexOfFirstConstantInstructionValue() settingsEntries,
val copyrightPolicyIndex = instructions.indexOfFirst { addEntry
(it as? WideLiteralInstruction)?.wideLiteral == copyrightPolicyLabelId )
} + 2
// Replace an existing settings entry with ReVanced settings entry.
arrayOf(
copyrightIndex,
copyrightPolicyIndex
).forEach { index ->
val instruction = getInstruction(index)
if (instruction.opcode != Opcode.MOVE_RESULT_OBJECT)
return PatchResultError("Hardcoded offset changed.")
val settingsEntryStringRegister = (instruction as OneRegisterInstruction).registerA
// Replace the settings entry string with a custom one.
replaceInstruction(
index,
"""
const-string v$settingsEntryStringRegister, "ReVanced Settings"
"""
) )
// These instructions call a method that create a settings entry use reflection base on the class name of classes that construct settings entry
// Replace the OnClickListener class with a custom one. mutableMethod.addInstructions(
val onClickListener = getInstruction<ReferenceInstruction>(index + 4).reference.toString() it + 6,
context.findClass(onClickListener)?.mutableClass?.methods?.first {
it.name == "onClick"
}?.addInstructions(
0,
""" """
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->startSettingsActivity()V const-string v$register1, "$settingsButtonClass"
return-void const-string v$register2, "$settingsButtonInfoClass"
invoke-static {v$register1, v$register2}, $CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR
move-result-object v$register2
""" """
) ?: return PatchResultError("Could not find the onClick method.") )
} }
} ?: return AddSettingsEntryFingerprint.toErrorResult()
} ?: return SettingsOnViewCreatedFingerprint.toErrorResult()
// Initialize the settings menu once the replaced setting entry is clicked. // Initialize the settings menu once the replaced setting entry is clicked.
AdPersonalizationActivityOnCreateFingerprint.result?.mutableMethod?.apply { AdPersonalizationActivityOnCreateFingerprint.result?.mutableMethod?.apply {
@@ -99,20 +76,28 @@ class SettingsPatch : BytecodePatch(
it.opcode == Opcode.INVOKE_SUPER it.opcode == Opcode.INVOKE_SUPER
} + 1 } + 1
val thisRegister = getInstruction<FiveRegisterInstruction>(initializeSettingsIndex - 1).registerC val thisRegister = getInstruction<Instruction35c>(initializeSettingsIndex - 1).registerC
val usableRegister = implementation!!.registerCount - parameters.size - 2
addInstructions( addInstructionsWithLabels(
initializeSettingsIndex, initializeSettingsIndex,
""" """
invoke-static {v$thisRegister}, $INITIALIZE_SETTINGS_METHOD_DESCRIPTOR invoke-static {v$thisRegister}, $INITIALIZE_SETTINGS_METHOD_DESCRIPTOR
move-result v$usableRegister
if-eqz v$usableRegister, :notrevanced
return-void return-void
""" """,
ExternalLabel("notrevanced", getInstruction(initializeSettingsIndex))
) )
} ?: return AdPersonalizationActivityOnCreateFingerprint.toErrorResult() } ?: return AdPersonalizationActivityOnCreateFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }
private fun String.toClassName(): String {
return substring(1, this.length - 1).replace("/", ".")
}
private companion object { private companion object {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/tiktok/settingsmenu/SettingsMenu;" "Lapp/revanced/tiktok/settingsmenu/SettingsMenu;"
@@ -120,6 +105,11 @@ class SettingsPatch : BytecodePatch(
private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR = private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->initializeSettings(" + "$INTEGRATIONS_CLASS_DESCRIPTOR->initializeSettings(" +
"Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" + "Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" +
")V" ")Z"
private const val CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->createSettingsEntry(" +
"Ljava/lang/String;" +
"Ljava/lang/String;" +
")Ljava/lang/Object;"
} }
} }

View File

@@ -3,6 +3,6 @@ package app.revanced.patches.trakt.annotations
import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package import app.revanced.patcher.annotation.Package
@Compatibility([Package("tv.trakt.trakt")]) @Compatibility([Package("tv.trakt.trakt", arrayOf("1.1.1"))])
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
internal annotation class UnlockProCompatibility internal annotation class UnlockProCompatibility

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.twitter.android", arrayOf("9.69.1-release.0", "9.71.0-release.0")
)]
)
@Target(AnnotationTarget.CLASS)
internal annotation class HideViewsCompatibility

View File

@@ -1,15 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object InlineActionTypesFingerprint : MethodFingerprint(
returnType = "Ljava/util/List",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
strings = listOf(
"getCurrentMemoizing()",
"android_animated_reply_icon_enabled",
"reply_voting_android_position_before_favorite_enabled"
)
)

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object TweetStatsContainerConstructorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L"),
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL
)
)

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object TweetStatsContainerWrapperConstructorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L"),
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT
)
)

View File

@@ -1,26 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object TweetStatsViewDelegateBinderFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.NEW_INSTANCE,
Opcode.CONST_16,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.CONST_16,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_OBJECT
)
)

View File

@@ -1,114 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.patch
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.twitter.layout.hideviews.fingerprints.InlineActionTypesFingerprint
import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsContainerConstructorFingerprint
import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsContainerWrapperConstructorFingerprint
import app.revanced.patches.twitter.layout.hideviews.fingerprints.TweetStatsViewDelegateBinderFingerprint
import org.jf.dexlib2.Opcode
class HideViewsBytecodePatch : BytecodePatch(
listOf(
InlineActionTypesFingerprint,
TweetStatsContainerWrapperConstructorFingerprint,
TweetStatsContainerConstructorFingerprint,
TweetStatsViewDelegateBinderFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
removeViewsFromTimeline(context)
removeTweetStatViewInitializer(context)
removeTweetStatViewWrapperInitializer(context)
removeViewDelegateBinderSubscription()
return PatchResultSuccess()
}
private fun removeViewsFromTimeline(context: BytecodeContext) {
val addViewsToActionBarMethodFingerprint = object : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IF_EQZ,
)
) {}
transformMethodAtPattern(
context,
InlineActionTypesFingerprint,
addViewsToActionBarMethodFingerprint
) { patternScanResult, method ->
method.removeInstruction(patternScanResult.endIndex - 1)
}
}
private fun removeTweetStatViewInitializer(context: BytecodeContext) {
val returnFingerprint = object : MethodFingerprint(
opcodes = listOf(Opcode.RETURN_VOID)
) {}
transformMethodAtPattern(
context,
TweetStatsContainerConstructorFingerprint,
returnFingerprint
) { patternScanResult, method ->
method.removeInstructions(patternScanResult.endIndex - 3, 3)
}
}
private fun removeTweetStatViewWrapperInitializer(context: BytecodeContext) {
val wrapperReturnFingerprint = object : MethodFingerprint(
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID,
)
) {}
transformMethodAtPattern(
context,
TweetStatsContainerWrapperConstructorFingerprint,
wrapperReturnFingerprint
) { patternScanResult, method ->
method.removeInstructions(patternScanResult.startIndex - 4, 4)
}
}
private fun removeViewDelegateBinderSubscription() {
transformMethod(TweetStatsViewDelegateBinderFingerprint) { result, method ->
method.removeInstructions(result.scanResult.patternScanResult!!.startIndex - 4, 10)
}
}
private fun transformMethodAtPattern(
context: BytecodeContext, methodFingerprint: MethodFingerprint,
patternFingerprint: MethodFingerprint, transformer: TransformerAtPattern
) {
transformMethod(methodFingerprint) { result, method ->
val patternResult = patternFingerprint.also {
it.resolve(context, method, result.classDef)
}.result!!
transformer(patternResult.scanResult.patternScanResult!!, method)
}
}
private fun transformMethod(methodFingerprint: MethodFingerprint, transformer: Transformer) {
val result = methodFingerprint.result!!
val method = result.mutableMethod
transformer(result, method)
}
}
private typealias Transformer = (MethodFingerprintResult, MutableMethod) -> Unit
private typealias TransformerAtPattern = (MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult, MutableMethod) -> Unit

View File

@@ -1,34 +0,0 @@
package app.revanced.patches.twitter.layout.hideviews.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.twitter.layout.hideviews.annotations.HideViewsCompatibility
import org.w3c.dom.Element
@Patch
@DependsOn([HideViewsBytecodePatch::class])
@Name("Hide views stats")
@Description("Hides the view stats under tweets.")
@HideViewsCompatibility
@Version("0.0.1")
class HideViewsResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
arrayOf(
"res/layout/condensed_tweet_stats.xml",
"res/layout/focal_tweet_stats.xml"
).forEach { file ->
context.xmlEditor[file].use { editor ->
val tags = editor.file.getElementsByTagName("com.twitter.ui.tweet.TweetStatView")
List(tags.length) { tags.item(it) as Element }
.filter { it.getAttribute("android:id").contains("views_stat") }
.forEach { it.parentNode.removeChild(it) }
}
}
return PatchResultSuccess()
}
}

View File

@@ -211,6 +211,12 @@ class HideLayoutComponentsPatch : BytecodePatch(
StringResource("revanced_hide_artist_cards_on", "Artist cards is hidden"), StringResource("revanced_hide_artist_cards_on", "Artist cards is hidden"),
StringResource("revanced_hide_artist_cards_off", "Artist cards is shown") StringResource("revanced_hide_artist_cards_off", "Artist cards is shown")
), ),
SwitchPreference(
"revanced_hide_chips_shelf",
StringResource("revanced_hide_chips_shelf_title", "Hide chips shelf"),
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( app.revanced.patches.shared.settings.preference.impl.PreferenceScreen(
"revanced_custom_filter_preference_screen", "revanced_custom_filter_preference_screen",
StringResource("revanced_custom_filter_preference_screen_title", "Custom filter"), StringResource("revanced_custom_filter_preference_screen_title", "Custom filter"),

View File

@@ -6,7 +6,7 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
object CreateDarkThemeSeekbarFingerprint : MethodFingerprint( object PlayerSeekbarColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { method, _ -> customFingerprint = { method, _ ->
method.containsConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) method.containsConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId)

View File

@@ -0,0 +1,11 @@
package app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
object ShortsSeekbarColorFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
literal = SeekbarColorResourcePatch.reelTimeBarPlayedColorId,
)

View File

@@ -14,8 +14,9 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.seekbar.annotations.SeekbarColorCompatibility import app.revanced.patches.youtube.layout.seekbar.annotations.SeekbarColorCompatibility
import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.CreateDarkThemeSeekbarFingerprint import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.PlayerSeekbarColorFingerprint
import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.SetSeekbarClickedColorFingerprint import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.SetSeekbarClickedColorFingerprint
import app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints.ShortsSeekbarColorFingerprint
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch.Companion.lithoColorOverrideHook import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch.Companion.lithoColorOverrideHook
@@ -28,30 +29,29 @@ import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
@SeekbarColorCompatibility @SeekbarColorCompatibility
@Version("0.0.1") @Version("0.0.1")
class SeekbarColorBytecodePatch : BytecodePatch( class SeekbarColorBytecodePatch : BytecodePatch(
listOf(CreateDarkThemeSeekbarFingerprint, SetSeekbarClickedColorFingerprint) listOf(PlayerSeekbarColorFingerprint, ShortsSeekbarColorFingerprint, SetSeekbarClickedColorFingerprint)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
CreateDarkThemeSeekbarFingerprint.result?.mutableMethod?.apply { fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
var registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) + 2 var registerIndex = indexOfFirstConstantInstructionValue(resourceId) + 2
var colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA var colorRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
addInstructions( addInstructions(
registerIndex + 1, registerIndex + 1,
""" """
invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
move-result v$colorRegister move-result v$colorRegister
""" """
) )
}
registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) + 2
colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA PlayerSeekbarColorFingerprint.result?.mutableMethod?.apply {
addInstructions( addColorChangeInstructions(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId)
registerIndex + 1, addColorChangeInstructions(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId)
""" } ?: return PlayerSeekbarColorFingerprint.toErrorResult()
invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
move-result v$colorRegister ShortsSeekbarColorFingerprint.result?.mutableMethod?.apply {
""" addColorChangeInstructions(SeekbarColorResourcePatch.reelTimeBarPlayedColorId)
) } ?: return ShortsSeekbarColorFingerprint.toErrorResult()
} ?: return CreateDarkThemeSeekbarFingerprint.toErrorResult()
SetSeekbarClickedColorFingerprint.result?.let { result -> SetSeekbarClickedColorFingerprint.result?.let { result ->
result.mutableMethod.let { result.mutableMethod.let {
@@ -62,7 +62,7 @@ class SeekbarColorBytecodePatch : BytecodePatch(
.getMethod() as MutableMethod .getMethod() as MutableMethod
method.apply { method.apply {
val colorRegister = (method.getInstruction(0) as TwoRegisterInstruction).registerA val colorRegister = getInstruction<TwoRegisterInstruction>(0).registerA
addInstructions( addInstructions(
0, 0,
""" """

View File

@@ -9,17 +9,20 @@ import org.w3c.dom.Element
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
class SeekbarColorResourcePatch : ResourcePatch { class SeekbarColorResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
// Edit theme colors via bytecode.
// For that the resource id is used in a bytecode patch to change the color.
val seekbarErrorMessage = "Could not find seekbar resource" override fun execute(context: ResourceContext): PatchResult {
inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch.resourceMappings fun findColorResource(resourceName: String): Long {
.find { it.name == "inline_time_bar_colorized_bar_played_color_dark" }?.id return ResourceMappingPatch.resourceMappings
?: return PatchResultError(seekbarErrorMessage) .find { it.type == "color" && it.name == resourceName }?.id
inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch.resourceMappings ?: throw PatchResultError("Could not find color resource: $resourceName")
.find { it.name == "inline_time_bar_played_not_highlighted_color" }?.id }
?: return PatchResultError(seekbarErrorMessage)
reelTimeBarPlayedColorId =
findColorResource("reel_time_bar_played_color")
inlineTimeBarColorizedBarPlayedColorDarkId =
findColorResource("inline_time_bar_colorized_bar_played_color_dark")
inlineTimeBarPlayedNotHighlightedColorId =
findColorResource("inline_time_bar_played_not_highlighted_color")
// Edit the resume playback drawable and replace the progress bar with a custom drawable // Edit the resume playback drawable and replace the progress bar with a custom drawable
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor -> context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
@@ -39,6 +42,7 @@ class SeekbarColorResourcePatch : ResourcePatch {
} }
companion object { companion object {
internal var reelTimeBarPlayedColorId = -1L
internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L internal var inlineTimeBarColorizedBarPlayedColorDarkId = -1L
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
} }

View File

@@ -42,7 +42,7 @@ class SpoofAppVersionPatch : BytecodePatch(
StringResource("revanced_spoof_app_version_user_dialog_message", StringResource("revanced_spoof_app_version_user_dialog_message",
"App version will be spoofed to an older version of YouTube." "App version will be spoofed to an older version of YouTube."
+ "\\n\\nThis will change the appearance and features of the app, but unknown side effects may occur." + "\\n\\nThis will change the appearance and features of the app, but unknown side effects may occur."
+ "\\n\\nIf later turned off, the old UI may remain until you log out or clear the app data.") + "\\n\\nIf later turned off, the old UI may remain until the app data is cleared.")
), ),
ListPreference( ListPreference(
"revanced_spoof_app_version_target", "revanced_spoof_app_version_target",
@@ -54,7 +54,7 @@ class SpoofAppVersionPatch : BytecodePatch(
"revanced_spoof_app_version_target_entries", "revanced_spoof_app_version_target_entries",
listOf( listOf(
StringResource("revanced_spoof_app_version_target_entry_1", "17.30.35 - Restore old UI layout"), StringResource("revanced_spoof_app_version_target_entry_1", "17.30.35 - Restore old UI layout"),
StringResource("revanced_spoof_app_version_target_entry_2", "17.01.35 - Enable sorting videos by oldest"), StringResource("revanced_spoof_app_version_target_entry_2", "17.01.35 - Restore old watch history"),
StringResource("revanced_spoof_app_version_target_entry_3", "16.08.35 - Restore explore tab"), StringResource("revanced_spoof_app_version_target_entry_3", "16.08.35 - Restore explore tab"),
StringResource("revanced_spoof_app_version_target_entry_4", "16.01.35 - Restore old Shorts player"), StringResource("revanced_spoof_app_version_target_entry_4", "16.01.35 - Restore old Shorts player"),
) )

View File

@@ -9,6 +9,7 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.InputType 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.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.TextPreference
import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarPreferencesPatch import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarPreferencesPatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.ThemeBytecodePatch.Companion.darkThemeBackgroundColor import app.revanced.patches.youtube.layout.theme.bytecode.patch.ThemeBytecodePatch.Companion.darkThemeBackgroundColor
@@ -20,10 +21,16 @@ import org.w3c.dom.Element
class ThemeResourcePatch : ResourcePatch { class ThemeResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
SeekbarPreferencesPatch.addPreferences( SeekbarPreferencesPatch.addPreferences(
SwitchPreference(
"revanced_seekbar_custom_color",
StringResource("revanced_seekbar_custom_color_title", "Enable custom seekbar color"),
StringResource("revanced_seekbar_custom_color_summary_on", "Custom seekbar color is shown"),
StringResource("revanced_seekbar_custom_color_summary_off", "Original seekbar color is shown")
),
TextPreference( TextPreference(
"revanced_seekbar_color", "revanced_seekbar_custom_color_value",
StringResource("revanced_seekbar_color_title", "Seekbar color"), StringResource("revanced_seekbar_custom_color_value_title", "Custom seekbar color"),
StringResource("revanced_seekbar_color_summary", "The color of the seekbar"), StringResource("revanced_seekbar_custom_color_value_summary", "The color of the seekbar"),
InputType.TEXT_CAP_CHARACTERS InputType.TEXT_CAP_CHARACTERS
) )
) )
@@ -38,8 +45,8 @@ class ThemeResourcePatch : ResourcePatch {
node.textContent = when (node.getAttribute("name")) { node.textContent = when (node.getAttribute("name")) {
"yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3", "yt_black0", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3",
"yt_black4", "yt_status_bar_background_dark", "material_grey_850" -> darkThemeBackgroundColor "yt_black4", "yt_status_bar_background_dark", "material_grey_850"
?: continue -> darkThemeBackgroundColor ?: continue
"yt_white1", "yt_white1_opacity95", "yt_white1_opacity98", "yt_white1", "yt_white1_opacity95", "yt_white1_opacity98",
"yt_white2", "yt_white3", "yt_white4", "yt_white2", "yt_white3", "yt_white4",
@@ -51,36 +58,43 @@ class ThemeResourcePatch : ResourcePatch {
} }
// Add a dynamic background color to the colors.xml file. // Add a dynamic background color to the colors.xml file.
addResourceColor(context, "res/values/colors.xml", lightThemeBackgroundColor?.let {
SPLASH_BACKGROUND_COLOR, lightThemeBackgroundColor!!) addColorResource(context, "res/values/colors.xml", SPLASH_BACKGROUND_COLOR, it)
addResourceColor(context, "res/values-night/colors.xml", }
SPLASH_BACKGROUND_COLOR, darkThemeBackgroundColor!!)
// Edit splash screen files and change the background color. darkThemeBackgroundColor?.let {
val splashScreenResourceFiles = listOf( addColorResource(context, "res/values-night/colors.xml", SPLASH_BACKGROUND_COLOR, it)
"res/drawable/quantum_launchscreen_youtube.xml", }
"res/drawable-sw600dp/quantum_launchscreen_youtube.xml")
splashScreenResourceFiles.forEach editSplashScreen@ { resourceFile -> // Edit splash screen files and change the background color,
context.xmlEditor[resourceFile].use { // if the background colors are set.
val layerList = it.file.getElementsByTagName("layer-list").item(0) as Element if (darkThemeBackgroundColor != null && lightThemeBackgroundColor != null) {
val splashScreenResourceFiles = listOf(
"res/drawable/quantum_launchscreen_youtube.xml",
"res/drawable-sw600dp/quantum_launchscreen_youtube.xml")
val childNodes = layerList.childNodes splashScreenResourceFiles.forEach editSplashScreen@ { resourceFile ->
for (i in 0 until childNodes.length) { context.xmlEditor[resourceFile].use {
val node = childNodes.item(i) val layerList = it.file.getElementsByTagName("layer-list").item(0) as Element
if (node is Element && node.hasAttribute("android:drawable")) {
node.setAttribute("android:drawable", "@color/$SPLASH_BACKGROUND_COLOR") val childNodes = layerList.childNodes
return@editSplashScreen for (i in 0 until childNodes.length) {
val node = childNodes.item(i)
if (node is Element && node.hasAttribute("android:drawable")) {
node.setAttribute("android:drawable", "@color/$SPLASH_BACKGROUND_COLOR")
return@editSplashScreen
}
} }
return PatchResultError("Failed to modify launch screen")
} }
return PatchResultError("Failed to modify launch screen")
} }
} }
return PatchResultSuccess() return PatchResultSuccess()
} }
private fun addResourceColor( private fun addColorResource(
context: ResourceContext, context: ResourceContext,
resourceFile: String, resourceFile: String,
colorName: String, colorName: String,

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.patch.SpoofSignatureVerificationResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.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.
literal = SpoofSignatureVerificationResourcePatch.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.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
/**
* Resolves using the class found in [StoryboardThumbnailParentFingerprint].
*/
object StoryboardThumbnailFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Z",
parameters = listOf(),
opcodes = listOf(
Opcode.MOVE_RESULT,
Opcode.IF_GTZ,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.RETURN, // Last instruction of method.
),
)

View File

@@ -0,0 +1,17 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
/**
* Here lies code that creates the seekbar thumbnails.
*
* An additional change here might force the thumbnails to be created,
* or possibly a change somewhere else (maybe involving YouTube 18.23.35 class `hte`)
*/
object StoryboardThumbnailParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Landroid/graphics/Bitmap;",
strings = listOf("Storyboard regionDecoder.decodeRegion exception - "),
)

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode

View File

@@ -7,47 +7,35 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@Name("Spoof signature verification") @Name("Spoof signature verification")
@Description("Spoofs a patched client to prevent playback issues.") @Description("Spoofs a patched client to prevent playback issues.")
@DependsOn([ @DependsOn([
SpoofSignatureVerificationResourcePatch::class,
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsPatch::class, PlayerTypeHookPatch::class
PlayerTypeHookPatch::class,
]) ])
@Version("0.0.1") @Version("0.0.1")
class SpoofSignatureVerificationPatch : BytecodePatch( class SpoofSignatureVerificationPatch : BytecodePatch(
listOf( listOf(
ProtobufParameterBuilderFingerprint, ProtobufParameterBuilderFingerprint,
StoryboardThumbnailParentFingerprint,
ScrubbedPreviewLayoutFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_spoof_signature_verification",
StringResource("revanced_spoof_signature_verification_title", "Spoof app signature"),
StringResource("revanced_spoof_signature_verification_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• Ambient mode may not work\\n"
+ "• Seekbar thumbnails are hidden\\n"
+ "• Downloading videos may not work"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"),
StringResource("revanced_spoof_signature_verification_user_dialog_message",
"Turning off this setting may cause playback issues.")
)
)
// hook parameter // hook parameter
ProtobufParameterBuilderFingerprint.result?.let { ProtobufParameterBuilderFingerprint.result?.let {
@@ -68,6 +56,53 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
} }
} ?: return ProtobufParameterBuilderFingerprint.toErrorResult() } ?: return ProtobufParameterBuilderFingerprint.toErrorResult()
// When signature spoofing is enabled, the seekbar when tapped does not show
// the video time, chapter names, or the video thumbnail.
// Changing the value returned of this method forces all of these to show up,
// except the thumbnails are blank, which is handled with the patch below.
StoryboardThumbnailParentFingerprint.result ?: return StoryboardThumbnailParentFingerprint.toErrorResult()
StoryboardThumbnailFingerprint.resolve(context, StoryboardThumbnailParentFingerprint.result!!.classDef)
StoryboardThumbnailFingerprint.result?.apply {
val endIndex = scanResult.patternScanResult!!.endIndex
// Replace existing instruction to preserve control flow label.
// The replaced return instruction always returns false
// (it is the 'no thumbnails found' control path),
// so there is no need to pass the existing return value to integrations.
mutableMethod.replaceInstruction(
endIndex,
"""
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSeekbarThumbnailOverrideValue()Z
"""
)
// Since this is end of the method must replace one line then add the rest.
mutableMethod.addInstructions(
endIndex + 1,
"""
move-result v0
return v0
"""
)
} ?: return StoryboardThumbnailFingerprint.toErrorResult()
// Seekbar thumbnail now show up but are always a blank image.
// Additional changes are needed to force the client to generate the thumbnails (assuming it's possible),
// but for now hide the empty thumbnail.
ScrubbedPreviewLayoutFingerprint.result?.apply {
val endIndex = scanResult.patternScanResult!!.endIndex
mutableMethod.apply {
val imageViewFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
addInstructions(
implementation!!.instructions.lastIndex,
"""
iget-object v0, p0, $imageViewFieldName # copy imageview field to a register
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->seekbarImageViewCreated(Landroid/widget/ImageView;)V
"""
)
}
} ?: return ScrubbedPreviewLayoutFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -0,0 +1,44 @@
package app.revanced.patches.youtube.misc.fix.playback.patch
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
class SpoofSignatureVerificationResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_spoof_signature_verification",
StringResource("revanced_spoof_signature_verification_title", "Spoof app signature"),
StringResource("revanced_spoof_signature_verification_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• Ambient mode may not work\\n"
+ "• Seekbar thumbnails are hidden\\n"
+ "• Downloading videos may not work"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"),
StringResource("revanced_spoof_signature_verification_user_dialog_message",
"Turning off this setting may cause playback issues.")
)
)
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "thumbnail"
}.id
return PatchResultSuccess()
}
companion object {
var scrubbedPreviewThumbnailResourceId: Long = -1
}
}

View File

@@ -176,7 +176,7 @@ class LithoFilterPatch : BytecodePatch(
""" """
new-instance v1, $classDescriptor new-instance v1, $classDescriptor
invoke-direct {v1}, $classDescriptor-><init>()V invoke-direct {v1}, $classDescriptor-><init>()V
const/4 v2, ${filterCount++} const/16 v2, ${filterCount++}
aput-object v1, v0, v2 aput-object v1, v0, v2
""" """
) )
@@ -187,7 +187,7 @@ class LithoFilterPatch : BytecodePatch(
} }
override fun close() = LithoFilterFingerprint.result!! override fun close() = LithoFilterFingerprint.result!!
.mutableMethod.replaceInstruction(0, "const/4 v0, $filterCount") .mutableMethod.replaceInstruction(0, "const/16 v0, $filterCount")
companion object { companion object {
private val MethodFingerprint.patternScanResult private val MethodFingerprint.patternScanResult
@@ -208,4 +208,4 @@ class LithoFilterPatch : BytecodePatch(
private var filterCount = 0 private var filterCount = 0
} }
} }

View File

@@ -1,25 +1,25 @@
package app.revanced.patches.youtube.video.speed package app.revanced.patches.youtube.video.speed
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.video.speed.custom.patch.CustomVideoSpeedPatch import app.revanced.patches.youtube.video.speed.custom.patch.CustomPlaybackSpeedPatch
import app.revanced.patches.youtube.video.speed.remember.patch.RememberPlaybackSpeedPatch import app.revanced.patches.youtube.video.speed.remember.patch.RememberPlaybackSpeedPatch
@Patch @Patch
@Name("Video speed") @Name("Playback speed")
@Description("Adds custom video speeds and ability to remember the playback speed you chose in the video playback speed flyout.") @Description("Adds custom playback speeds and ability to remember the playback speed you chose in the video playback speed flyout.")
@DependsOn([CustomVideoSpeedPatch::class, RememberPlaybackSpeedPatch::class]) @DependsOn([CustomPlaybackSpeedPatch::class, RememberPlaybackSpeedPatch::class])
@VideoSpeedCompatibility @PlaybackSpeedCompatibility
@Version("0.0.1") @Version("0.0.1")
class VideoSpeed : BytecodePatch() { class PlaybackSpeed : BytecodePatch() {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
return PatchResultSuccess() // All patches this patch depends on succeed. return PatchResultSuccess() // All patches this patch depends on succeed.
} }
} }

View File

@@ -5,4 +5,4 @@ import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35"))]) @Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35"))])
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
internal annotation class VideoSpeedCompatibility internal annotation class PlaybackSpeedCompatibility

View File

@@ -2,7 +2,7 @@ package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object GetOldVideoSpeedsFingerprint : MethodFingerprint( object GetOldPlaybackSpeedsFingerprint : MethodFingerprint(
parameters = listOf("[L", "I"), parameters = listOf("[L", "I"),
strings = listOf("menu_item_playback_speed") strings = listOf("menu_item_playback_speed")
) )

View File

@@ -2,6 +2,6 @@ package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object ShowOldVideoSpeedMenuFingerprint : MethodFingerprint( object ShowOldPlaybackSpeedMenuFingerprint : MethodFingerprint(
strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT") strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT")
) )

View File

@@ -0,0 +1,7 @@
package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object ShowOldPlaybackSpeedMenuIntegrationsFingerprint : MethodFingerprint(
customFingerprint = { method, _ -> method.name == "showOldPlaybackSpeedMenu" }
)

View File

@@ -1,7 +0,0 @@
package app.revanced.patches.youtube.video.speed.custom.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object ShowOldVideoSpeedMenuIntegrationsFingerprint : MethodFingerprint(
customFingerprint = { method, _ -> method.name == "showOldVideoSpeedMenu" }
)

View File

@@ -31,16 +31,16 @@ import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.immutable.ImmutableField import org.jf.dexlib2.immutable.ImmutableField
@Name("Custom video speed") @Name("Custom playback speed")
@Description("Adds custom video speed options.") @Description("Adds custom playback speed options.")
@DependsOn([IntegrationsPatch::class, LithoFilterPatch::class, SettingsPatch::class, BottomSheetHookPatch::class]) @DependsOn([IntegrationsPatch::class, LithoFilterPatch::class, SettingsPatch::class, BottomSheetHookPatch::class])
@Version("0.0.1") @Version("0.0.1")
class CustomVideoSpeedPatch : BytecodePatch( class CustomPlaybackSpeedPatch : BytecodePatch(
listOf( listOf(
SpeedArrayGeneratorFingerprint, SpeedArrayGeneratorFingerprint,
SpeedLimiterFingerprint, SpeedLimiterFingerprint,
GetOldVideoSpeedsFingerprint, GetOldPlaybackSpeedsFingerprint,
ShowOldVideoSpeedMenuIntegrationsFingerprint ShowOldPlaybackSpeedMenuIntegrationsFingerprint
) )
) { ) {
@@ -81,12 +81,12 @@ class CustomVideoSpeedPatch : BytecodePatch(
val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA
val videoSpeedsArrayType = "$INTEGRATIONS_CLASS_DESCRIPTOR->customVideoSpeeds:[F" val playbackSpeedsArrayType = "$INTEGRATIONS_CLASS_DESCRIPTOR->customPlaybackSpeeds:[F"
arrayGenMethod.addInstructions( arrayGenMethod.addInstructions(
arrayLengthConstIndex + 1, arrayLengthConstIndex + 1,
""" """
sget-object v$arrayLengthConstDestination, $videoSpeedsArrayType sget-object v$arrayLengthConstDestination, $playbackSpeedsArrayType
array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination
""" """
) )
@@ -102,7 +102,7 @@ class CustomVideoSpeedPatch : BytecodePatch(
arrayGenMethod.replaceInstruction( arrayGenMethod.replaceInstruction(
originalArrayFetchIndex, originalArrayFetchIndex,
"sget-object v$originalArrayFetchDestination, $videoSpeedsArrayType" "sget-object v$originalArrayFetchDestination, $playbackSpeedsArrayType"
) )
val limiterMethod = SpeedLimiterFingerprint.result?.mutableMethod!! val limiterMethod = SpeedLimiterFingerprint.result?.mutableMethod!!
@@ -121,24 +121,24 @@ class CustomVideoSpeedPatch : BytecodePatch(
// edit: alternatively this might work by overriding with fixed values such as 0.1x and 10x // edit: alternatively this might work by overriding with fixed values such as 0.1x and 10x
limiterMethod.replaceInstruction( limiterMethod.replaceInstruction(
limiterMinConstIndex, limiterMinConstIndex,
"sget v$limiterMinConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->minVideoSpeed:F" "sget v$limiterMinConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->minPlaybackSpeed:F"
) )
limiterMethod.replaceInstruction( limiterMethod.replaceInstruction(
limiterMaxConstIndex, limiterMaxConstIndex,
"sget v$limiterMaxConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->maxVideoSpeed:F" "sget v$limiterMaxConstDestination, $INTEGRATIONS_CLASS_DESCRIPTOR->maxPlaybackSpeed:F"
) )
// region Force old video quality menu. // region Force old video quality menu.
// This is necessary, because there is no known way of adding custom video speeds to the new menu. // This is necessary, because there is no known way of adding custom playback speeds to the new menu.
BottomSheetHookPatch.addHook(INTEGRATIONS_CLASS_DESCRIPTOR) BottomSheetHookPatch.addHook(INTEGRATIONS_CLASS_DESCRIPTOR)
// Required to check if the video speed menu is currently shown. // Required to check if the playback speed menu is currently shown.
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
GetOldVideoSpeedsFingerprint.result?.let { result -> GetOldPlaybackSpeedsFingerprint.result?.let { result ->
// Add a static INSTANCE field to the class. // Add a static INSTANCE field to the class.
// This is later used to call "showOldVideoSpeedMenu" on the instance. // This is later used to call "showOldPlaybackSpeedMenu" on the instance.
val instanceField = ImmutableField( val instanceField = ImmutableField(
result.classDef.type, result.classDef.type,
"INSTANCE", "INSTANCE",
@@ -154,15 +154,15 @@ class CustomVideoSpeedPatch : BytecodePatch(
// In order to prevent a conflict with another patch, add the instruction at index 1. // In order to prevent a conflict with another patch, add the instruction at index 1.
result.mutableMethod.addInstruction(1, "sput-object p0, $instanceField") result.mutableMethod.addInstruction(1, "sput-object p0, $instanceField")
// Get the "showOldVideoSpeedMenu" method. // Get the "showOldPlaybackSpeedMenu" method.
// This is later called on the field INSTANCE. // This is later called on the field INSTANCE.
val showOldVideoSpeedMenuMethod = ShowOldVideoSpeedMenuFingerprint.also { val showOldPlaybackSpeedMenuMethod = ShowOldPlaybackSpeedMenuFingerprint.also {
if (!it.resolve(context, result.classDef)) if (!it.resolve(context, result.classDef))
throw ShowOldVideoSpeedMenuFingerprint.toErrorResult() throw ShowOldPlaybackSpeedMenuFingerprint.toErrorResult()
}.result!!.method.toString() }.result!!.method.toString()
// Insert the call to the "showOldVideoSpeedMenu" method on the field INSTANCE. // Insert the call to the "showOldPlaybackSpeedMenu" method on the field INSTANCE.
ShowOldVideoSpeedMenuIntegrationsFingerprint.result?.mutableMethod?.apply { ShowOldPlaybackSpeedMenuIntegrationsFingerprint.result?.mutableMethod?.apply {
addInstructionsWithLabels( addInstructionsWithLabels(
implementation!!.instructions.lastIndex, implementation!!.instructions.lastIndex,
""" """
@@ -170,11 +170,11 @@ class CustomVideoSpeedPatch : BytecodePatch(
if-nez v0, :not_null if-nez v0, :not_null
return-void return-void
:not_null :not_null
invoke-virtual { v0 }, $showOldVideoSpeedMenuMethod invoke-virtual { v0 }, $showOldPlaybackSpeedMenuMethod
""" """
) )
} ?: return ShowOldVideoSpeedMenuIntegrationsFingerprint.toErrorResult() } ?: return ShowOldPlaybackSpeedMenuIntegrationsFingerprint.toErrorResult()
} ?: return GetOldVideoSpeedsFingerprint.toErrorResult() } ?: return GetOldPlaybackSpeedsFingerprint.toErrorResult()
// endregion // endregion
@@ -183,10 +183,10 @@ class CustomVideoSpeedPatch : BytecodePatch(
private companion object { private companion object {
private const val FILTER_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/components/VideoSpeedMenuFilterPatch;" "Lapp/revanced/integrations/patches/components/PlaybackSpeedMenuFilterPatch;"
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/playback/speed/CustomVideoSpeedPatch;" "Lapp/revanced/integrations/patches/playback/speed/CustomPlaybackSpeedPatch;"
} }
} }

View File

@@ -19,13 +19,13 @@ import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.video.information.patch.VideoInformationPatch import app.revanced.patches.youtube.video.information.patch.VideoInformationPatch
import app.revanced.patches.youtube.video.speed.custom.patch.CustomVideoSpeedPatch import app.revanced.patches.youtube.video.speed.custom.patch.CustomPlaybackSpeedPatch
import app.revanced.patches.youtube.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint import app.revanced.patches.youtube.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@Name("Remember playback speed") @Name("Remember playback speed")
@Description("Adds the ability to remember the playback speed you chose in the video playback speed flyout.") @Description("Adds the ability to remember the playback speed you chose in the playback speed flyout.")
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoInformationPatch::class, CustomVideoSpeedPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoInformationPatch::class, CustomPlaybackSpeedPatch::class])
@Version("0.0.1") @Version("0.0.1")
class RememberPlaybackSpeedPatch : BytecodePatch( class RememberPlaybackSpeedPatch : BytecodePatch(
listOf( listOf(