mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-26 10:54:07 +01:00
Compare commits
52 Commits
v2.188.0-d
...
v2.191.0-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe3a6fd4a4 | ||
|
|
2a340d21d7 | ||
|
|
ce6a9fc1ec | ||
|
|
632b50e1fe | ||
|
|
2957d3791a | ||
|
|
f894561817 | ||
|
|
04bc0f54e3 | ||
|
|
3fc64530c5 | ||
|
|
74df205be5 | ||
|
|
a09797710e | ||
|
|
5f43afcbaf | ||
|
|
a9308d46e2 | ||
|
|
9470694cd4 | ||
|
|
06503e9527 | ||
|
|
c322a9b7aa | ||
|
|
d18c6cfc3a | ||
|
|
6c8d545c6e | ||
|
|
6b3bde3bda | ||
|
|
a6e032d447 | ||
|
|
728d49ddb5 | ||
|
|
4dc9a7f6e1 | ||
|
|
1f9683849f | ||
|
|
4f7506ba21 | ||
|
|
c0163c122c | ||
|
|
b0875a168d | ||
|
|
bb3a32a407 | ||
|
|
f27af6fdfa | ||
|
|
a478db3cca | ||
|
|
dc6fa70d6f | ||
|
|
3d93a9d851 | ||
|
|
426c4c2600 | ||
|
|
8bcbd8443d | ||
|
|
1d01155b47 | ||
|
|
bada0ea50f | ||
|
|
0a9e0982da | ||
|
|
078e5d3b88 | ||
|
|
2adfc37a66 | ||
|
|
392021124c | ||
|
|
d5dd8a22de | ||
|
|
03725b853a | ||
|
|
3938f2f1b3 | ||
|
|
ce2e46a7cb | ||
|
|
75a113d327 | ||
|
|
9bc4323a80 | ||
|
|
74ef6843cb | ||
|
|
4318cf7121 | ||
|
|
a4b33f2063 | ||
|
|
5979230705 | ||
|
|
79b037d044 | ||
|
|
c5ef490eee | ||
|
|
69092def55 | ||
|
|
004aae8258 |
197
CHANGELOG.md
197
CHANGELOG.md
@@ -1,3 +1,200 @@
|
||||
# [2.191.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v2.191.0-dev.4...v2.191.0-dev.5) (2023-09-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Restore functionality of `Old video quality menu` and `Custom speeds` on tablets ([#2999](https://github.com/ReVanced/revanced-patches/issues/2999)) ([238bed1](https://github.com/ReVanced/revanced-patches/commit/238bed12519ec61a53b1ee72da467830ef252154))
|
||||
|
||||
# [2.191.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.191.0-dev.3...v2.191.0-dev.4) (2023-09-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Twitch - Block embedded ads:** Switch from `ttv.lol` to `luminous.dev` ([0fe115e](https://github.com/ReVanced/revanced-patches/commit/0fe115e8f98ccdc86d318090fc92fe77cece1dd8))
|
||||
|
||||
# [2.191.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.191.0-dev.2...v2.191.0-dev.3) (2023-09-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **TU Dortmund:** Add `Show on lockscreen` patch ([#2947](https://github.com/ReVanced/revanced-patches/issues/2947)) ([9a18326](https://github.com/ReVanced/revanced-patches/commit/9a18326aeb68d7518594d0eab326ca845b9bdbdd))
|
||||
* **Tumblr:** Add `Disable blog notification reminder` patch ([29f19b9](https://github.com/ReVanced/revanced-patches/commit/29f19b9378c7e167137f38fa4517ae19382ca4f6))
|
||||
* **Tumblr:** Add `Disable gift message popup` patch ([a4d6b4e](https://github.com/ReVanced/revanced-patches/commit/a4d6b4e5ce6065d932f3895b4996e7dc1e5f7c67))
|
||||
|
||||
# [2.191.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.191.0-dev.1...v2.191.0-dev.2) (2023-09-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use consistent toggle description ([#2983](https://github.com/ReVanced/revanced-patches/issues/2983)) ([ceaa512](https://github.com/ReVanced/revanced-patches/commit/ceaa512f317fdd95dca37e425b389494a9b2e226))
|
||||
|
||||
# [2.191.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.190.1-dev.4...v2.191.0-dev.1) (2023-09-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Tumblr:** Add `Disable dashboard ads` patch ([#2979](https://github.com/ReVanced/revanced-patches/issues/2979)) ([07c267a](https://github.com/ReVanced/revanced-patches/commit/07c267ad20afa1415d2dba31f0830d2dd5a34654))
|
||||
|
||||
## [2.190.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v2.190.1-dev.3...v2.190.1-dev.4) (2023-09-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Custom filter:** Use new lines between components instead of commas ([#2952](https://github.com/ReVanced/revanced-patches/issues/2952)) ([ecb2e32](https://github.com/ReVanced/revanced-patches/commit/ecb2e32b1e296590d150bdd3f8bea2665b19a84d))
|
||||
|
||||
## [2.190.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.190.1-dev.2...v2.190.1-dev.3) (2023-09-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Infinity for Reddit - Spoof client:** Constrain patch to last working versions ([#2944](https://github.com/ReVanced/revanced-patches/issues/2944)) ([ee975de](https://github.com/ReVanced/revanced-patches/commit/ee975dea846c77af0efe608e647075f4055af320))
|
||||
|
||||
## [2.190.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.190.1-dev.1...v2.190.1-dev.2) (2023-09-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Hide layout components:** Always hide redundant 'player audio track' button ([#2951](https://github.com/ReVanced/revanced-patches/issues/2951)) ([ca632bd](https://github.com/ReVanced/revanced-patches/commit/ca632bd2cc74f0ce5ccb948e902445de3ab893cf))
|
||||
|
||||
## [2.190.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.190.0...v2.190.1-dev.1) (2023-09-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Twitch - Audio ads:** Support missing version `16.1.0` ([#2928](https://github.com/ReVanced/revanced-patches/issues/2928)) ([688d8fa](https://github.com/ReVanced/revanced-patches/commit/688d8fa7e86862e03d8336af5f6cb207c4b72593))
|
||||
|
||||
# [2.190.0](https://github.com/ReVanced/revanced-patches/compare/v2.189.0...v2.190.0) (2023-09-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Infinity for Reddit - Spoof client:** Support latest version ([8a5311b](https://github.com/ReVanced/revanced-patches/commit/8a5311b1e645ca2aab1e416d647cf52bf0be6e7f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Photomath:** Support latest version ([5a2cad0](https://github.com/ReVanced/revanced-patches/commit/5a2cad077f03880ee1417c5cfd448bbdea4c07e2))
|
||||
* **Twitch:** Support version `16.1.0` ([#2923](https://github.com/ReVanced/revanced-patches/issues/2923)) ([d9834a9](https://github.com/ReVanced/revanced-patches/commit/d9834a9abb43390af4cb33f5dd5a0e2d3b7060e2))
|
||||
|
||||
# [2.190.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v2.190.0-dev.2...v2.190.0-dev.3) (2023-09-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Twitch:** Support version `16.1.0` ([#2923](https://github.com/ReVanced/revanced-patches/issues/2923)) ([d9834a9](https://github.com/ReVanced/revanced-patches/commit/d9834a9abb43390af4cb33f5dd5a0e2d3b7060e2))
|
||||
|
||||
# [2.190.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v2.190.0-dev.1...v2.190.0-dev.2) (2023-08-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Infinity for Reddit - Spoof client:** Support latest version ([8a5311b](https://github.com/ReVanced/revanced-patches/commit/8a5311b1e645ca2aab1e416d647cf52bf0be6e7f))
|
||||
|
||||
# [2.190.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.189.0...v2.190.0-dev.1) (2023-08-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Photomath:** Support latest version ([5a2cad0](https://github.com/ReVanced/revanced-patches/commit/5a2cad077f03880ee1417c5cfd448bbdea4c07e2))
|
||||
|
||||
# [2.189.0](https://github.com/ReVanced/revanced-patches/compare/v2.188.1...v2.189.0) (2023-08-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Restore previous release ([f7352fe](https://github.com/ReVanced/revanced-patches/commit/f7352feb6e9604162b52072d74310b9e3067bc69))
|
||||
|
||||
# [2.189.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.188.1...v2.189.0-dev.1) (2023-08-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Restore previous release ([f7352fe](https://github.com/ReVanced/revanced-patches/commit/f7352feb6e9604162b52072d74310b9e3067bc69))
|
||||
|
||||
## [2.188.1](https://github.com/ReVanced/revanced-patches/compare/v2.188.0...v2.188.1) (2023-08-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Revert previous release ([ed24a20](https://github.com/ReVanced/revanced-patches/commit/ed24a201a9fbe08dd6694582d0ab08ced8ad026a))
|
||||
|
||||
## [2.188.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v2.188.0...v2.188.1-dev.1) (2023-08-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Revert previous release ([ed24a20](https://github.com/ReVanced/revanced-patches/commit/ed24a201a9fbe08dd6694582d0ab08ced8ad026a))
|
||||
|
||||
# [2.188.0](https://github.com/ReVanced/revanced-patches/compare/v2.187.0...v2.188.0) (2023-08-26)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow using `PreferenceScreen` outside of current module ([fe94013](https://github.com/ReVanced/revanced-patches/commit/fe94013a2235953b32fed6e0710a252698a264b3))
|
||||
* **Client spoof:** Remove exception from option ([9c69f87](https://github.com/ReVanced/revanced-patches/commit/9c69f876902496c101eac295e581c15e02bfaf29))
|
||||
* **Enable android debugging:** Update patch description ([#2869](https://github.com/ReVanced/revanced-patches/issues/2869)) ([d9f0d08](https://github.com/ReVanced/revanced-patches/commit/d9f0d08498662e7aa18edb5201a5d60f3738e4e4))
|
||||
* improve wording ([26f9b05](https://github.com/ReVanced/revanced-patches/commit/26f9b0514fda9434b2a36d2f9e5ad6a4f5bb94bd))
|
||||
* **Reddit is Fun - Spoof client:** Use a more convincing user agent ([236a18f](https://github.com/ReVanced/revanced-patches/commit/236a18f9356cede156417c0d55a876d25a98cd4d))
|
||||
* remove newline ([545388b](https://github.com/ReVanced/revanced-patches/commit/545388b3b21cabb485c4d2025756c48984548d6b))
|
||||
* **Tiktok - Show seekbar:** Bump compatibility ([#2737](https://github.com/ReVanced/revanced-patches/issues/2737)) ([08413bd](https://github.com/ReVanced/revanced-patches/commit/08413bdc97aef892f7372c585d1d792eb95e30f4))
|
||||
* **YouTube - Client spoof:** Adjust spoof signature settings description ([#2760](https://github.com/ReVanced/revanced-patches/issues/2760)) ([f71d893](https://github.com/ReVanced/revanced-patches/commit/f71d8937663fdbfc93d8e3ce1cdb47e1667554f0))
|
||||
* **YouTube Music - Remove upgrade button:** Remove the correct navigation bar item ([fd3813f](https://github.com/ReVanced/revanced-patches/commit/fd3813f66ededdae1e52bf021a3de9d818f65096))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add `Override certificate pinning` patch ([#2781](https://github.com/ReVanced/revanced-patches/issues/2781)) ([94ed738](https://github.com/ReVanced/revanced-patches/commit/94ed738515aa6e1a1d346b85b54805e68e36f94c))
|
||||
* **Change package name:** Append `.revanced` to package name by default ([#2750](https://github.com/ReVanced/revanced-patches/issues/2750)) ([e83e62f](https://github.com/ReVanced/revanced-patches/commit/e83e62fc2400caf1c5179d25e0ac4fbd51ddba00))
|
||||
* **Duolingo:** Add `Unlock Duolingo Super` patch ([#2862](https://github.com/ReVanced/revanced-patches/issues/2862)) ([61a7533](https://github.com/ReVanced/revanced-patches/commit/61a7533136f38d7a308e31c9f250baad00515d6a))
|
||||
* Exclude `Custom branding` patch by default ([d6de957](https://github.com/ReVanced/revanced-patches/commit/d6de957f4efce11d9a709d4c8f500b039166fc2f))
|
||||
* **Lightroom:** Add `Disable mandatory login` patch ([#2738](https://github.com/ReVanced/revanced-patches/issues/2738)) ([896a713](https://github.com/ReVanced/revanced-patches/commit/896a71308f1084d7f941c5b59610e40ea5d53009))
|
||||
* **Lightroom:** Add `Unlock premium` patch ([#2740](https://github.com/ReVanced/revanced-patches/issues/2740)) ([e18a9bc](https://github.com/ReVanced/revanced-patches/commit/e18a9bcb50705d374ccbf03cd6ab9a140a2f23ec))
|
||||
* **Nova Launcher:** Remove `Unlock prime` patch ([bbde91c](https://github.com/ReVanced/revanced-patches/commit/bbde91cf9df4b410a34147bbe5f359e39a71ad4c))
|
||||
* Publicize resource utility functions ([20aff26](https://github.com/ReVanced/revanced-patches/commit/20aff26784296517257ea19d66ffd3bdfe6b06fa))
|
||||
* **Solid Explorer:** Add `Remove file size limit` patch ([01c617d](https://github.com/ReVanced/revanced-patches/commit/01c617d94e58b30bbffb3426fcfa55b8979962bd))
|
||||
* **Strava:** Add `Subscription features` patch ([#2872](https://github.com/ReVanced/revanced-patches/issues/2872)) ([387eb29](https://github.com/ReVanced/revanced-patches/commit/387eb29e7ed45169c89a03513af64104d0082f28))
|
||||
* **Tasker:** Remove `Unlock trial` patch ([8354a87](https://github.com/ReVanced/revanced-patches/commit/8354a879cfc6028820e2bb0e01d6f607e145c0f6))
|
||||
* Use an extension property to create new exception when failing to resolve a fingerprint ([47eac14](https://github.com/ReVanced/revanced-patches/commit/47eac14f039dc466c1957470d82255bfa2c06ff0))
|
||||
* **YouTube - Debug:** Logging of layout proto buffer strings ([#2759](https://github.com/ReVanced/revanced-patches/issues/2759)) ([189f719](https://github.com/ReVanced/revanced-patches/commit/189f719720551f36c6e006c45558fe5ae46ca4f8))
|
||||
* **YouTube - External downloads:** Recommend Seal instead of PowerTube ([#2803](https://github.com/ReVanced/revanced-patches/issues/2803)) ([082e067](https://github.com/ReVanced/revanced-patches/commit/082e067338026d05046ed5f398a1261aa20d3cb3))
|
||||
* **YouTube - Hide video action buttons:** Hide individual action buttons ([#2723](https://github.com/ReVanced/revanced-patches/issues/2723)) ([220f694](https://github.com/ReVanced/revanced-patches/commit/220f694b12e7ed013753c8215d181936ab2205c3))
|
||||
* **YouTube Music - Exclusive audio playback:** Support latest version ([0861991](https://github.com/ReVanced/revanced-patches/commit/0861991cfbdfa977713f1f1f4ee8a0a5fd3f939e))
|
||||
* **YouTube Music:** Add `Permanent repeat` patch ([#2722](https://github.com/ReVanced/revanced-patches/issues/2722)) ([506d49c](https://github.com/ReVanced/revanced-patches/commit/506d49c82a68faee25aede8194e7884191c0f271))
|
||||
* **YouTube Music:** Add `Permanent Shuffle` patch ([#2730](https://github.com/ReVanced/revanced-patches/issues/2730)) ([86a271c](https://github.com/ReVanced/revanced-patches/commit/86a271cd7cc3d1d2a11ff9ebe962574368b93f4f))
|
||||
* **YouTube:** Add `Alternative thumbnails` patch ([#2834](https://github.com/ReVanced/revanced-patches/issues/2834)) ([8a4277c](https://github.com/ReVanced/revanced-patches/commit/8a4277c486d995f57cde3a56274979c4a7b42bf6))
|
||||
* **YouTube:** Add `Custom player overlay opacity` patch ([#2721](https://github.com/ReVanced/revanced-patches/issues/2721)) ([2622b00](https://github.com/ReVanced/revanced-patches/commit/2622b008ab78b15aa3c28a13b38e63041f29c9ea))
|
||||
* **YouTube:** Add `Enable tablet layout` patch ([c89b2aa](https://github.com/ReVanced/revanced-patches/commit/c89b2aa26125d302079b5cf522f3b6c9fbe1257a))
|
||||
* **YouTube:** Support version `18.29.38` ([c1b9eef](https://github.com/ReVanced/revanced-patches/commit/c1b9eefa280b980d08a571e1ce205dc71ccde3b6))
|
||||
* **YouTube:** Support version `18.32.39` ([7b503e2](https://github.com/ReVanced/revanced-patches/commit/7b503e2336dd4d330b651bf7c168d95a38e8c777))
|
||||
|
||||
# [2.188.0-dev.28](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.27...v2.188.0-dev.28) (2023-08-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Add `Enable tablet layout` patch ([3ac68b3](https://github.com/ReVanced/revanced-patches/commit/3ac68b3c6ef0d568780855003217fc3e904d789b))
|
||||
|
||||
# [2.188.0-dev.27](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.26...v2.188.0-dev.27) (2023-08-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube Music - Exclusive audio playback:** Support latest version ([bfa379a](https://github.com/ReVanced/revanced-patches/commit/bfa379a398bce8d635043eb2d4f81c4ed7440101))
|
||||
|
||||
# [2.188.0-dev.26](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.25...v2.188.0-dev.26) (2023-08-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Support version `18.32.39` ([7b503e2](https://github.com/ReVanced/revanced-patches/commit/7b503e2336dd4d330b651bf7c168d95a38e8c777))
|
||||
|
||||
# [2.188.0-dev.25](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.24...v2.188.0-dev.25) (2023-08-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Add `Custom player overlay opacity` patch ([#2721](https://github.com/ReVanced/revanced-patches/issues/2721)) ([2622b00](https://github.com/ReVanced/revanced-patches/commit/2622b008ab78b15aa3c28a13b38e63041f29c9ea))
|
||||
|
||||
# [2.188.0-dev.24](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.23...v2.188.0-dev.24) (2023-08-25)
|
||||
|
||||
|
||||
|
||||
106
CONTRIBUTING.md
Normal file
106
CONTRIBUTING.md
Normal file
@@ -0,0 +1,106 @@
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
src="assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<img height="24px" src="assets/revanced-logo/revanced-logo-round.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</a>
|
||||
<a href="https://twitter.com/revancedapp">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032018-6da37214-7474-4641-a1da-7af7db3a31cd.png" />
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
# 📙 ReVanced Patches contribution guidelines
|
||||
|
||||
This document describes how to contribute to ReVanced Patches.
|
||||
|
||||
## 📖 Resources to help you get started
|
||||
|
||||
* The [documentation](https://github.com/ReVanced/revanced-patches/tree/docs/docs) provides the fundamentals of patches
|
||||
and everything necessary to create your own patch from scratch
|
||||
* [Our backlog](https://github.com/orgs/ReVanced/projects/12) is where we keep track of what we're working on
|
||||
* [Issues](https://github.com/ReVanced/revanced-patches/issues) are where we keep track of bugs and feature requests
|
||||
|
||||
## 🙏 Submitting a patch request
|
||||
|
||||
Patches can be requested by opening an issue using the
|
||||
[Patch request issue template](https://github.com/ReVanced/revanced-patches/issues/new?assignees=&labels=patch-request&projects=&template=patch-request.yml&title=feat%3A+).
|
||||
|
||||
> **Note**
|
||||
> Requests can be accepted or rejected at the discretion of maintainers of ReVanced Patches.
|
||||
> Good motivation has to be provided for a request to be accepted.
|
||||
|
||||
## 🐞 Submitting a bug report
|
||||
|
||||
If you encounter a bug while using ReVanced Patches, open an issue using the
|
||||
[Bug report issue template](https://github.com/ReVanced/revanced-patches/issues/new?assignees=&labels=bug&projects=&template=bug-issue.yml&title=bug%3A+).
|
||||
|
||||
## 🧑⚖️ Guidelines for requesting or contributing patches
|
||||
|
||||
To maintain a high-quality and ethical collection of patches, the following guidelines for requesting
|
||||
or contributing patches are effective as of September 14, 2023. Any patches present prior to this date
|
||||
are unaffected by this change.
|
||||
|
||||
> **Note**
|
||||
> We generally adhere to the guidelines outlined below. However, we may make exceptions
|
||||
> in specific cases based on our discretion. Pull requests for patches that deviate from the guidelines
|
||||
> will be evaluated individually. While a patch may not align with our general guidelines,
|
||||
> we will consider its acceptance on a case-by-case basis, taking into account its impact on user experience
|
||||
> and ethical considerations. We reserve the right to make exceptions for patches that provide significant value.
|
||||
|
||||
✅ Examples for acceptable patches include:
|
||||
|
||||
* Customizations: Feel free to contribute patches that allow users to personalize their experience
|
||||
* Ad-Blocking: Patches aimed at enhancing user privacy and blocking intrusive advertisements are appreciated
|
||||
* Feature additions: Patches that add new features or change behaviour to the app are welcome
|
||||
|
||||
❌ Examples for unacceptable patches include:
|
||||
|
||||
* Payment circumvention: We do not accept patches that exist solely to bypass payment for the app or any of its features
|
||||
* Malicious patches: Patches that are malicious in nature are not allowed
|
||||
|
||||
|
||||
## 📝 How to contribute
|
||||
|
||||
1. Before contributing, it is recommended to open an issue to discuss your change
|
||||
with the maintainers of ReVanced Patches. This will help you determine whether your change is acceptable
|
||||
and whether it is worth your time to implement it
|
||||
2. Development happens on the `dev` branch. Fork the repository and create your branch from `dev`
|
||||
3. Commit your changes. In case you are contributing a new patch, make sure to follow the conventions for patches
|
||||
described in the [documentation](https://github.com/ReVanced/revanced-patches/tree/docs/docs)
|
||||
4. Submit a pull request to the `dev` branch of the repository and reference issues
|
||||
that your pull request closes in the description of your pull request
|
||||
5. Our team will review your pull request and provide feedback. Once your pull request is approved,
|
||||
it will be merged into the `dev` branch and will be included in the next release of ReVanced Patches
|
||||
|
||||
❤️ Thank you for considering contributing to ReVanced Patches,
|
||||
ReVanced
|
||||
92
README.md
92
README.md
@@ -1,3 +1,91 @@
|
||||
## 🧩 ReVanced Patches
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
src="assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<img height="24px" src="assets/revanced-logo/revanced-logo-round.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</a>
|
||||
<a href="https://twitter.com/revancedapp">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032018-6da37214-7474-4641-a1da-7af7db3a31cd.png" />
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
Patches for ReVanced.
|
||||
|
||||
# 🧩 ReVanced Patches
|
||||
|
||||

|
||||

|
||||
|
||||
This repository contains a collection of ReVanced Patches.
|
||||
|
||||
## ❓ About
|
||||
|
||||
Patches are small modifications to Android apps that allow you to change the behaviour of or add new features,
|
||||
block ads, customize the appearance, and much more.
|
||||
|
||||
## 💪 Features
|
||||
|
||||
Some of the features the patches provide are:
|
||||
|
||||
* 🚫 **Block ads**: Say goodbye to ads
|
||||
* ⭐ **Customize your app**: Personalize the appearance of apps with various layouts and themes
|
||||
* 🪄 **Add new features**: Extend the functionality of apps with lots of new features
|
||||
* ⚙️ **Miscellaneous and general purpose**: Rename packages, enable debugging, disable screen capture restrictions,
|
||||
export activities, etc.
|
||||
* ✨ **And much more!**
|
||||
|
||||
For a full list of all available patches, visit [revanced.app/patches](https://revanced.app/patches).
|
||||
|
||||
## 🚀 How to get started
|
||||
|
||||
You can use [ReVanced CLI](https://github.com/ReVanced/revanced-cli) or [ReVanced Manager](https://github.com/ReVanced/revanced-manager) to use ReVanced Patches.
|
||||
|
||||
## 📚 Everything else
|
||||
|
||||
### 📙 Contributing
|
||||
|
||||
Thank you for considering contributing to ReVanced Patches. You can find the contribution guidelines [here](CONTRIBUTING.md).
|
||||
|
||||
### 📃 Documentation
|
||||
|
||||
The documentation provides the fundamentals of patches and everything necessary to create your own patch from scratch.
|
||||
You can find it [here](https://github.com/ReVanced/revanced-patches/tree/docs/docs).
|
||||
|
||||
### 🛠️ Building
|
||||
|
||||
In order to build ReVanced Patches, you can follow the [ReVanced documentation](https://github.com/ReVanced/revanced-documentation).
|
||||
|
||||
## 📜 Licence
|
||||
|
||||
ReVanced Patches is licensed under the GPLv3 licence. Please see the [licence file](LICENSE) for more information.
|
||||
[tl;dr](https://www.tldrlegal.com/license/gnu-general-public-license-v3-gpl-3) you may copy, distribute and modify ReVanced patches as long as you track changes/dates in source files.
|
||||
Any modifications to ReVanced Patches must also be made available under the GPL along with build & install instructions.
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
1
assets/revanced-logo/revanced-logo-round.svg
Normal file
1
assets/revanced-logo/revanced-logo-round.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 800 800" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="Logo"><g id="Ring"><circle id="Ring-Background" serif:id="Ring Background" cx="400" cy="400" r="400" style="fill:#1b1b1b;"/><path id="Ring1" serif:id="Ring" d="M400,0c220.766,0 400,179.234 400,400c-0,220.766 -179.234,400 -400,400c-220.766,-0 -400,-179.234 -400,-400c0,-220.766 179.234,-400 400,-400Zm-0,36c200.897,-0 364,163.103 364,364c0,200.897 -163.103,364 -364,364c-200.897,0 -364,-163.103 -364,-364c-0,-200.897 163.103,-364 364,-364Z" style="fill:url(#_Linear1);"/></g><g id="Shape"><path id="V-Shape" serif:id="V Shape" d="M538.74,269.872c1.481,-3.382 1.157,-7.283 -0.863,-10.373c-2.021,-3.091 -5.464,-4.954 -9.156,-4.954c-5.148,0 -10.435,0 -14.165,0c-3.1,0 -5.907,1.834 -7.153,4.672c-12.468,28.396 -78.273,178.273 -100.25,228.328c-1.246,2.838 -4.053,4.671 -7.154,4.671c-3.1,0 -5.907,-1.833 -7.153,-4.671c-21.977,-50.055 -87.782,-199.932 -100.25,-228.328c-1.246,-2.838 -4.053,-4.672 -7.153,-4.672c-3.73,0 -9.017,0 -14.164,0c-3.693,0 -7.135,1.863 -9.156,4.954c-2.02,3.09 -2.344,6.991 -0.863,10.373c23.557,53.766 101.872,232.519 117.871,269.034c1.743,3.979 5.674,6.549 10.018,6.549c6.293,-0 15.408,-0 21.701,-0c4.344,-0 8.275,-2.57 10.018,-6.549c15.999,-36.515 94.315,-215.268 117.872,-269.034Z" style="fill:#fff;"/><path id="Diamond" d="M408.119,395.312c-1.675,2.901 -4.77,4.688 -8.119,4.688c-3.349,-0 -6.444,-1.787 -8.119,-4.688c-16.997,-29.44 -56.156,-97.264 -73.153,-126.704c-1.675,-2.901 -1.675,-6.474 0,-9.375c1.675,-2.901 4.77,-4.688 8.119,-4.688c33.995,0 112.311,0 146.306,0c3.349,0 6.444,1.787 8.119,4.688c1.675,2.901 1.675,6.474 -0,9.375c-16.997,29.44 -56.156,97.264 -73.153,126.704Z" style="fill:url(#_Linear2);"/></g></g><defs><linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(4.89859e-14,800,-800,4.89859e-14,400.001,3.31681e-10)"><stop offset="0" style="stop-color:#f04e98;stop-opacity:1"/><stop offset="0.5" style="stop-color:#5f65d4;stop-opacity:1"/><stop offset="1" style="stop-color:#4e98f0;stop-opacity:1"/></linearGradient><linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.77155e-14,289.317,-282.535,1.73003e-14,400,254.545)"><stop offset="0" style="stop-color:#f04e98;stop-opacity:1"/><stop offset="0.5" style="stop-color:#5f65d4;stop-opacity:1"/><stop offset="1" style="stop-color:#4e98f0;stop-opacity:1"/></linearGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -25,7 +25,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("app.revanced:revanced-patcher:14.0.0")
|
||||
implementation("app.revanced:revanced-patcher:14.2.1")
|
||||
implementation("com.android.tools.smali:smali:3.0.3")
|
||||
// Required because build fails without it.
|
||||
// TODO: Find a way to remove this dependency.
|
||||
@@ -50,7 +50,7 @@ tasks {
|
||||
val androidHome = System.getenv("ANDROID_HOME") ?: throw GradleException("ANDROID_HOME not found")
|
||||
val d8 = "${androidHome}/build-tools/33.0.1/d8"
|
||||
val input = configurations.archives.get().allArtifacts.files.files.first().absolutePath
|
||||
val work = File("${buildDir}/libs")
|
||||
val work = layout.buildDirectory.dir("libs").get().asFile
|
||||
|
||||
exec {
|
||||
workingDir = work
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 2.188.0-dev.24
|
||||
version = 2.191.0-dev.5
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -15,7 +15,7 @@ import java.util.*
|
||||
@Name("Spoof wifi connection")
|
||||
@Description("Spoofs an existing Wi-Fi connection.")
|
||||
@RequiresIntegrations
|
||||
internal class SpoofWifiPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
class SpoofWifiPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
|
||||
private companion object {
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = "Lapp/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch"
|
||||
|
||||
@@ -7,7 +7,10 @@ import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.patch.annotations.RequiresIntegrations
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.all.screencapture.removerestriction.resource.patch.RemoveCaptureRestrictionResourcePatch
|
||||
import app.revanced.util.patch.*
|
||||
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.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
@@ -17,7 +20,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
@Description("Removes the restriction of capturing audio from apps that normally wouldn't allow it.")
|
||||
@DependsOn([RemoveCaptureRestrictionResourcePatch::class])
|
||||
@RequiresIntegrations
|
||||
internal class RemoveCaptureRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
class RemoveCaptureRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
// Information about method calls we want to replace
|
||||
enum class MethodCall(
|
||||
override val definedClassName: String,
|
||||
|
||||
@@ -5,17 +5,19 @@ import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.patch.annotations.RequiresIntegrations
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.util.patch.*
|
||||
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.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
import java.util.*
|
||||
|
||||
@Patch(false)
|
||||
@Name("Remove screenshot restriction")
|
||||
@Description("Removes the restriction of taking screenshots in apps that normally wouldn't allow it.")
|
||||
@RequiresIntegrations
|
||||
internal class RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
class RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
|
||||
private companion object {
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
|
||||
|
||||
@@ -5,14 +5,11 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
object AudioOnlyEnablerFingerprint: MethodFingerprint(
|
||||
"Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
object AllowExclusiveAudioPlaybackFingerprint: MethodFingerprint(
|
||||
"Z",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf(),
|
||||
listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
@@ -1,25 +1,31 @@
|
||||
package app.revanced.patches.music.audio.exclusiveaudio.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.music.annotations.MusicCompatibility
|
||||
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AudioOnlyEnablerFingerprint
|
||||
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AllowExclusiveAudioPlaybackFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("Exclusive audio playback")
|
||||
@Description("Enables the option to play music without video.")
|
||||
@Description("Enables the option to play audio without video.")
|
||||
@MusicCompatibility
|
||||
class ExclusiveAudioPatch : BytecodePatch(
|
||||
listOf(AudioOnlyEnablerFingerprint)
|
||||
listOf(AllowExclusiveAudioPlaybackFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
val method = AudioOnlyEnablerFingerprint.result!!.mutableMethod
|
||||
method.replaceInstruction(method.implementation!!.instructions.count() - 1, "const/4 v0, 0x1")
|
||||
method.addInstruction("return v0")
|
||||
AllowExclusiveAudioPlaybackFingerprint.result?.mutableMethod?.apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
} ?: throw AllowExclusiveAudioPlaybackFingerprint.exception
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.photomath.detection.deviceid.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
object GetDeviceIdFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
strings = listOf("androidId", "android_id"),
|
||||
parameters = listOf()
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
package app.revanced.patches.photomath.detection.deviceid.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
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.replaceInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.photomath.detection.deviceid.fingerprints.GetDeviceIdFingerprint
|
||||
import app.revanced.patches.photomath.detection.signature.patch.SignatureDetectionPatch
|
||||
import kotlin.random.Random
|
||||
|
||||
@Patch
|
||||
@DependsOn([SignatureDetectionPatch::class])
|
||||
@Name("Spoof device ID")
|
||||
@Description("Spoofs device ID to mitigate manual bans by developers.")
|
||||
@Compatibility([Package("com.microblink.photomath")])
|
||||
class SpoofDeviceIdPatch : BytecodePatch(
|
||||
listOf(GetDeviceIdFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) = GetDeviceIdFingerprint.result?.mutableMethod?.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "${Random.nextLong().toString(16)}"
|
||||
return-object v0
|
||||
"""
|
||||
) ?: throw GetDeviceIdFingerprint.exception
|
||||
}
|
||||
@@ -1,19 +1,11 @@
|
||||
package app.revanced.patches.photomath.detection.signature.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
object CheckSignatureFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
customFingerprint = { methodDef, _ ->
|
||||
(methodDef.definingClass == "Lcom/microblink/photomath/main/activity/LauncherActivity;" ||
|
||||
methodDef.definingClass == "Lcom/microblink/photomath/PhotoMath;") &&
|
||||
methodDef.name == "onCreate"
|
||||
},
|
||||
strings = listOf(
|
||||
"packageInfo.signatures",
|
||||
"currentSignature"
|
||||
),
|
||||
opcodes = listOf(
|
||||
|
||||
@@ -23,5 +23,4 @@ class SignatureDetectionPatch : BytecodePatch(
|
||||
mutableMethod.replaceInstruction(signatureCheckInstruction.location.index, "const/4 v$checkRegister, 0x1")
|
||||
} ?: throw CheckSignatureFingerprint.exception
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.photomath.misc.bookpoint.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
object IsBookpointEnabledFingerprint : MethodFingerprint(
|
||||
returnType = "Z",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf(),
|
||||
strings = listOf(
|
||||
"NoGeoData",
|
||||
"NoCountryInGeo",
|
||||
"RemoteConfig",
|
||||
"GeoRCMismatch"
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
package app.revanced.patches.photomath.misc.bookpoint.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patches.photomath.misc.bookpoint.fingerprints.IsBookpointEnabledFingerprint
|
||||
|
||||
@Description("Enables textbook access")
|
||||
class EnableBookpointPatch : BytecodePatch(listOf(IsBookpointEnabledFingerprint)) {
|
||||
override fun execute(context: BytecodeContext) =
|
||||
IsBookpointEnabledFingerprint.result?.mutableMethod?.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
) ?: throw IsBookpointEnabledFingerprint.exception
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package app.revanced.patches.photomath.misc.unlockplus.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.microblink.photomath", arrayOf("8.20.0"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class UnlockPlusCompatibilty
|
||||
@@ -1,37 +1,30 @@
|
||||
package app.revanced.patches.photomath.misc.unlockplus.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Package
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.photomath.detection.signature.patch.SignatureDetectionPatch
|
||||
import app.revanced.patches.photomath.misc.unlockplus.annotations.UnlockPlusCompatibilty
|
||||
import app.revanced.patches.photomath.misc.bookpoint.patch.EnableBookpointPatch
|
||||
import app.revanced.patches.photomath.misc.unlockplus.fingerprints.IsPlusUnlockedFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("Unlock plus")
|
||||
@DependsOn([SignatureDetectionPatch::class])
|
||||
@Description("Unlocks plus features.")
|
||||
@UnlockPlusCompatibilty
|
||||
@DependsOn([SignatureDetectionPatch::class, EnableBookpointPatch::class])
|
||||
@Compatibility([Package("com.microblink.photomath")])
|
||||
class UnlockPlusPatch : BytecodePatch(
|
||||
listOf(
|
||||
IsPlusUnlockedFingerprint
|
||||
)
|
||||
listOf(IsPlusUnlockedFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
IsPlusUnlockedFingerprint.result?.mutableMethod?.apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
} ?: throw IsPlusUnlockedFingerprint.exception
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext) = IsPlusUnlockedFingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
) ?: throw IsPlusUnlockedFingerprint.exception
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
|
||||
abstract class AbstractClientIdFingerprint(classTypeSuffix: String, methodName: String) : MethodFingerprint(
|
||||
strings = listOf("NOe2iKrPPzwscA"),
|
||||
customFingerprint = custom@{ methodDef, classDef ->
|
||||
if (!classDef.type.endsWith(classTypeSuffix)) return@custom false
|
||||
|
||||
methodDef.name == methodName
|
||||
}
|
||||
)
|
||||
/**
|
||||
* Fingerprint for a method that has the client id hardcoded in it.
|
||||
* The first string in the fingerprint is the client id.
|
||||
*
|
||||
* @param customFingerprint A custom fingerprint.
|
||||
* @param additionalStrings Additional strings to add to the fingerprint.
|
||||
*/
|
||||
abstract class AbstractClientIdFingerprint(
|
||||
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
||||
vararg additionalStrings: String
|
||||
) : MethodFingerprint(strings = listOf("NOe2iKrPPzwscA", *additionalStrings), customFingerprint = customFingerprint)
|
||||
@@ -1,6 +1,3 @@
|
||||
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
|
||||
|
||||
object GetHttpBasicAuthHeaderFingerprint : AbstractClientIdFingerprint(
|
||||
"APIUtils;",
|
||||
"getHttpBasicAuthHeader"
|
||||
)
|
||||
object GetHttpBasicAuthHeaderFingerprint : AbstractClientIdFingerprint(additionalStrings = arrayOf("Authorization"))
|
||||
@@ -1,6 +1,5 @@
|
||||
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
|
||||
|
||||
object LoginActivityOnCreateFingerprint : AbstractClientIdFingerprint(
|
||||
"LoginActivity;",
|
||||
"onCreate"
|
||||
)
|
||||
object LoginActivityOnCreateFingerprint : AbstractClientIdFingerprint(custom@{ methodDef, classDef ->
|
||||
methodDef.name == "onCreate" && classDef.type.endsWith("LoginActivity;")
|
||||
})
|
||||
@@ -17,7 +17,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@Description("Spoofs the client in order to allow logging in. " +
|
||||
"The OAuth application type has to be \"Installed app\" " +
|
||||
"and the redirect URI has to be set to \"infinity://localhost\".")
|
||||
@Compatibility([Package("ml.docilealligator.infinityforreddit")])
|
||||
@Compatibility([Package("ml.docilealligator.infinityforreddit", arrayOf("5.4.0", "5.4.1", "5.4.2", "6.0.1", "6.0.2", "6.0.4", "6.0.6", "6.1.1"))])
|
||||
class SpoofClientPatch : AbstractSpoofClientPatch(
|
||||
"infinity://localhost",
|
||||
Options,
|
||||
@@ -25,6 +25,7 @@ class SpoofClientPatch : AbstractSpoofClientPatch(
|
||||
) {
|
||||
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
|
||||
forEach {
|
||||
// First is index of the clientId string.
|
||||
val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index
|
||||
it.mutableMethod.apply {
|
||||
val oAuthClientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||
@@ -38,4 +39,4 @@ class SpoofClientPatch : AbstractSpoofClientPatch(
|
||||
}
|
||||
|
||||
companion object Options : AbstractSpoofClientPatch.Options.SpoofClientOptionsContainer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.tudortmund.lockscreen.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
object BrightnessFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC.value,
|
||||
parameters = listOf(),
|
||||
customFingerprint = { method, classDef ->
|
||||
method.name == "run"
|
||||
&& method.definingClass.contains("/ScreenPlugin\$")
|
||||
&& classDef.fields.any { it.type == "Ljava/lang/Float;" }
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,93 @@
|
||||
package app.revanced.patches.tudortmund.lockscreen.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
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.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.patch.annotations.RequiresIntegrations
|
||||
import app.revanced.patches.tudortmund.lockscreen.fingerprints.BrightnessFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch
|
||||
@Name("Show on lockscreen")
|
||||
@Description("Shows student id and student ticket on lockscreen.")
|
||||
@Compatibility([Package("de.tudortmund.app")])
|
||||
@RequiresIntegrations
|
||||
class ShowOnLockscreenPatch : BytecodePatch(
|
||||
listOf(BrightnessFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
BrightnessFingerprint.result?.mutableMethod?.apply {
|
||||
// Find the instruction where the brightness value is loaded into a register
|
||||
val brightnessInstruction = implementation!!.instructions.firstNotNullOf { instruction ->
|
||||
if (instruction.opcode != Opcode.IGET_OBJECT) return@firstNotNullOf null
|
||||
|
||||
val getInstruction = instruction as Instruction22c
|
||||
val fieldReference = getInstruction.reference as FieldReference
|
||||
|
||||
if (fieldReference.type != "Ljava/lang/Float;") return@firstNotNullOf null
|
||||
|
||||
instruction
|
||||
}
|
||||
|
||||
// Search for the instruction where we get the android.view.Window via the Activity.
|
||||
// Gets the index of that instruction and the register of the Activity.
|
||||
val (windowIndex, activityRegister) = implementation!!.instructions.withIndex()
|
||||
.firstNotNullOf { (index, instruction) ->
|
||||
if (instruction.opcode != Opcode.INVOKE_VIRTUAL)
|
||||
return@firstNotNullOf null
|
||||
|
||||
val invokeInstruction = instruction as Instruction35c
|
||||
val methodRef = invokeInstruction.reference as MethodReference
|
||||
|
||||
if (methodRef.name != "getWindow" || methodRef.returnType != "Landroid/view/Window;")
|
||||
return@firstNotNullOf null
|
||||
|
||||
Pair(index, invokeInstruction.registerC)
|
||||
}
|
||||
|
||||
// The register in which the brightness value is loaded
|
||||
val brightnessRegister = brightnessInstruction.registerA
|
||||
|
||||
// Replaces the getWindow call with our custom one to run the lockscreen code
|
||||
replaceInstruction(
|
||||
windowIndex,
|
||||
"invoke-static { v$activityRegister, v$brightnessRegister }, " +
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->" +
|
||||
"getWindow" +
|
||||
"(Landroidx/appcompat/app/AppCompatActivity;F)" +
|
||||
"Landroid/view/Window;"
|
||||
)
|
||||
|
||||
// Normally, the brightness is loaded into a register after the getWindow call.
|
||||
// In order to pass the brightness value to our custom getWindow implementation,
|
||||
// we need to add the same instructions before the getWindow call.
|
||||
// The Float object is loaded into the brightness register and gets converted to a float.
|
||||
addInstructions(
|
||||
windowIndex,
|
||||
"""
|
||||
invoke-virtual { v$brightnessRegister }, Ljava/lang/Float;->floatValue()F
|
||||
move-result v$brightnessRegister
|
||||
"""
|
||||
)
|
||||
|
||||
addInstruction(windowIndex, brightnessInstruction)
|
||||
|
||||
} ?: throw BrightnessFingerprint.exception
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/tudortmund/lockscreen/ShowOnLockscreenPatch;"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package app.revanced.patches.tumblr.ads.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
// The Tumblr app sends a request to /v2/timeline/dashboard which replies with an array of elements
|
||||
// to show in the user dashboard. These element have different type ids (post, title, carousel, etc.)
|
||||
// The standard dashboard Ad has the id client_side_ad_waterfall, and this string has to be in the code
|
||||
// to handle ads and provide their appearance.
|
||||
// If we just replace this string in the tumblr code with anything else, it will fail to recognize the
|
||||
// dashboard object type and just skip it. This is a bit weird, but it shouldn't break
|
||||
// unless they change the api (unlikely) or explicitly Change the tumblr code to prevent this.
|
||||
object AdWaterfallFingerprint : MethodFingerprint(strings = listOf("client_side_ad_waterfall"))
|
||||
@@ -0,0 +1,34 @@
|
||||
package app.revanced.patches.tumblr.ads.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
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.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.tumblr.ads.fingerprints.AdWaterfallFingerprint
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@Name("Disable dashboard ads")
|
||||
@Description("Disables ads in the dashboard.")
|
||||
@Compatibility([Package("com.tumblr")])
|
||||
class DisableDashboardAds : BytecodePatch(
|
||||
listOf(AdWaterfallFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) = AdWaterfallFingerprint.result?.let {
|
||||
it.scanResult.stringsScanResult!!.matches.forEach { match ->
|
||||
// We just replace all occurrences of "client_side_ad_waterfall" with anything else
|
||||
// so the app fails to handle ads in the timeline elements array and just skips them.
|
||||
// See AdWaterfallFingerprint for more info.
|
||||
val stringRegister = it.mutableMethod.getInstruction<OneRegisterInstruction>(match.index).registerA
|
||||
it.mutableMethod.replaceInstruction(
|
||||
match.index, "const-string v$stringRegister, \"dummy\""
|
||||
)
|
||||
}
|
||||
} ?: throw AdWaterfallFingerprint.exception
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.tumblr.annoyances.notifications.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
// The BlogNotifyCtaDialog asks you if you want to enable notifications for a blog.
|
||||
// It shows whenever you visit a certain blog for the second time and disables itself
|
||||
// if it was shown a total of 3 times (stored in app storage).
|
||||
// This targets the BlogNotifyCtaDialog.isEnabled() method to let it always return false.
|
||||
object IsBlogNotifyEnabledFingerprint : MethodFingerprint(strings = listOf("isEnabled --> ", "blog_notify_enabled"))
|
||||
@@ -0,0 +1,30 @@
|
||||
package app.revanced.patches.tumblr.annoyances.notifications.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
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.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.tumblr.annoyances.notifications.fingerprints.IsBlogNotifyEnabledFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("Disable blog notification reminder")
|
||||
@Description("Disables the reminder to enable notifications for blogs you visit.")
|
||||
@Compatibility([Package("com.tumblr")])
|
||||
class DisableBlogNotificationReminderPatch : BytecodePatch(
|
||||
listOf(IsBlogNotifyEnabledFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) =
|
||||
IsBlogNotifyEnabledFingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
# Return false for BlogNotifyCtaDialog.isEnabled() method.
|
||||
const/4 v0, 0x0
|
||||
return v0
|
||||
"""
|
||||
) ?: throw IsBlogNotifyEnabledFingerprint.exception
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.tumblr.annoyances.popups.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
// This method is responsible for loading and displaying the visual Layout of the Gift Message Popup.
|
||||
object ShowGiftMessagePopupFingerprint : MethodFingerprint(
|
||||
strings = listOf("activity", "anchorView"),
|
||||
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("GiftMessagePopup;") }
|
||||
)
|
||||
@@ -0,0 +1,24 @@
|
||||
package app.revanced.patches.tumblr.annoyances.popups.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
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.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.tumblr.annoyances.popups.fingerprints.ShowGiftMessagePopupFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("Disable gift message popup")
|
||||
@Description("Disables the popup suggesting to buy TumblrMart items for other people.")
|
||||
@Compatibility([Package("com.tumblr")])
|
||||
class DisableGiftMessagePopupPatch : BytecodePatch(
|
||||
listOf(ShowGiftMessagePopupFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) =
|
||||
ShowGiftMessagePopupFingerprint.result?.mutableMethod?.addInstructions(0, "return-void")
|
||||
?: throw ShowGiftMessagePopupFingerprint.exception
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.twitch.ad.audio.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1"))])
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1", "16.1.0"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AudioAdsCompatibility
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.twitch.ad.embedded.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1"))])
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1", "16.1.0"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class EmbeddedAdsCompatibility
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ package app.revanced.patches.twitch.ad.embedded.patch
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
@@ -21,7 +21,7 @@ import app.revanced.patches.twitch.misc.settings.bytecode.patch.SettingsPatch
|
||||
@Patch
|
||||
@DependsOn([VideoAdsPatch::class, IntegrationsPatch::class, SettingsPatch::class])
|
||||
@Name("Block embedded ads")
|
||||
@Description("Blocks embedded stream ads using services like TTV.lol or PurpleAdBlocker.")
|
||||
@Description("Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.")
|
||||
@EmbeddedAdsCompatibility
|
||||
class EmbeddedAdsPatch : BytecodePatch(
|
||||
listOf(CreateUsherClientFingerprint)
|
||||
@@ -50,7 +50,7 @@ class EmbeddedAdsPatch : BytecodePatch(
|
||||
"revanced_hls_proxies",
|
||||
listOf(
|
||||
StringResource("revanced_proxy_disabled", "Disabled"),
|
||||
StringResource("revanced_proxy_ttv_lol", "TTV LOL proxy"),
|
||||
StringResource("revanced_proxy_luminous", "Luminous proxy"),
|
||||
StringResource("revanced_proxy_purpleadblock", "PurpleAdBlock proxy"),
|
||||
)
|
||||
),
|
||||
@@ -58,11 +58,11 @@ class EmbeddedAdsPatch : BytecodePatch(
|
||||
"revanced_hls_proxies_values",
|
||||
listOf(
|
||||
StringResource("key_revanced_proxy_disabled", "disabled"),
|
||||
StringResource("key_revanced_proxy_ttv_lol", "ttv-lol"),
|
||||
StringResource("key_revanced_proxy_luminous", "luminous"),
|
||||
StringResource("key_revanced_proxy_purpleadblock", "purpleadblock")
|
||||
)
|
||||
),
|
||||
default = "ttv-lol"
|
||||
default = "luminous"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.twitch.ad.video.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1"))])
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1", "16.1.0"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class VideoAdsCompatibility
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.twitch.chat.antidelete.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1"))])
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1", "16.1.0"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class ShowDeletedMessagesCompatibility
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.twitch.chat.autoclaim.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1"))])
|
||||
@Compatibility([Package("tv.twitch.android.app", arrayOf("15.4.1", "16.1.0"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AutoClaimChannelPointsCompatibility
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.ad.general.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideAdsCompatibility
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.ad.getpremium.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideGetPremiumCompatibility
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.ad.video.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class VideoAdsCompatibility
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.interaction.copyvideourl.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class CopyVideoUrlCompatibility
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.interaction.downloads.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class ExternalDownloadsCompatibility
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.interaction.seekbar.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class SeekbarTappingCompatibility
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.interaction.swipecontrols.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class SwipeControlsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.autocaptions.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AutoCaptionsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.action.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideButtonsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.autoplay.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AutoplayButtonCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.captions.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideCaptionsButtonCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.navigation.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class NavigationButtonsCompatibility
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.buttons.player.hide.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HidePlayerButtonsCompatibility
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.albumcards.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AlbumCardsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.breakingnews.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class BreakingNewsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.comments.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideCommentsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class CrowdfundingBoxCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.endscreencards.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideEndscreenCardsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.filterbar.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideFilterBar
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.floatingmicrophone.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideFloatingMicrophoneButtonCompatibility
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.hide.general.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideLayoutComponentsCompatibility
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package app.revanced.patches.youtube.layout.hide.general.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
object ConvertElementToFlatBufferFingerprint : MethodFingerprint(
|
||||
strings = listOf("Failed to convert Element to Flatbuffers: %s"),
|
||||
opcodes = listOf(Opcode.IGET_OBJECT) // Patched at this opcodes index
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.youtube.layout.hide.general.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
object ParseElementFromBufferFingerprint : MethodFingerprint(
|
||||
parameters = listOf("L","L","[B", "L","L"),
|
||||
opcodes = listOf(Opcode.INVOKE_INTERFACE, Opcode.MOVE_RESULT_OBJECT),
|
||||
strings = listOf("Failed to parse Element")
|
||||
)
|
||||
@@ -4,21 +4,24 @@ import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.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.youtube.layout.hide.general.annotations.HideLayoutComponentsCompatibility
|
||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ConvertElementToFlatBufferFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
|
||||
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@Name("Hide layout components")
|
||||
@@ -26,7 +29,7 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.P
|
||||
@DependsOn([LithoFilterPatch::class, SettingsPatch::class])
|
||||
@HideLayoutComponentsCompatibility
|
||||
class HideLayoutComponentsPatch : BytecodePatch(
|
||||
listOf(ConvertElementToFlatBufferFingerprint)
|
||||
listOf(ParseElementFromBufferFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
PreferenceScreen.LAYOUT.addPreferences(
|
||||
@@ -52,7 +55,7 @@ class HideLayoutComponentsPatch : BytecodePatch(
|
||||
"revanced_hide_expandable_chip",
|
||||
StringResource(
|
||||
"revanced_hide_expandable_chip_title",
|
||||
"Hide the expandable chip under videos"
|
||||
"Hide expandable chip under videos"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_hide_expandable_chip_summary_on",
|
||||
@@ -183,12 +186,6 @@ class HideLayoutComponentsPatch : BytecodePatch(
|
||||
StringResource("revanced_hide_image_shelf_summary_on", "Image shelf is hidden"),
|
||||
StringResource("revanced_hide_image_shelf_summary_off", "Image shelf is shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_hide_audio_track_button",
|
||||
StringResource("revanced_hide_audio_track_button_title", "Hide audio track button"),
|
||||
StringResource("revanced_hide_audio_track_button_on", "Audio track button is hidden"),
|
||||
StringResource("revanced_hide_audio_track_button_off", "Audio track button is shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_hide_latest_posts_ads",
|
||||
StringResource("revanced_hide_latest_posts_ads_title", "Hide latest posts"),
|
||||
@@ -238,8 +235,9 @@ class HideLayoutComponentsPatch : BytecodePatch(
|
||||
StringResource("revanced_custom_filter_strings_title", "Custom filter"),
|
||||
StringResource(
|
||||
"revanced_custom_filter_strings_summary",
|
||||
"Filter components by their name separated by a comma"
|
||||
)
|
||||
"List of components to filter separated by new line"
|
||||
),
|
||||
inputType = InputType.TEXT_MULTI_LINE
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -249,30 +247,26 @@ class HideLayoutComponentsPatch : BytecodePatch(
|
||||
|
||||
// region Mix playlists
|
||||
|
||||
ConvertElementToFlatBufferFingerprint.result?.let {
|
||||
val returnEmptyComponentIndex = it.scanResult.stringsScanResult!!.matches.first().index + 2
|
||||
ParseElementFromBufferFingerprint.result?.let { result ->
|
||||
val returnEmptyComponentInstruction = result.mutableMethod.getInstructions()
|
||||
.last { it.opcode == Opcode.INVOKE_STATIC }
|
||||
|
||||
it.mutableMethod.apply {
|
||||
// The last virtual register (not parameter). Used to store the byte array
|
||||
// that may contain information about a mix playlist.
|
||||
val freeRegister = (implementation!!.registerCount - 1) - parameterTypes.size - 1
|
||||
result.mutableMethod.apply {
|
||||
val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
|
||||
val byteBufferRegister = getInstruction<FiveRegisterInstruction>(consumeByteBufferIndex).registerD
|
||||
|
||||
// Check if the byte array contains anything about a mix playlist.
|
||||
addInstructionsWithLabels(
|
||||
it.scanResult.patternScanResult!!.startIndex,
|
||||
result.scanResult.patternScanResult!!.startIndex,
|
||||
"""
|
||||
invoke-static {v$freeRegister}, $FILTER_CLASS_DESCRIPTOR->filterMixPlaylists([B)Z
|
||||
move-result v$freeRegister
|
||||
if-nez v$freeRegister, :return_empty_component
|
||||
invoke-static {v$byteBufferRegister}, $FILTER_CLASS_DESCRIPTOR->filterMixPlaylists([B)Z
|
||||
move-result v0 # Conveniently same register happens to be free.
|
||||
if-nez v0, :return_empty_component
|
||||
""",
|
||||
ExternalLabel("return_empty_component", getInstruction(returnEmptyComponentIndex))
|
||||
ExternalLabel("return_empty_component", returnEmptyComponentInstruction)
|
||||
)
|
||||
|
||||
// Move the byte array to a free register.
|
||||
addInstruction(0, "move-object/from16 v$freeRegister, p3")
|
||||
}
|
||||
|
||||
} ?: throw ConvertElementToFlatBufferFingerprint.exception
|
||||
} ?: throw ParseElementFromBufferFingerprint.exception
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.infocards.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideInfocardsCompatibility
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.hide.loadmorebutton.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideLoadMoreButtonCompatibility
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.personalinformation.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideEmailAddressCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.player.flyoutmenupanel.annotati
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HidePlayerFlyoutMenuItemsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.seekbar.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideSeekbarCompatibility
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.shorts.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideShortsComponentsCompatibility
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = listOf("Z", "Z", "L"),
|
||||
literal = HideShortsComponentsResourcePatch.reelPlayerRightLargeIconSize
|
||||
literal = HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight
|
||||
)
|
||||
@@ -91,11 +91,11 @@ class HideShortsComponentsResourcePatch : ResourcePatch {
|
||||
fun String.getId() = ResourceMappingPatch.resourceMappings.single { it.name == this }.id
|
||||
|
||||
reelMultipleItemShelfId = "reel_multiple_items_shelf".getId()
|
||||
reelPlayerRightLargeIconSize = "reel_player_right_large_icon_size".getId()
|
||||
reelPlayerRightCellButtonHeight = "reel_player_right_cell_button_height".getId()
|
||||
}
|
||||
|
||||
companion object {
|
||||
var reelMultipleItemShelfId: Long = -1
|
||||
var reelPlayerRightLargeIconSize = -1L
|
||||
var reelMultipleItemShelfId = -1L
|
||||
var reelPlayerRightCellButtonHeight = -1L
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.time.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideTimeCompatibility
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.hide.watermark.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HideWatermarkCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.panels.popup.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class PlayerPopupPanelsCompatibility
|
||||
|
||||
@@ -2,6 +2,6 @@ package app.revanced.patches.youtube.layout.player.background.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class PlayerControlsBackgroundCompatibility
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package app.revanced.patches.youtube.layout.hide.player.overlay.annotations
|
||||
package app.revanced.patches.youtube.layout.player.overlay.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class HidePlayerOverlayPatchCompatibility
|
||||
internal annotation class PlayerOverlayPatchCompatibility
|
||||
@@ -1,9 +1,9 @@
|
||||
package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints
|
||||
package app.revanced.patches.youtube.layout.player.overlay.bytecode.fingerprints
|
||||
|
||||
import app.revanced.extensions.containsConstantInstructionValue
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch
|
||||
import app.revanced.patches.youtube.layout.player.overlay.resource.patch.CustomPlayerOverlayOpacityResourcePatch
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@@ -17,6 +17,6 @@ object CreatePlayerOverviewFingerprint : MethodFingerprint(
|
||||
Opcode.CHECK_CAST
|
||||
),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId)
|
||||
methodDef.containsConstantInstructionValue(CustomPlayerOverlayOpacityResourcePatch.scrimOverlayId)
|
||||
}
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.patch
|
||||
package app.revanced.patches.youtube.layout.player.overlay.bytecode.patch
|
||||
|
||||
import app.revanced.extensions.indexOfFirstConstantInstructionValue
|
||||
import app.revanced.extensions.exception
|
||||
@@ -10,35 +10,36 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HidePlayerOverlayPatchCompatibility
|
||||
import app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints.CreatePlayerOverviewFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch
|
||||
import app.revanced.patches.youtube.layout.player.overlay.annotations.PlayerOverlayPatchCompatibility
|
||||
import app.revanced.patches.youtube.layout.player.overlay.bytecode.fingerprints.CreatePlayerOverviewFingerprint
|
||||
import app.revanced.patches.youtube.layout.player.overlay.resource.patch.CustomPlayerOverlayOpacityResourcePatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@Name("Hide player overlay")
|
||||
@Description("Hides the dark background overlay from the player when player controls are visible.")
|
||||
@DependsOn([HidePlayerOverlayResourcePatch::class])
|
||||
@HidePlayerOverlayPatchCompatibility
|
||||
class HidePlayerOverlayPatch : BytecodePatch(listOf(CreatePlayerOverviewFingerprint)) {
|
||||
@Name("Custom player overlay opacity")
|
||||
@Description("Change the opacity of the player background, when player controls are visible.")
|
||||
@DependsOn([CustomPlayerOverlayOpacityResourcePatch::class])
|
||||
@PlayerOverlayPatchCompatibility
|
||||
class CustomPlayerOverlayOpacityPatch : BytecodePatch(listOf(CreatePlayerOverviewFingerprint)) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
CreatePlayerOverviewFingerprint.result?.let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val viewRegisterIndex =
|
||||
indexOfFirstConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId) + 3
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(viewRegisterIndex).registerA
|
||||
indexOfFirstConstantInstructionValue(CustomPlayerOverlayOpacityResourcePatch.scrimOverlayId) + 3
|
||||
val viewRegister =
|
||||
getInstruction<OneRegisterInstruction>(viewRegisterIndex).registerA
|
||||
|
||||
val insertIndex = viewRegisterIndex + 1
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static { v$viewRegister }, " +
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->hidePlayerOverlay(Landroid/widget/ImageView;)V"
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->changeOpacity(Landroid/widget/ImageView;)V"
|
||||
)
|
||||
}
|
||||
} ?: throw CreatePlayerOverviewFingerprint.exception
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/HidePlayerOverlayPatch;"
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/CustomPlayerOverlayOpacityPatch;"
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,29 @@
|
||||
package app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch
|
||||
package app.revanced.patches.youtube.layout.player.overlay.resource.patch
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
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.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.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
|
||||
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
|
||||
class HidePlayerOverlayResourcePatch : ResourcePatch {
|
||||
class CustomPlayerOverlayOpacityResourcePatch : ResourcePatch {
|
||||
override fun execute(context: ResourceContext) {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_hide_player_overlay",
|
||||
StringResource("revanced_hide_player_overlay_title", "Hide background overlay in player"),
|
||||
StringResource("revanced_hide_player_overlay_summary_on", "Background overlay is hidden"),
|
||||
StringResource("revanced_hide_player_overlay_summary_off", "Background overlay is shown")
|
||||
TextPreference(
|
||||
"revanced_player_overlay_opacity",
|
||||
StringResource(
|
||||
"revanced_player_overlay_opacity_title",
|
||||
"Player overlay opacity"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_player_overlay_opacity_summary",
|
||||
"Opacity value between 0-100, where 0 is transparent"
|
||||
),
|
||||
InputType.NUMBER
|
||||
)
|
||||
)
|
||||
|
||||
@@ -26,6 +33,6 @@ class HidePlayerOverlayResourcePatch : ResourcePatch {
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
var scrimOverlayId: Long = -1
|
||||
var scrimOverlayId = -1L
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class ReturnYouTubeDislikeCompatibility
|
||||
@@ -13,19 +13,17 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE_OBJECT_FROM16, // available unused register
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
null, // move-object/from16 or move/from16
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.MOVE_OBJECT, // Register A and B is context, use B as context, reuse A as free register
|
||||
Opcode.INVOKE_VIRTUAL, // Register C is atomic reference
|
||||
Opcode.MOVE_RESULT_OBJECT, // Register A is char sequence
|
||||
Opcode.MOVE_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.MOVE_OBJECT, // CharSequence reference, and control flow label. Insert code here.
|
||||
null, // invoke-interface or invoke-virtual
|
||||
Opcode.MOVE_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE, // Insert hook here
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
null, // invoke-interface or invoke-virtual
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.GOTO,
|
||||
Opcode.GOTO
|
||||
)
|
||||
)
|
||||
@@ -83,10 +83,8 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
// since the underlying (likes only) text did not change.
|
||||
// This hook handles all situations, as it's where the created Spans are stored and later reused.
|
||||
TextComponentContextFingerprint.also {
|
||||
it.resolve(
|
||||
context,
|
||||
TextComponentConstructorFingerprint.result!!.classDef
|
||||
)
|
||||
if (!it.resolve(context, TextComponentConstructorFingerprint.result!!.classDef))
|
||||
throw it.exception
|
||||
}.result?.also { result ->
|
||||
if (!TextComponentAtomicReferenceFingerprint.resolve(context, result.method, result.classDef))
|
||||
throw TextComponentAtomicReferenceFingerprint.exception
|
||||
@@ -96,33 +94,46 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
val atomicReferenceStartIndex = TextComponentAtomicReferenceFingerprint.result!!
|
||||
.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
val insertIndex = atomicReferenceStartIndex + 7
|
||||
val insertIndex = atomicReferenceStartIndex + 6
|
||||
|
||||
textComponentContextFingerprintResult.mutableMethod.apply {
|
||||
// Get the conversion context obfuscated field name, and the registers for the AtomicReference and CharSequence
|
||||
val conversionContextFieldReference =
|
||||
getInstruction<ReferenceInstruction>(conversionContextIndex).reference
|
||||
|
||||
// any free register
|
||||
val contextRegister =
|
||||
// Reuse the free register to make room for the atomic reference register.
|
||||
val freeRegister =
|
||||
getInstruction<TwoRegisterInstruction>(atomicReferenceStartIndex).registerB
|
||||
|
||||
val atomicReferenceRegister =
|
||||
getInstruction<FiveRegisterInstruction>(atomicReferenceStartIndex + 4).registerC
|
||||
getInstruction<FiveRegisterInstruction>(atomicReferenceStartIndex + 1).registerC
|
||||
|
||||
val moveCharSequenceInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
|
||||
val charSequenceRegister = moveCharSequenceInstruction.registerB
|
||||
val moveCharSequenceInstruction = getInstruction<TwoRegisterInstruction>(insertIndex - 1)
|
||||
val charSequenceSourceRegister = moveCharSequenceInstruction.registerB
|
||||
val charSequenceTargetRegister = moveCharSequenceInstruction.registerA
|
||||
|
||||
// Insert as first instructions at the control flow label.
|
||||
// Must replace the existing instruction to preserve the label, and then insert the remaining instructions.
|
||||
replaceInstruction(insertIndex, "move-object/from16 v$contextRegister, p0")
|
||||
// In order to preserve the atomic reference register, because it is overwritten,
|
||||
// use another free register to store it.
|
||||
replaceInstruction(
|
||||
atomicReferenceStartIndex + 2,
|
||||
"move-result-object v$freeRegister"
|
||||
)
|
||||
replaceInstruction(
|
||||
atomicReferenceStartIndex + 3,
|
||||
"move-object v$charSequenceSourceRegister, v$freeRegister"
|
||||
)
|
||||
|
||||
// Move the current instance to the free register, and get the conversion context from it.
|
||||
replaceInstruction(insertIndex - 1, "move-object/from16 v$freeRegister, p0")
|
||||
addInstructions(
|
||||
insertIndex + 1,
|
||||
insertIndex,
|
||||
"""
|
||||
iget-object v$contextRegister, v$contextRegister, $conversionContextFieldReference # copy obfuscated context field into free register
|
||||
invoke-static {v$contextRegister, v$atomicReferenceRegister, v$charSequenceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$charSequenceRegister
|
||||
move-object v${moveCharSequenceInstruction.registerA}, v${charSequenceRegister} # original instruction at the insertion point
|
||||
# Move context to free register
|
||||
iget-object v$freeRegister, v$freeRegister, $conversionContextFieldReference
|
||||
invoke-static {v$freeRegister, v$atomicReferenceRegister, v$charSequenceSourceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$freeRegister
|
||||
# Replace the original char sequence with the modified one.
|
||||
move-object v${charSequenceTargetRegister}, v${freeRegister}
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.searchbar.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class WideSearchbarCompatibility
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.sponsorblock.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class SponsorBlockCompatibility
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.layout.spoofappversion.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class SpoofAppVersionCompatibility
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.startupshortsreset.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class StartupShortsResetCompatibility
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package app.revanced.patches.youtube.layout.tablet.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class EnableTabletLayoutCompatibility
|
||||
@@ -0,0 +1,25 @@
|
||||
package app.revanced.patches.youtube.layout.tablet.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
object GetFormFactorFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
returnType = "L",
|
||||
parameters = listOf("Landroid/content/Context;", "Ljava/util/List;"),
|
||||
opcodes = listOf(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,56 @@
|
||||
package app.revanced.patches.youtube.layout.tablet.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||
import app.revanced.patches.youtube.layout.tablet.annotations.EnableTabletLayoutCompatibility
|
||||
import app.revanced.patches.youtube.layout.tablet.fingerprints.GetFormFactorFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
|
||||
@Patch
|
||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||
@Name("Enable tablet layout")
|
||||
@Description("Spoofs the device form factor to a tablet which enables the tablet layout.")
|
||||
@EnableTabletLayoutCompatibility
|
||||
class EnableTabletLayoutPatch : BytecodePatch(listOf(GetFormFactorFingerprint)) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_tablet_layout",
|
||||
StringResource("revanced_tablet_layout_enabled_title", "Enable tablet layout"),
|
||||
StringResource("revanced_tablet_layout_summary_on", "Tablet layout is enabled"),
|
||||
StringResource("revanced_tablet_layout_summary_off", "Tablet layout is disabled"),
|
||||
StringResource("revanced_tablet_layout_user_dialog_message", "Community posts do not show up on tablet layouts")
|
||||
)
|
||||
)
|
||||
|
||||
GetFormFactorFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val returnLargeFormFactorIndex = it.scanResult.patternScanResult!!.endIndex - 4
|
||||
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/patches/EnableTabletLayoutPatch;->enableTabletLayout()Z
|
||||
move-result v0
|
||||
if-nez v0, :is_large_form_factor
|
||||
""",
|
||||
ExternalLabel(
|
||||
"is_large_form_factor",
|
||||
getInstruction(returnLargeFormFactorIndex)
|
||||
)
|
||||
)
|
||||
}
|
||||
} ?: GetFormFactorFingerprint.exception
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class TabletMiniPlayerCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.layout.thumbnails.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AlternativeThumbnailsCompatibility
|
||||
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.autorepeat.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class AutoRepeatCompatibility
|
||||
@@ -1,13 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.bottomsheet.hook.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.misc.bottomsheet.hook.patch.BottomSheetHookResourcePatch
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
object CreateBottomSheetFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
returnType = "Landroid/widget/LinearLayout;",
|
||||
literal = BottomSheetHookResourcePatch.bottomSheetMargins
|
||||
)
|
||||
@@ -1,39 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.bottomsheet.hook.patch
|
||||
|
||||
import app.revanced.extensions.exception
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.youtube.misc.bottomsheet.hook.fingerprints.CreateBottomSheetFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@DependsOn([IntegrationsPatch::class, BottomSheetHookResourcePatch::class])
|
||||
class BottomSheetHookPatch : BytecodePatch(
|
||||
listOf(CreateBottomSheetFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
CreateBottomSheetFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val returnLinearLayoutIndex = implementation!!.instructions.lastIndex
|
||||
val linearLayoutRegister = getInstruction<OneRegisterInstruction>(returnLinearLayoutIndex).registerA
|
||||
|
||||
addHook = { classDescriptor ->
|
||||
addInstruction(
|
||||
returnLinearLayoutIndex,
|
||||
"invoke-static { v$linearLayoutRegister }, " +
|
||||
"${classDescriptor}->" +
|
||||
"onFlyoutMenuCreate(Landroid/widget/LinearLayout;)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: throw CreateBottomSheetFingerprint.exception
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
internal lateinit var addHook: (String) -> Unit
|
||||
private set
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.bottomsheet.hook.patch
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
|
||||
|
||||
@DependsOn([ResourceMappingPatch::class])
|
||||
class BottomSheetHookResourcePatch : ResourcePatch {
|
||||
override fun execute(context: ResourceContext) {
|
||||
bottomSheetMargins = ResourceMappingPatch.resourceMappings.find { it.name == "bottom_sheet_margins" }?.id
|
||||
?: throw PatchException("Could not find resource")
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
var bottomSheetMargins = -1L
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.fix.backtoexitgesture.annotation
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class FixBackToExitGestureCompatibility
|
||||
@@ -3,6 +3,6 @@ package app.revanced.patches.youtube.misc.fix.playback.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class ClientSpoofCompatibility
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.annotations
|
||||
package app.revanced.patches.youtube.misc.links.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38"))])
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35", "18.29.38", "18.32.39"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class OpenLinksExternallyCompatibility
|
||||
@@ -1,17 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.links.open.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
object BindSessionServiceFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
opcodes = listOf(
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("android.support.customtabs.action.CustomTabsService")
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user