mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-25 18:34:07 +01:00
Compare commits
34 Commits
v4.8.0-dev
...
v4.9.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f54118b39 | ||
|
|
6c25c95747 | ||
|
|
ad07efbd4a | ||
|
|
ea1deb630e | ||
|
|
9f116422d2 | ||
|
|
367a83accd | ||
|
|
54d671dd3e | ||
|
|
d925e7f2e8 | ||
|
|
de18cdcc12 | ||
|
|
19d1503594 | ||
|
|
62b1adfde1 | ||
|
|
78b9716a76 | ||
|
|
33ea424c37 | ||
|
|
7bd9cabf5a | ||
|
|
7946d503db | ||
|
|
b2f046a7f6 | ||
|
|
91ea79ca0e | ||
|
|
532293ce70 | ||
|
|
662598fb67 | ||
|
|
3276277c5a | ||
|
|
e9df0ec5d1 | ||
|
|
c20dbffc86 | ||
|
|
9c58b4b1f7 | ||
|
|
4eab75511f | ||
|
|
04e556f4f1 | ||
|
|
82a0847c6d | ||
|
|
0d1c455964 | ||
|
|
395c1280e2 | ||
|
|
740e011da7 | ||
|
|
f92dabd8ea | ||
|
|
240b05c01b | ||
|
|
a02c74f5c8 | ||
|
|
2fc4d7f1bb | ||
|
|
6ac3ba03aa |
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -70,7 +70,7 @@ body:
|
||||
|
||||
Before creating a new bug report, please keep the following in mind:
|
||||
|
||||
- **Do not submit a duplicate bug report**: You can review existing bug reports [here](https://github.com/ReVanced/revanced-patches/labels/Bug%20report).
|
||||
- **Do not submit a duplicate bug report**: Search for existing bug reports [here](https://github.com/ReVanced/revanced-patches/issues?q=label%3A%22Bug+report%22).
|
||||
- **Review the contribution guidelines**: Make sure your bug report adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-patches/blob/main/CONTRIBUTING.md).
|
||||
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
|
||||
- type: textarea
|
||||
@@ -102,7 +102,7 @@ body:
|
||||
label: Acknowledgements
|
||||
description: Your bug report will be closed if you don't follow the checklist below.
|
||||
options:
|
||||
- label: This issue is not a duplicate of an existing bug report.
|
||||
- label: I have checked all open and closed bug reports and this is not a duplicate.
|
||||
required: true
|
||||
- label: I have chosen an appropriate title.
|
||||
required: true
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
4
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -70,7 +70,7 @@ body:
|
||||
|
||||
Before creating a new feature request, please keep the following in mind:
|
||||
|
||||
- **Do not submit a duplicate feature request**: You can review existing feature requests [here](https://github.com/ReVanced/revanced-patches/labels/Feature%20request).
|
||||
- **Do not submit a duplicate feature request**: Search for existing feature requests [here](https://github.com/ReVanced/revanced-patches/issues?q=label%3A%22Feature+request%22).
|
||||
- **Review the contribution guidelines**: Make sure your feature request adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-patches/blob/main/CONTRIBUTING.md).
|
||||
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
|
||||
- type: textarea
|
||||
@@ -98,7 +98,7 @@ body:
|
||||
label: Acknowledgements
|
||||
description: Your feature request will be closed if you don't follow the checklist below.
|
||||
options:
|
||||
- label: This issue is not a duplicate of an existing feature request.
|
||||
- label: I have checked all open and closed feature requests and this is not a duplicate
|
||||
required: true
|
||||
- label: I have chosen an appropriate title.
|
||||
required: true
|
||||
|
||||
130
CHANGELOG.md
130
CHANGELOG.md
@@ -1,3 +1,133 @@
|
||||
# [4.9.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.9.0-dev.2...v4.9.0-dev.3) (2024-06-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube Music:** Support version `7.03` ([#3272](https://github.com/ReVanced/revanced-patches/issues/3272)) ([d1ceca3](https://github.com/ReVanced/revanced-patches/commit/d1ceca39984f7933b28d81802d04bb3ead327595))
|
||||
|
||||
# [4.9.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.9.0-dev.1...v4.9.0-dev.2) (2024-06-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof client:** Allow swipe gestures to enter/exit fullscreen when spoofing with `Android VR` client ([#3259](https://github.com/ReVanced/revanced-patches/issues/3259)) ([5114900](https://github.com/ReVanced/revanced-patches/commit/5114900b1b5572c04ba6759eedab77f0a934b058))
|
||||
|
||||
# [4.9.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.8.3...v4.9.0-dev.1) (2024-05-31)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Hide layout components:** Disable like / subscribe button glow animation ([#3265](https://github.com/ReVanced/revanced-patches/issues/3265)) ([68d35ea](https://github.com/ReVanced/revanced-patches/commit/68d35eafc15513c23cd5220260023e7ec5b7978a))
|
||||
|
||||
## [4.8.3](https://github.com/ReVanced/revanced-patches/compare/v4.8.2...v4.8.3) (2024-05-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **3rd-party Reddit apps:** Spoof user agent to work around Reddit API issues ([#3253](https://github.com/ReVanced/revanced-patches/issues/3253)) ([495e6d6](https://github.com/ReVanced/revanced-patches/commit/495e6d65e7cbae88baa71f8334b9afcf9819deaf))
|
||||
* **Reddit - Hide ads:** Constrain to last working version 2024.17.0 ([#3192](https://github.com/ReVanced/revanced-patches/issues/3192)) ([4fb3456](https://github.com/ReVanced/revanced-patches/commit/4fb3456e93ff7ec19030de8870e1cb9c1319faef))
|
||||
* **YouTube - Spoof client:** Clarify that only enter/exit fullscreen gesture does not work with Android VR spoof ([#3243](https://github.com/ReVanced/revanced-patches/issues/3243)) ([06d8f55](https://github.com/ReVanced/revanced-patches/commit/06d8f55e9b6ce27d8c550f202615689ac9c34cfa))
|
||||
* **YouTube - Spoof client:** Improve Android spoofing ([#3230](https://github.com/ReVanced/revanced-patches/issues/3230)) ([b688923](https://github.com/ReVanced/revanced-patches/commit/b688923c7e83805f2377a19b20a969b8cb749a9c))
|
||||
|
||||
## [4.8.3-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.8.3-dev.3...v4.8.3-dev.4) (2024-05-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **3rd-party Reddit apps:** Spoof user agent to work around Reddit API issues ([#3253](https://github.com/ReVanced/revanced-patches/issues/3253)) ([495e6d6](https://github.com/ReVanced/revanced-patches/commit/495e6d65e7cbae88baa71f8334b9afcf9819deaf))
|
||||
|
||||
## [4.8.3-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.8.3-dev.2...v4.8.3-dev.3) (2024-05-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Reddit - Hide ads:** Constrain to last working version 2024.17.0 ([#3192](https://github.com/ReVanced/revanced-patches/issues/3192)) ([4fb3456](https://github.com/ReVanced/revanced-patches/commit/4fb3456e93ff7ec19030de8870e1cb9c1319faef))
|
||||
|
||||
## [4.8.3-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.8.3-dev.1...v4.8.3-dev.2) (2024-05-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof client:** Clarify that only enter/exit fullscreen gesture does not work with Android VR spoof ([#3243](https://github.com/ReVanced/revanced-patches/issues/3243)) ([06d8f55](https://github.com/ReVanced/revanced-patches/commit/06d8f55e9b6ce27d8c550f202615689ac9c34cfa))
|
||||
|
||||
## [4.8.3-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.8.2...v4.8.3-dev.1) (2024-05-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof client:** Improve Android spoofing ([#3230](https://github.com/ReVanced/revanced-patches/issues/3230)) ([b688923](https://github.com/ReVanced/revanced-patches/commit/b688923c7e83805f2377a19b20a969b8cb749a9c))
|
||||
|
||||
## [4.8.2](https://github.com/ReVanced/revanced-patches/compare/v4.8.1...v4.8.2) (2024-05-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Client spoof:** Spoof iOS client model to fix various side effects ([#3220](https://github.com/ReVanced/revanced-patches/issues/3220)) ([9b5f4ce](https://github.com/ReVanced/revanced-patches/commit/9b5f4ce2b251c67e24cfcac3edae70c8a8aae230))
|
||||
|
||||
## [4.8.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.8.1...v4.8.2-dev.1) (2024-05-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Client spoof:** Spoof iOS client model to fix various side effects ([#3220](https://github.com/ReVanced/revanced-patches/issues/3220)) ([9b5f4ce](https://github.com/ReVanced/revanced-patches/commit/9b5f4ce2b251c67e24cfcac3edae70c8a8aae230))
|
||||
|
||||
## [4.8.1](https://github.com/ReVanced/revanced-patches/compare/v4.8.0...v4.8.1) (2024-05-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use UrlDecoder API available in older Android versions ([d42fbb1](https://github.com/ReVanced/revanced-patches/commit/d42fbb152126cf2177315c4706fb03bc89f5af1c))
|
||||
|
||||
## [4.8.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.8.0...v4.8.1-dev.1) (2024-05-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use UrlDecoder API available in older Android versions ([d42fbb1](https://github.com/ReVanced/revanced-patches/commit/d42fbb152126cf2177315c4706fb03bc89f5af1c))
|
||||
|
||||
# [4.8.0](https://github.com/ReVanced/revanced-patches/compare/v4.7.0...v4.8.0) (2024-05-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Case patch option title correctly ([259c8b4](https://github.com/ReVanced/revanced-patches/commit/259c8b4e58df51d92d7e19417e13afa3848afc73))
|
||||
* Correctly handle patches jar path if it contains exclamation marks ([056e2d7](https://github.com/ReVanced/revanced-patches/commit/056e2d7dd5bbacb7dc6b109b3e2d44d55e7eb7d3))
|
||||
* Publicize abstract property ([b7c108e](https://github.com/ReVanced/revanced-patches/commit/b7c108ee201c84df31b079f3fecb6cc2f5eaf9f1))
|
||||
* **Reddit is Fun - Spoof client:** Fix login by updating the authorization subdomain from "old" to "ssl" ([b156cb1](https://github.com/ReVanced/revanced-patches/commit/b156cb1d8996c4314d59e3441c6b85d8f704cdff))
|
||||
* URL decode path to JAR containing spaces to get JAR manifest ([#3079](https://github.com/ReVanced/revanced-patches/issues/3079)) ([e1bbcb3](https://github.com/ReVanced/revanced-patches/commit/e1bbcb338dd7fce895b606440bd6f040d5486a64))
|
||||
* Use correct preference key ([3732b2c](https://github.com/ReVanced/revanced-patches/commit/3732b2ce6b617b4c1c6647397b614f8a040eece3))
|
||||
* **YouTube - Client spoof:** Spoof client to fix playback ([#3199](https://github.com/ReVanced/revanced-patches/issues/3199)) ([bec1eef](https://github.com/ReVanced/revanced-patches/commit/bec1eef10f2eb4e15696acb271357f1621543de1))
|
||||
* **YouTube - Hide ads:** Fix string typo ([ecc56d6](https://github.com/ReVanced/revanced-patches/commit/ecc56d643a0c4e5f25b933431f097a03d4bf2e69))
|
||||
* **YouTube - Hide Shorts components:** Rename option title to make it consistent ([4d6e34b](https://github.com/ReVanced/revanced-patches/commit/4d6e34b0540a3334bd77b2b48a1a5e10329171c8))
|
||||
* **YouTube - Hide video action buttons:** Remove obsolete `hide Shop button` ([#3057](https://github.com/ReVanced/revanced-patches/issues/3057)) ([b5e34f3](https://github.com/ReVanced/revanced-patches/commit/b5e34f3aabc1d9df8c41f92251618243caecdc9f))
|
||||
* **YouTube - Navigation buttons:** Adjust summary text of switch notification button ([#3130](https://github.com/ReVanced/revanced-patches/issues/3130)) ([cc8b4c9](https://github.com/ReVanced/revanced-patches/commit/cc8b4c913ed25d07fd4000cfd6318bb06a9d27c0))
|
||||
* **YouTube - Player flyout menu:** Remove obsolete `Hide report menu` ([d627d44](https://github.com/ReVanced/revanced-patches/commit/d627d44ad07fa32bb2f247ce24a3591ec5e1be0e))
|
||||
* **YouTube - Restore old video quality menu:** Show advanced quality menu in Shorts quality flyout ([#3155](https://github.com/ReVanced/revanced-patches/issues/3155)) ([c2b5bb7](https://github.com/ReVanced/revanced-patches/commit/c2b5bb723416e43a920817f97b9e0ee4ceab4f6b))
|
||||
* **YouTube - SponsorBlock:** Show correct segment times if video is over 24 hours in length ([#3138](https://github.com/ReVanced/revanced-patches/issues/3138)) ([6cdf697](https://github.com/ReVanced/revanced-patches/commit/6cdf697e8e47f6d53964497703dbe79fab3b1821))
|
||||
* **YouTube Music:** Make `Hide 'Get Music Premium' label` and `Remove upgrade button` compatible with latest version ([#3164](https://github.com/ReVanced/revanced-patches/issues/3164)) ([3ff20de](https://github.com/ReVanced/revanced-patches/commit/3ff20dee4aea49ca77dcd3fbe148287b55a2b5e3))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Photomath:** Support version `8.37.0` ([#3109](https://github.com/ReVanced/revanced-patches/issues/3109)) ([fb02b48](https://github.com/ReVanced/revanced-patches/commit/fb02b481e2be8c2bc4441dc5b3dc6a9df3a2a379))
|
||||
* **Piccoma:** Add `Disable tracking` patch ([#3143](https://github.com/ReVanced/revanced-patches/issues/3143)) ([8ab9e8f](https://github.com/ReVanced/revanced-patches/commit/8ab9e8f89d2bd014138e31dab7004f8ba77cae10))
|
||||
* **Piccoma:** Add `Spoof Android device ID` patch ([#3145](https://github.com/ReVanced/revanced-patches/issues/3145)) ([d953c6b](https://github.com/ReVanced/revanced-patches/commit/d953c6bdd4315d2ba44845fd569a3d12ac4d1af0))
|
||||
* **Tumblr:** Add `Disable Ad-Free Banner` patch ([#3091](https://github.com/ReVanced/revanced-patches/issues/3091)) ([54baf08](https://github.com/ReVanced/revanced-patches/commit/54baf08f777b7c975fa0b6508f0a4de19ac491f4))
|
||||
* **WarnWetter - Promo code unlock:** Constrain to last working version ([#3110](https://github.com/ReVanced/revanced-patches/issues/3110)) ([92fc8aa](https://github.com/ReVanced/revanced-patches/commit/92fc8aaad80f8fad35b75e6de032692986211536))
|
||||
* **YouTube - Comments:** Add option to hide timestamp and emoji buttons ([#3076](https://github.com/ReVanced/revanced-patches/issues/3076)) ([7efe5ae](https://github.com/ReVanced/revanced-patches/commit/7efe5aefb252a2ed908907ff218b879e2ad1a331))
|
||||
* **YouTube - Hide ads:** Add option to hide the 'Visit store' button on channel pages ([#3077](https://github.com/ReVanced/revanced-patches/issues/3077)) ([03d2cfa](https://github.com/ReVanced/revanced-patches/commit/03d2cfafbf977340456598a848858ac9452c853f))
|
||||
* **YouTube - Hide Shorts components:** Hide 'Buy super thanks' button ([#3176](https://github.com/ReVanced/revanced-patches/issues/3176)) ([89c1548](https://github.com/ReVanced/revanced-patches/commit/89c154861c8b3afa665542e97ff201c3e84410b2))
|
||||
* **YouTube - Hide Shorts components:** Hide like / dislike button in video ads ([#3062](https://github.com/ReVanced/revanced-patches/issues/3062)) ([1296985](https://github.com/ReVanced/revanced-patches/commit/12969853adfe530eb6006df38e1a5aa30b28fdf9))
|
||||
* **YouTube - Navigation buttons:** Add option to hide navigation button labels ([#3189](https://github.com/ReVanced/revanced-patches/issues/3189)) ([f9dc705](https://github.com/ReVanced/revanced-patches/commit/f9dc7050513b9fdb7766838a63a172f1478296f7))
|
||||
* **YT Music:** Add support for `7.01.52` ([#3177](https://github.com/ReVanced/revanced-patches/issues/3177)) ([e9bfb25](https://github.com/ReVanced/revanced-patches/commit/e9bfb25dfe85754fd7fa5c9db934bb4fc52e4694))
|
||||
|
||||
# [4.8.0-dev.24](https://github.com/ReVanced/revanced-patches/compare/v4.8.0-dev.23...v4.8.0-dev.24) (2024-05-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Client spoof:** Spoof client to fix playback ([#3199](https://github.com/ReVanced/revanced-patches/issues/3199)) ([bec1eef](https://github.com/ReVanced/revanced-patches/commit/bec1eef10f2eb4e15696acb271357f1621543de1))
|
||||
|
||||
# [4.8.0-dev.23](https://github.com/ReVanced/revanced-patches/compare/v4.8.0-dev.22...v4.8.0-dev.23) (2024-05-18)
|
||||
|
||||
|
||||
|
||||
@@ -555,6 +555,7 @@ public final class app/revanced/patches/reddit/customclients/baconreader/api/Spo
|
||||
public final class app/revanced/patches/reddit/customclients/boostforreddit/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/api/SpoofClientPatch;
|
||||
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public fun patchUserAgent (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch {
|
||||
@@ -577,6 +578,11 @@ public final class app/revanced/patches/reddit/customclients/joeyforreddit/ads/D
|
||||
public final class app/revanced/patches/reddit/customclients/joeyforreddit/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/joeyforreddit/api/SpoofClientPatch;
|
||||
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public fun patchUserAgent (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/reddit/customclients/joeyforreddit/api/fingerprints/AuthUtilityUserAgent : app/revanced/patcher/fingerprint/MethodFingerprint {
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/joeyforreddit/api/fingerprints/AuthUtilityUserAgent;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/reddit/customclients/joeyforreddit/detection/piracy/DisablePiracyDetectionPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
@@ -621,6 +627,7 @@ public final class app/revanced/patches/reddit/customclients/syncforreddit/api/S
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/api/SpoofClientPatch;
|
||||
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public fun patchMiscellaneous (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public fun patchUserAgent (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/reddit/customclients/syncforreddit/detection/piracy/DisablePiracyDetectionPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
@@ -1631,12 +1638,10 @@ public final class app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDevic
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch;
|
||||
public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object;
|
||||
public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Lkotlin/Triple;
|
||||
public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V
|
||||
public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Triple;)V
|
||||
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
@@ -1651,6 +1656,14 @@ public final class app/revanced/patches/youtube/misc/fix/playback/SpoofSignature
|
||||
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch;
|
||||
public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object;
|
||||
public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Lkotlin/Triple;
|
||||
public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V
|
||||
public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Triple;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch : app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 4.8.0-dev.23
|
||||
version = 4.9.0-dev.3
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
[versions]
|
||||
revanced-patcher = "19.3.1"
|
||||
smali = "3.0.5"
|
||||
guava = "33.0.0-jre"
|
||||
#noinspection GradleDependency
|
||||
smali = "3.0.5" # 3.0.7 breaks binary compatibility. Tracking https://github.com/google/smali/issues/58.
|
||||
guava = "33.1.0-jre"
|
||||
gson = "2.10.1"
|
||||
binary-compatibility-validator = "0.14.0"
|
||||
kotlin = "1.9.22"
|
||||
kotlin = "2.0.0"
|
||||
|
||||
[libraries]
|
||||
revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" }
|
||||
|
||||
8
gradle/wrapper/gradle-wrapper.properties
vendored
8
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,8 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c
|
||||
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dist
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
20
gradlew.bat
vendored
20
gradlew.bat
vendored
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
||||
3059
package-lock.json
generated
3059
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,6 @@
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"gradle-semantic-release-plugin": "^1.9.1",
|
||||
"semantic-release": "^23.0.2"
|
||||
"semantic-release": "^23.0.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,18 @@ import app.revanced.util.exception
|
||||
|
||||
@Patch(
|
||||
name = "Hide music video ads",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideMusicVideoAds : BytecodePatch(
|
||||
|
||||
@@ -11,7 +11,18 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@Patch(
|
||||
description = "Adds more audio codec options. The new audio codecs usually result in better audio quality.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@Deprecated("This patch is no longer needed as the feature is now enabled by default.")
|
||||
object CodecsUnlockPatch : BytecodePatch(
|
||||
|
||||
@@ -11,7 +11,18 @@ import app.revanced.util.exception
|
||||
@Patch(
|
||||
name = "Enable exclusive audio playback",
|
||||
description = "Enables the option to play audio without video.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object EnableExclusiveAudioPlayback : BytecodePatch(
|
||||
|
||||
@@ -13,7 +13,18 @@ import app.revanced.patches.music.interaction.permanentrepeat.fingerprints.Repea
|
||||
@Patch(
|
||||
name = "Permanent repeat",
|
||||
description = "Permanently remember your repeating preference even if the playlist ends or another track is played.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
],
|
||||
use = false
|
||||
)
|
||||
@Suppress("unused")
|
||||
@@ -23,7 +34,7 @@ object PermanentRepeatPatch : BytecodePatch(
|
||||
override fun execute(context: BytecodeContext) {
|
||||
RepeatTrackFingerprint.result?.let {
|
||||
val startIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val repeatIndex = startIndex + 3
|
||||
val repeatIndex = startIndex + 1
|
||||
|
||||
it.mutableMethod.apply {
|
||||
addInstructionsWithLabels(
|
||||
|
||||
@@ -6,17 +6,16 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object RepeatTrackFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf("L", "L"),
|
||||
listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L", "L"),
|
||||
opcodes = listOf(
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_NEZ
|
||||
)
|
||||
),
|
||||
strings = listOf("w_st")
|
||||
)
|
||||
|
||||
@@ -12,7 +12,18 @@ import app.revanced.util.exception
|
||||
name = "Permanent shuffle",
|
||||
description = "Permanently remember your shuffle preference " +
|
||||
"even if the playlist ends or another track is played.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
],
|
||||
use = false,
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -13,7 +13,18 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@Patch(
|
||||
name = "Hide category bar",
|
||||
description = "Hides the category bar at the top of the homepage.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
],
|
||||
use = false,
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -13,7 +13,18 @@ import app.revanced.util.exception
|
||||
@Patch(
|
||||
name = "Minimized playback",
|
||||
description = "Unlocks options for picture-in-picture and background playback.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object MinimizedPlaybackPatch : BytecodePatch(
|
||||
|
||||
@@ -16,7 +16,18 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
@Patch(
|
||||
name = "Hide 'Get Music Premium' label",
|
||||
description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideGetPremiumPatch : BytecodePatch(
|
||||
|
||||
@@ -22,7 +22,18 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
@Patch(
|
||||
name = "Remove upgrade button",
|
||||
description = "Removes the upgrade tab from the pivot bar.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object RemoveUpgradeButtonPatch : BytecodePatch(
|
||||
|
||||
@@ -12,7 +12,18 @@ import app.revanced.patches.music.misc.androidauto.fingerprints.CheckCertificate
|
||||
@Patch(
|
||||
name = "Bypass certificate checks",
|
||||
description = "Bypasses certificate checks which prevent YouTube Music from working on Android Auto.",
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object BypassCertificateChecksPatch : BytecodePatch(setOf(CheckCertificateFingerprint)) {
|
||||
|
||||
@@ -23,7 +23,18 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||
mainActivityOnCreateFingerprint = MusicActivityOnCreateFingerprint,
|
||||
integrationsPatchDependency = IntegrationsPatch::class,
|
||||
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
||||
compatiblePackages = setOf(CompatiblePackage("com.google.android.apps.youtube.music")),
|
||||
compatiblePackages = setOf(
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
setOf(
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
)
|
||||
)
|
||||
),
|
||||
fingerprints = setOf(
|
||||
ServiceCheckFingerprint,
|
||||
GooglePlayUtilityFingerprint,
|
||||
|
||||
@@ -4,6 +4,9 @@ import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
|
||||
// Note that for now, this patch and anything using it will only work on
|
||||
// Reddit 2024.17.0 or older. Newer versions will crash during patching.
|
||||
// See https://github.com/ReVanced/revanced-patches/issues/3099
|
||||
@Patch(description = "Hides banner ads from comments on subreddits.")
|
||||
object HideBannerPatch : ResourcePatch() {
|
||||
private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml"
|
||||
|
||||
@@ -20,7 +20,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
@Patch(
|
||||
name = "Hide ads",
|
||||
dependencies = [HideBannerPatch::class, HideCommentAdsPatch::class],
|
||||
compatiblePackages = [CompatiblePackage("com.reddit.frontpage")],
|
||||
// Note that for now, this patch and anything using it will only work on
|
||||
// Reddit 2024.17.0 or older. Newer versions will crash during patching.
|
||||
// See https://github.com/ReVanced/revanced-patches/issues/3099
|
||||
// and https://github.com/iBotPeaches/Apktool/issues/3534.
|
||||
// This constraint is necessary due to dependency on HideBannerPatch.
|
||||
compatiblePackages = [CompatiblePackage("com.reddit.frontpage", ["2024.17.0"])],
|
||||
requiresIntegrations = true,
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -4,16 +4,15 @@ import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprintResult
|
||||
import app.revanced.patches.reddit.customclients.BaseSpoofClientPatch
|
||||
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.BuildUserAgentFingerprint
|
||||
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint
|
||||
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.LoginActivityOnCreateFingerprint
|
||||
|
||||
|
||||
@Suppress("unused")
|
||||
object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
redirectUri = "http://rubenmayayo.com",
|
||||
clientIdFingerprints = setOf(GetClientIdFingerprint),
|
||||
userAgentFingerprints = setOf(LoginActivityOnCreateFingerprint),
|
||||
compatiblePackages = setOf(CompatiblePackage("com.rubenmayayo.reddit"))
|
||||
userAgentFingerprints = setOf(BuildUserAgentFingerprint),
|
||||
compatiblePackages = setOf(CompatiblePackage("com.rubenmayayo.reddit")),
|
||||
) {
|
||||
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
|
||||
first().mutableMethod.addInstructions(
|
||||
@@ -21,7 +20,18 @@ object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
"""
|
||||
const-string v0, "$clientId"
|
||||
return-object v0
|
||||
"""
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
override fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
|
||||
// Use a random number as the platform in the user agent string.
|
||||
val platformName = (0..100000).random()
|
||||
val platformParameter = 0
|
||||
|
||||
first().mutableMethod.addInstructions(
|
||||
0,
|
||||
"const-string p$platformParameter, \"$platformName\"",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object BuildUserAgentFingerprint : MethodFingerprint(
|
||||
strings = listOf("%s:%s:%s (by /u/%s)"),
|
||||
)
|
||||
@@ -1,14 +0,0 @@
|
||||
package app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object LoginActivityOnCreateFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CONST_4
|
||||
),
|
||||
customFingerprint = { method, classDef ->
|
||||
method.name == "onCreate" && classDef.type.endsWith("LoginActivity;")
|
||||
}
|
||||
)
|
||||
@@ -2,8 +2,10 @@ package app.revanced.patches.reddit.customclients.joeyforreddit.api
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprintResult
|
||||
import app.revanced.patches.reddit.customclients.BaseSpoofClientPatch
|
||||
import app.revanced.patches.reddit.customclients.joeyforreddit.api.fingerprints.AuthUtilityUserAgent
|
||||
import app.revanced.patches.reddit.customclients.joeyforreddit.api.fingerprints.GetClientIdFingerprint
|
||||
import app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy.DisablePiracyDetectionPatch
|
||||
|
||||
@@ -12,6 +14,7 @@ import app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy.
|
||||
object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
redirectUri = "https://127.0.0.1:65023/authorize_callback",
|
||||
clientIdFingerprints = setOf(GetClientIdFingerprint),
|
||||
userAgentFingerprints = setOf(AuthUtilityUserAgent),
|
||||
compatiblePackages = setOf(
|
||||
CompatiblePackage("o.o.joey"),
|
||||
CompatiblePackage("o.o.joey.pro"),
|
||||
@@ -28,4 +31,18 @@ object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
override fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
|
||||
// Use a random user agent.
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
first().mutableMethod.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.reddit.customclients.joeyforreddit.api.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
object AuthUtilityUserAgent : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
opcodes = listOf(Opcode.APUT_OBJECT),
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.sourceFile == "AuthUtility.java"
|
||||
},
|
||||
)
|
||||
@@ -1,18 +1,16 @@
|
||||
package app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy
|
||||
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint
|
||||
import app.revanced.util.exception
|
||||
|
||||
object DisablePiracyDetectionPatch : BytecodePatch(setOf(PiracyDetectionFingerprint)) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
PiracyDetectionFingerprint.result?.mutableMethod?.addInstruction(
|
||||
0,
|
||||
"""
|
||||
return-void
|
||||
"""
|
||||
"return-void",
|
||||
) ?: throw PiracyDetectionFingerprint.exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Suppress("unused")
|
||||
object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
redirectUri = "redditisfun://auth",
|
||||
@@ -54,7 +53,7 @@ object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
override fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
|
||||
// Use a random user agent.
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "android:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
first().mutableMethod.addInstructions(
|
||||
0,
|
||||
|
||||
@@ -6,10 +6,10 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprintResult
|
||||
import app.revanced.patches.reddit.customclients.BaseSpoofClientPatch
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.*
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetBearerTokenFingerprint
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.ImgurImageAPIFingerprint
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.LoadBrowserURLFingerprint
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.DisablePiracyDetectionPatch
|
||||
import app.revanced.util.exception
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@@ -17,19 +17,18 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
import java.util.*
|
||||
|
||||
|
||||
@Suppress("unused")
|
||||
object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
redirectUri = "http://redditsync/auth",
|
||||
miscellaneousFingerprints = setOf(ImgurImageAPIFingerprint),
|
||||
clientIdFingerprints = setOf(GetAuthorizationStringFingerprint),
|
||||
userAgentFingerprints = setOf(LoadBrowserURLFingerprint),
|
||||
userAgentFingerprints = setOf(GetUserAgentFingerprint),
|
||||
compatiblePackages = setOf(
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync"),
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync.pro"),
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync.dev")
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync.dev"),
|
||||
),
|
||||
dependencies = setOf(DisablePiracyDetectionPatch::class)
|
||||
dependencies = setOf(DisablePiracyDetectionPatch::class),
|
||||
) {
|
||||
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
|
||||
forEach { fingerprintResult ->
|
||||
@@ -41,7 +40,7 @@ object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
"""
|
||||
const-string v0, "Basic $auth"
|
||||
return-object v0
|
||||
"""
|
||||
""",
|
||||
)
|
||||
} ?: throw GetBearerTokenFingerprint.exception
|
||||
}.let {
|
||||
@@ -54,12 +53,12 @@ object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
|
||||
val newAuthorizationUrl = reference.string.replace(
|
||||
"client_id=.*?&".toRegex(),
|
||||
"client_id=$clientId&"
|
||||
"client_id=$clientId&",
|
||||
)
|
||||
|
||||
replaceInstruction(
|
||||
occurrenceIndex,
|
||||
"const-string v$targetRegister, \"$newAuthorizationUrl\""
|
||||
"const-string v$targetRegister, \"$newAuthorizationUrl\"",
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -72,7 +71,21 @@ object SpoofClientPatch : BaseSpoofClientPatch(
|
||||
|
||||
it.mutableMethod.replaceInstruction(
|
||||
apiUrlIndex,
|
||||
"const-string v1, \"https://api.imgur.com/3/image\""
|
||||
"const-string v1, \"https://api.imgur.com/3/image\"",
|
||||
)
|
||||
}
|
||||
|
||||
override fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
|
||||
// Use a random user agent.
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
first().mutableMethod.replaceInstruction(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object GetUserAgentFingerprint : MethodFingerprint(
|
||||
strings = listOf("android:com.laurencedawson.reddit_sync"),
|
||||
)
|
||||
@@ -14,7 +14,6 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import java.net.URLDecoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.jar.JarFile
|
||||
|
||||
abstract class BaseIntegrationsPatch(
|
||||
@@ -77,7 +76,8 @@ abstract class BaseIntegrationsPatch(
|
||||
|
||||
if (urlString.startsWith("jar:file:")) {
|
||||
val end = urlString.lastIndexOf('!')
|
||||
return URLDecoder.decode(urlString.substring("jar:file:".length, end), StandardCharsets.UTF_8)
|
||||
|
||||
return URLDecoder.decode(urlString.substring("jar:file:".length, end), "UTF-8")
|
||||
}
|
||||
}
|
||||
throw IllegalStateException("Not running from inside a JAR file.")
|
||||
|
||||
@@ -102,6 +102,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||
SwitchPreference("revanced_hide_expandable_chip"),
|
||||
SwitchPreference("revanced_hide_info_panels"),
|
||||
SwitchPreference("revanced_hide_join_membership_button"),
|
||||
SwitchPreference("revanced_disable_like_subscribe_glow"),
|
||||
SwitchPreference("revanced_hide_medical_panels"),
|
||||
SwitchPreference("revanced_hide_quick_actions"),
|
||||
SwitchPreference("revanced_hide_related_videos"),
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
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.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.BuildInitPlaybackRequestFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.BuildPlayerRequestURIFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.CreatePlayerRequestBodyFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.CreatePlayerRequestBodyWithModelFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerGestureConfigSyntheticFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.SetPlayerRequestClientTypeFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
@Patch(
|
||||
name = "Spoof client",
|
||||
description = "Spoofs the client to allow video playback.",
|
||||
dependencies = [
|
||||
SettingsPatch::class,
|
||||
AddResourcesPatch::class,
|
||||
UserAgentClientSpoofPatch::class,
|
||||
],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
object SpoofClientPatch : BytecodePatch(
|
||||
setOf(
|
||||
// Client type spoof.
|
||||
BuildInitPlaybackRequestFingerprint,
|
||||
BuildPlayerRequestURIFingerprint,
|
||||
SetPlayerRequestClientTypeFingerprint,
|
||||
CreatePlayerRequestBodyFingerprint,
|
||||
CreatePlayerRequestBodyWithModelFingerprint,
|
||||
|
||||
// Player gesture config.
|
||||
PlayerGestureConfigSyntheticFingerprint,
|
||||
),
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/youtube/patches/spoof/SpoofClientPatch;"
|
||||
private const val CLIENT_INFO_CLASS_DESCRIPTOR =
|
||||
"Lcom/google/protos/youtube/api/innertube/InnertubeContext\$ClientInfo;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
PreferenceScreen(
|
||||
key = "revanced_spoof_client_screen",
|
||||
sorting = Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_client"),
|
||||
SwitchPreference("revanced_spoof_client_use_ios"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
// region Block /initplayback requests to fall back to /get_watch requests.
|
||||
|
||||
BuildInitPlaybackRequestFingerprint.resultOrThrow().let {
|
||||
val moveUriStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
moveUriStringIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region fix player gesture.
|
||||
|
||||
PlayerGestureConfigSyntheticFingerprint.resultOrThrow().let {
|
||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
arrayOf(3, 9).forEach { offSet ->
|
||||
(context.toMethodWalker(it.mutableMethod)
|
||||
.nextMethod(endIndex - offSet, true)
|
||||
.getMethod() as MutableMethod)
|
||||
.apply {
|
||||
|
||||
val index = implementation!!.instructions.lastIndex
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstructions(
|
||||
index,
|
||||
"""
|
||||
invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->enablePlayerGesture(Z)Z
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Block /get_watch requests to fall back to /player requests.
|
||||
|
||||
BuildPlayerRequestURIFingerprint.resultOrThrow().let {
|
||||
val invokeToStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||
|
||||
addInstructions(
|
||||
invokeToStringIndex,
|
||||
"""
|
||||
invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||
move-result-object v$uriRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Get field references to be used below.
|
||||
|
||||
val (clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField) =
|
||||
SetPlayerRequestClientTypeFingerprint.resultOrThrow().let { result ->
|
||||
// Field in the player request object that holds the client info object.
|
||||
val clientInfoField = result.mutableMethod
|
||||
.getInstructions().find { instruction ->
|
||||
// requestMessage.clientInfo = clientInfoBuilder.build();
|
||||
instruction.opcode == Opcode.IPUT_OBJECT &&
|
||||
instruction.getReference<FieldReference>()?.type == CLIENT_INFO_CLASS_DESCRIPTOR
|
||||
}?.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoField")
|
||||
|
||||
// Client info object's client type field.
|
||||
val clientInfoClientTypeField = result.mutableMethod
|
||||
.getInstruction(result.scanResult.patternScanResult!!.endIndex)
|
||||
.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientTypeField")
|
||||
|
||||
// Client info object's client version field.
|
||||
val clientInfoClientVersionField = result.mutableMethod
|
||||
.getInstruction(result.scanResult.stringsScanResult!!.matches.first().index + 1)
|
||||
.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientVersionField")
|
||||
|
||||
Triple(clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField)
|
||||
}
|
||||
|
||||
val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().let {
|
||||
val getClientModelIndex = CreatePlayerRequestBodyWithModelFingerprint.indexOfBuildModelInstruction(it.method)
|
||||
val instructions = it.mutableMethod.getInstructions()
|
||||
|
||||
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
|
||||
instructions.subList(
|
||||
getClientModelIndex,
|
||||
instructions.size,
|
||||
).find { instruction ->
|
||||
instruction.opcode == Opcode.IPUT_OBJECT
|
||||
}?.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientModelField")
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Spoof client type for /player requests.
|
||||
|
||||
CreatePlayerRequestBodyFingerprint.resultOrThrow().let { result ->
|
||||
val setClientInfoMethodName = "patch_setClientInfo"
|
||||
val checkCastIndex = result.scanResult.patternScanResult!!.startIndex
|
||||
var clientInfoContainerClassName: String
|
||||
|
||||
result.mutableMethod.apply {
|
||||
val checkCastInstruction = getInstruction<OneRegisterInstruction>(checkCastIndex)
|
||||
val requestMessageInstanceRegister = checkCastInstruction.registerA
|
||||
clientInfoContainerClassName = checkCastInstruction.getReference<TypeReference>()!!.type
|
||||
|
||||
addInstruction(
|
||||
checkCastIndex + 1,
|
||||
"invoke-static { v$requestMessageInstanceRegister }," +
|
||||
" ${result.classDef.type}->$setClientInfoMethodName($clientInfoContainerClassName)V",
|
||||
)
|
||||
}
|
||||
|
||||
// Change client info to use the spoofed values.
|
||||
// Do this in a helper method, to remove the need of picking out multiple free registers from the hooked code.
|
||||
result.mutableClass.methods.add(
|
||||
ImmutableMethod(
|
||||
result.mutableClass.type,
|
||||
setClientInfoMethodName,
|
||||
listOf(ImmutableMethodParameter(clientInfoContainerClassName, null, "clientInfoContainer")),
|
||||
"V",
|
||||
AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(3),
|
||||
).toMutable().apply {
|
||||
addInstructions(
|
||||
"""
|
||||
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->isClientSpoofingEnabled()Z
|
||||
move-result v0
|
||||
if-eqz v0, :disabled
|
||||
|
||||
iget-object v0, p0, $clientInfoField
|
||||
|
||||
# Set client type to the spoofed value.
|
||||
iget v1, v0, $clientInfoClientTypeField
|
||||
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientTypeId(I)I
|
||||
move-result v1
|
||||
iput v1, v0, $clientInfoClientTypeField
|
||||
|
||||
# Set client model to the spoofed value.
|
||||
iget-object v1, v0, $clientInfoClientModelField
|
||||
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientModel(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $clientInfoClientModelField
|
||||
|
||||
# Set client version to the spoofed value.
|
||||
iget-object v1, v0, $clientInfoClientVersionField
|
||||
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientVersion(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $clientInfoClientVersionField
|
||||
|
||||
:disabled
|
||||
return-void
|
||||
""",
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||
StoryboardRendererDecoderSpecFingerprint,
|
||||
StoryboardRendererDecoderRecommendedLevelFingerprint,
|
||||
StoryboardThumbnailParentFingerprint,
|
||||
ScrubbedPreviewLayoutFingerprint,
|
||||
SpoofSignaturePatchScrubbedPreviewLayoutFingerprint,
|
||||
StatsQueryParameterFingerprint,
|
||||
ParamsMapPutFingerprint,
|
||||
),
|
||||
@@ -68,7 +68,7 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||
|
||||
// Hook the player parameters.
|
||||
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.ProtoBufferParameter(
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Z)Ljava/lang/String;",
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
|
||||
)
|
||||
|
||||
// Force the seekbar time and chapters to always show up.
|
||||
@@ -104,7 +104,7 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||
}
|
||||
|
||||
// If storyboard spoofing is turned off, then hide the empty seekbar thumbnail view.
|
||||
ScrubbedPreviewLayoutFingerprint.result?.apply {
|
||||
SpoofSignaturePatchScrubbedPreviewLayoutFingerprint.result?.apply {
|
||||
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||
mutableMethod.apply {
|
||||
val imageViewFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||
@@ -116,7 +116,7 @@ object SpoofSignaturePatch : BytecodePatch(
|
||||
""",
|
||||
)
|
||||
}
|
||||
} ?: throw ScrubbedPreviewLayoutFingerprint.exception
|
||||
} ?: throw SpoofSignaturePatchScrubbedPreviewLayoutFingerprint.exception
|
||||
|
||||
/**
|
||||
* Hook StoryBoard renderer url
|
||||
|
||||
@@ -4,9 +4,9 @@ import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
|
||||
@Patch(dependencies = [SettingsPatch::class, ResourceMappingPatch::class])
|
||||
@Patch(dependencies = [ResourceMappingPatch::class])
|
||||
@Deprecated("This patch will be removed in the future.")
|
||||
object SpoofSignatureResourcePatch : ResourcePatch() {
|
||||
internal var scrubbedPreviewThumbnailResourceId: Long = -1
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@ package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.all.misc.transformation.BaseTransformInstructionsPatch
|
||||
import app.revanced.patches.all.misc.transformation.IMethodCall
|
||||
@@ -16,14 +14,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
name = "Client spoof",
|
||||
description = "Spoofs the client to allow video playback.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.google.android.youtube"),
|
||||
],
|
||||
)
|
||||
object ClientSpoofPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
object UserAgentClientSpoofPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
|
||||
private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE =
|
||||
"Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;"
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object BuildInitPlaybackRequestFingerprint : MethodFingerprint(
|
||||
returnType = "Lorg/chromium/net/UrlRequest\$Builder;",
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IGET_OBJECT, // Moves the request URI string to a register to build the request with.
|
||||
),
|
||||
strings = listOf(
|
||||
"Content-Type",
|
||||
"Range",
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object BuildPlayerRequestURIFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL, // Register holds player request URI.
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.MONITOR_EXIT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
),
|
||||
strings = listOf(
|
||||
"youtubei/v1",
|
||||
"key",
|
||||
"asig",
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object CreatePlayerRequestBodyFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.IGET,
|
||||
Opcode.AND_INT_LIT16,
|
||||
),
|
||||
strings = listOf("ms"),
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.CreatePlayerRequestBodyWithModelFingerprint.indexOfBuildModelInstruction
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
internal object CreatePlayerRequestBodyWithModelFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf(),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionValue(1073741824) &&
|
||||
indexOfBuildModelInstruction(methodDef) >= 0
|
||||
},
|
||||
) {
|
||||
fun indexOfBuildModelInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstruction {
|
||||
val reference = getReference<FieldReference>()
|
||||
reference?.definingClass == "Landroid/os/Build;" &&
|
||||
reference.name == "MODEL" &&
|
||||
reference.type == "Ljava/lang/String;"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object ParamsMapPutFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerGestureConfigSyntheticFingerprint.indexOfDownAndOutAllowedInstruction
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal object PlayerGestureConfigSyntheticFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Ljava/lang/Object;"),
|
||||
opcodes = listOf(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutLandscapeAllowed
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutPortraitAllowed
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
Opcode.RETURN_VOID,
|
||||
),
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
// This method is always called "a" because this kind of class always has a single method.
|
||||
methodDef.name == "a" && classDef.methods.count() == 2 &&
|
||||
indexOfDownAndOutAllowedInstruction(methodDef) >= 0
|
||||
}
|
||||
) {
|
||||
fun indexOfDownAndOutAllowedInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" &&
|
||||
reference.parameterTypes.isEmpty() &&
|
||||
reference.returnType == "Z"
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object PlayerResponseModelImplGeneralFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
@@ -13,11 +14,11 @@ internal object PlayerResponseModelImplGeneralFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.RETURN_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN_OBJECT
|
||||
Opcode.RETURN_OBJECT,
|
||||
),
|
||||
customFingerprint = handler@{ methodDef, _ ->
|
||||
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionValue(55735497)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object PlayerResponseModelImplLiveStreamFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
@@ -13,11 +14,11 @@ internal object PlayerResponseModelImplLiveStreamFingerprint : MethodFingerprint
|
||||
opcodes = listOf(
|
||||
Opcode.RETURN_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN_OBJECT
|
||||
Opcode.RETURN_OBJECT,
|
||||
),
|
||||
customFingerprint = handler@{ methodDef, _ ->
|
||||
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionValue(70276274)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object PlayerResponseModelImplRecommendedLevelFingerprint : MethodFingerprint(
|
||||
returnType = "I",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
@@ -13,11 +14,11 @@ internal object PlayerResponseModelImplRecommendedLevelFingerprint : MethodFinge
|
||||
opcodes = listOf(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.IGET,
|
||||
Opcode.RETURN
|
||||
Opcode.RETURN,
|
||||
),
|
||||
customFingerprint = handler@{ methodDef, _ ->
|
||||
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionValue(55735497)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object SetPlayerRequestClientTypeFingerprint : LiteralValueFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.IGET,
|
||||
Opcode.IPUT, // Sets ClientInfo.clientId.
|
||||
),
|
||||
strings = listOf("10.29"),
|
||||
literalSupplier = { 134217728 }
|
||||
)
|
||||
@@ -6,7 +6,8 @@ import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object ScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object SpoofSignaturePatchScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = listOf("Landroid/content/Context;", "Landroid/util/AttributeSet;", "I", "I"),
|
||||
@@ -23,5 +24,5 @@ internal object ScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
|
||||
Opcode.IPUT_OBJECT, // preview imageview
|
||||
),
|
||||
// This resource is used in ~ 40 different locations, but this method has a distinct list of parameters to match to.
|
||||
literalSupplier = { SpoofSignatureResourcePatch.scrubbedPreviewThumbnailResourceId }
|
||||
)
|
||||
literalSupplier = { SpoofSignatureResourcePatch.scrubbedPreviewThumbnailResourceId },
|
||||
)
|
||||
@@ -2,6 +2,7 @@ package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StatsQueryParameterFingerprint : MethodFingerprint(
|
||||
strings = listOf("adunit"),
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
/**
|
||||
* Resolves to the same method as [StoryboardRendererDecoderSpecFingerprint].
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardRendererDecoderRecommendedLevelFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
@@ -17,7 +18,7 @@ internal object StoryboardRendererDecoderRecommendedLevelFingerprint : MethodFin
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT
|
||||
Opcode.MOVE_RESULT,
|
||||
),
|
||||
strings = listOf("#-1#")
|
||||
strings = listOf("#-1#"),
|
||||
)
|
||||
|
||||
@@ -6,8 +6,9 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
/**
|
||||
* Resolves to the same method as [StoryboardRendererDecoderRecommendedLevelFingerprint].
|
||||
*/
|
||||
* Resolves to the same method as [StoryboardRendererDecoderRecommendedLevelFingerprint].
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardRendererDecoderSpecFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
@@ -19,5 +20,5 @@ internal object StoryboardRendererDecoderSpecFingerprint : MethodFingerprint(
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_NEZ,
|
||||
),
|
||||
strings = listOf("#-1#")
|
||||
strings = listOf("#-1#"),
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardRendererSpecFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
returnType = "L",
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
/**
|
||||
* Resolves using the class found in [StoryboardThumbnailParentFingerprint].
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardThumbnailFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Z",
|
||||
|
||||
@@ -10,8 +10,9 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||
* An additional change here might force the thumbnails to be created,
|
||||
* or possibly a change somewhere else (maybe involving YouTube 18.23.35 class `hte`)
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardThumbnailParentFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Landroid/graphics/Bitmap;",
|
||||
strings = listOf("Storyboard regionDecoder.decodeRegion exception - "),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.youtube.misc.gms
|
||||
import app.revanced.patches.shared.fingerprints.CastContextFetchFingerprint
|
||||
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
|
||||
import app.revanced.patches.youtube.layout.buttons.cast.HideCastButtonPatch
|
||||
import app.revanced.patches.youtube.misc.fix.playback.ClientSpoofPatch
|
||||
import app.revanced.patches.youtube.misc.fix.playback.SpoofClientPatch
|
||||
import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME
|
||||
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
||||
import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption
|
||||
@@ -27,13 +27,18 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||
integrationsPatchDependency = IntegrationsPatch::class,
|
||||
dependencies = setOf(
|
||||
HideCastButtonPatch::class,
|
||||
ClientSpoofPatch::class,
|
||||
SpoofClientPatch::class,
|
||||
),
|
||||
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
||||
compatiblePackages = setOf(
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
setOf(
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
@@ -46,7 +51,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43"
|
||||
"19.11.43",
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -119,7 +119,7 @@ object VideoInformationPatch : BytecodePatch(
|
||||
// Call before any other video id hooks,
|
||||
// so they can use VideoInformation and check if the video id is for a Short.
|
||||
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.ProtoBufferParameterBeforeVideoId(
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseSignature(Ljava/lang/String;Z)Ljava/lang/String;")
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseSignature(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;")
|
||||
|
||||
/*
|
||||
* Set the video time method
|
||||
|
||||
@@ -24,24 +24,39 @@ object PlayerResponseMethodHookPatch :
|
||||
private const val PARAMETER_PROTO_BUFFER = 3
|
||||
private const val PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING = 11
|
||||
|
||||
// Temporary 4-bit registers used to pass the parameters to integrations.
|
||||
private const val REGISTER_VIDEO_ID = 0
|
||||
private const val REGISTER_PROTO_BUFFER = 1
|
||||
private const val REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING = 2
|
||||
// Registers used to pass the parameters to integrations.
|
||||
private var playerResponseMethodCopyRegisters = false
|
||||
private lateinit var REGISTER_VIDEO_ID : String
|
||||
private lateinit var REGISTER_PROTO_BUFFER : String
|
||||
private lateinit var REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING : String
|
||||
|
||||
private lateinit var playerResponseMethod: MutableMethod
|
||||
|
||||
private var numberOfInstructionsAdded = 0
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
playerResponseMethod = PlayerParameterBuilderFingerprint.result?.mutableMethod
|
||||
?: throw PlayerParameterBuilderFingerprint.exception
|
||||
|
||||
// On some app targets the method has too many registers pushing the parameters past v15.
|
||||
// If needed, move the parameters to 4-bit registers so they can be passed to integrations.
|
||||
playerResponseMethodCopyRegisters = playerResponseMethod.implementation!!.registerCount -
|
||||
playerResponseMethod.parameterTypes.size + PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING > 15
|
||||
|
||||
if (playerResponseMethodCopyRegisters) {
|
||||
REGISTER_VIDEO_ID = "v0"
|
||||
REGISTER_PROTO_BUFFER = "v1"
|
||||
REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING = "v2"
|
||||
} else {
|
||||
REGISTER_VIDEO_ID = "p$PARAMETER_VIDEO_ID"
|
||||
REGISTER_PROTO_BUFFER = "p$PARAMETER_PROTO_BUFFER"
|
||||
REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING = "p$PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING"
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
fun hookVideoId(hook: Hook) {
|
||||
playerResponseMethod.addInstruction(
|
||||
0, "invoke-static {v$REGISTER_VIDEO_ID, v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook"
|
||||
0, "invoke-static {$REGISTER_VIDEO_ID, $REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook"
|
||||
)
|
||||
numberOfInstructionsAdded++
|
||||
}
|
||||
@@ -50,8 +65,8 @@ object PlayerResponseMethodHookPatch :
|
||||
playerResponseMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static {v$REGISTER_PROTO_BUFFER, v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook
|
||||
move-result-object v$REGISTER_PROTO_BUFFER
|
||||
invoke-static {$REGISTER_PROTO_BUFFER, $REGISTER_VIDEO_ID, $REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook
|
||||
move-result-object $REGISTER_PROTO_BUFFER
|
||||
"""
|
||||
)
|
||||
numberOfInstructionsAdded += 2
|
||||
@@ -67,22 +82,22 @@ object PlayerResponseMethodHookPatch :
|
||||
videoIdHooks.forEach(::hookVideoId)
|
||||
beforeVideoIdHooks.forEach(::hookProtoBufferParameter)
|
||||
|
||||
// On some app targets the method has too many registers pushing the parameters past v15.
|
||||
// Move the parameters to 4-bit registers so they can be passed to integrations.
|
||||
playerResponseMethod.addInstructions(
|
||||
0, """
|
||||
move-object/from16 v$REGISTER_VIDEO_ID, p$PARAMETER_VIDEO_ID
|
||||
move-object/from16 v$REGISTER_PROTO_BUFFER, p$PARAMETER_PROTO_BUFFER
|
||||
move/from16 v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING, p$PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING
|
||||
if (playerResponseMethodCopyRegisters) {
|
||||
playerResponseMethod.addInstructions(
|
||||
0, """
|
||||
move-object/from16 $REGISTER_VIDEO_ID, p$PARAMETER_VIDEO_ID
|
||||
move-object/from16 $REGISTER_PROTO_BUFFER, p$PARAMETER_PROTO_BUFFER
|
||||
move/from16 $REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING, p$PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING
|
||||
""",
|
||||
)
|
||||
numberOfInstructionsAdded += 3
|
||||
)
|
||||
numberOfInstructionsAdded += 3
|
||||
|
||||
// Move the modified register back.
|
||||
playerResponseMethod.addInstruction(
|
||||
numberOfInstructionsAdded,
|
||||
"move-object/from16 p$PARAMETER_PROTO_BUFFER, v$REGISTER_PROTO_BUFFER"
|
||||
)
|
||||
// Move the modified register back.
|
||||
playerResponseMethod.addInstruction(
|
||||
numberOfInstructionsAdded,
|
||||
"move-object/from16 p$PARAMETER_PROTO_BUFFER, $REGISTER_PROTO_BUFFER"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class Hook(private val methodDescriptor: String) {
|
||||
|
||||
@@ -91,6 +91,9 @@
|
||||
<string name="revanced_debug_toast_on_error_user_dialog_message">Turning off error toasts hides all ReVanced error notifications.\n\nYou will not be notified of any unexpected events.</string>
|
||||
</patch>
|
||||
<patch id="layout.hide.general.HideLayoutComponentsPatch">
|
||||
<string name="revanced_disable_like_subscribe_glow_title">Disable like / subscribe button glow</string>
|
||||
<string name="revanced_disable_like_subscribe_glow_summary_on">Like and subscribe button will not glow when mentioned</string>
|
||||
<string name="revanced_disable_like_subscribe_glow_summary_off">Like and subscribe button will glow when mentioned</string>
|
||||
<string name="revanced_hide_gray_separator_title">Hide gray separator</string>
|
||||
<string name="revanced_hide_gray_separator_summary_on">Gray separators are hidden</string>
|
||||
<string name="revanced_hide_gray_separator_summary_off">Gray separators are shown</string>
|
||||
@@ -907,7 +910,7 @@
|
||||
<string name="revanced_spoof_app_version_summary_on">Version spoofed</string>
|
||||
<string name="revanced_spoof_app_version_summary_off">Version not spoofed</string>
|
||||
<string name="revanced_spoof_app_version_user_dialog_message">App version will be spoofed to an older version of YouTube.\n\nThis will change the appearance and features of the app, but unknown side effects may occur.\n\nIf later turned off, it is recommended to clear the app data to prevent UI bugs.</string>
|
||||
<!-- It is ideal, but not required, if the text here appears alphabetically after the text used for 'revanced_spoof_app_version_title'.
|
||||
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_spoof_app_version_title'.
|
||||
This is because the 'General layout' menu uses alphabetic sorting, and it functionally works better if the spoof target selector appears below the 'Spoof app version' UI switch -->
|
||||
<string name="revanced_spoof_app_version_target_title">Spoof app version target</string>
|
||||
<!-- 'RYD' is 'Return YouTube Dislike' -->
|
||||
@@ -1085,6 +1088,19 @@
|
||||
<string name="revanced_slide_to_seek_summary_on">Slide to seek is enabled</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">Slide to seek is not enabled</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Spoof client</string>
|
||||
<string name="revanced_spoof_client_screen_summary">Spoof the client to prevent playback issues</string>
|
||||
<string name="revanced_spoof_client_title">Spoof client</string>
|
||||
<string name="revanced_spoof_client_summary_on">Client is spoofed</string>
|
||||
<string name="revanced_spoof_client_summary_off">Client is not spoofed\n\nVideo playback may not work</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">Turning off this setting may cause video playback issues.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Spoof client to iOS</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">Client is currently spoofed to iOS\n\nSide effects include:\n• No HDR video\n• Speed menu is missing\n• Watch history may not work\n• Live streams cannot play as audio only\n• Live streams not available on older devices</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">Client is currently spoofed to Android VR\n\nSide effects include:\n• No HDR video\n• Kids videos do not playback\n• Paused videos can randomly resume</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">Spoof client thumbnails not available (API timed out)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">Spoof client thumbnails temporarily not available: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<string name="revanced_spoof_signature_verification_screen_title">Spoof app signature</string>
|
||||
@@ -1163,4 +1179,4 @@
|
||||
<string name="revanced_twitch_debug_summary_off">Debug logs are disabled</string>
|
||||
</patch>
|
||||
</app>
|
||||
</resources>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user