mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-07 01:51:27 +01:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfe3876cea | ||
|
|
3ad2c42a53 | ||
|
|
0d22fc2d2f | ||
|
|
6e6dbd0c1a | ||
|
|
4272fade4f | ||
|
|
2095e34db8 | ||
|
|
1483a9d8bb | ||
|
|
ea113f01a3 | ||
|
|
d4658c7056 | ||
|
|
a615717580 | ||
|
|
04db353154 | ||
|
|
7cb0312a9d | ||
|
|
5357ff2e48 | ||
|
|
62083ead98 | ||
|
|
6f04169117 | ||
|
|
cc1b283cb7 | ||
|
|
4597a74e32 | ||
|
|
3734545ca6 | ||
|
|
60ef90c745 | ||
|
|
ece4ac1a9e | ||
|
|
d6e17f948d | ||
|
|
9ab3bd0313 | ||
|
|
0f10888aa3 | ||
|
|
63c0e5dc84 | ||
|
|
41bc0222b9 | ||
|
|
71e4cc964b | ||
|
|
afc9886ebd | ||
|
|
de06d96ea0 | ||
|
|
1139f77cb9 | ||
|
|
5a801b1562 | ||
|
|
7f301090b9 | ||
|
|
28a687c605 | ||
|
|
9b74a08ae1 | ||
|
|
1177c41373 | ||
|
|
be4de62c8f | ||
|
|
528156aec9 | ||
|
|
e377ecf208 | ||
|
|
fa147bd6cc | ||
|
|
88211e28ca | ||
|
|
a4e3a97937 | ||
|
|
02bd807a27 | ||
|
|
a06e81ae39 | ||
|
|
a87d0bc440 | ||
|
|
a2b64f63e0 | ||
|
|
80ab1592c3 | ||
|
|
e17f476c46 | ||
|
|
bfa9abe4cf | ||
|
|
0e0118eaa6 | ||
|
|
7b6439b200 | ||
|
|
65e3b21d64 | ||
|
|
d90bcc3135 |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -19,10 +19,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup JDK
|
||||
uses: actions/setup-java@v2
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'adopt'
|
||||
distribution: 'temurin'
|
||||
cache: gradle
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v2
|
||||
|
||||
127
CHANGELOG.md
127
CHANGELOG.md
@@ -1,3 +1,130 @@
|
||||
## [2.111.3](https://github.com/revanced/revanced-patches/compare/v2.111.2...v2.111.3) (2022-11-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/litho-filter:** use correct type for switch case ([#1068](https://github.com/revanced/revanced-patches/issues/1068)) ([ab03511](https://github.com/revanced/revanced-patches/commit/ab03511e23d07c7c40b58eae5791fb2a798289de))
|
||||
|
||||
## [2.111.2](https://github.com/revanced/revanced-patches/compare/v2.111.1...v2.111.2) (2022-11-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/general-ads:** import correct compatibility annotation ([#1065](https://github.com/revanced/revanced-patches/issues/1065)) ([db2085c](https://github.com/revanced/revanced-patches/commit/db2085c217311a8b7d45a01c03c6162bc60a9298))
|
||||
|
||||
## [2.111.1](https://github.com/revanced/revanced-patches/compare/v2.111.0...v2.111.1) (2022-11-18)
|
||||
|
||||
# [2.111.0](https://github.com/revanced/revanced-patches/compare/v2.110.0...v2.111.0) (2022-11-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **iconpackstudio:** `unlock-pro` patch ([#1047](https://github.com/revanced/revanced-patches/issues/1047)) ([fcbca9c](https://github.com/revanced/revanced-patches/commit/fcbca9cf0ff3940c48df53a9e5e4d06d65f9a1b1))
|
||||
|
||||
# [2.110.0](https://github.com/revanced/revanced-patches/compare/v2.109.0...v2.110.0) (2022-11-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/debugging:** include by default & add option to debug on Android ([9d6d5b2](https://github.com/revanced/revanced-patches/commit/9d6d5b29227980aacb4c1331161afb3fa265bbe4))
|
||||
* **youtube/debugging:** use more suitable preference title ([d182351](https://github.com/revanced/revanced-patches/commit/d182351e789bcbfb7982774406449e8d973765b2))
|
||||
* **youtube/general-ads:** hide chapter teaser under videos ([9cf415a](https://github.com/revanced/revanced-patches/commit/9cf415a894ab5458134ef1cd5a4c5bf7579e592c))
|
||||
* **youtube/general-ads:** hide self sponsored cards ([b627d75](https://github.com/revanced/revanced-patches/commit/b627d751b49c228e52f7f9fb5d2bcacb9d243a64))
|
||||
* **youtube/general-ads:** hide shorts in search ([c01ba5c](https://github.com/revanced/revanced-patches/commit/c01ba5cbcc694f8c9ee83a4e9eb081cf5b45753c))
|
||||
|
||||
# [2.109.0](https://github.com/revanced/revanced-patches/compare/v2.108.0...v2.109.0) (2022-11-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **twitch:** `block-audio-ads` patch ([#1041](https://github.com/revanced/revanced-patches/issues/1041)) ([3419bae](https://github.com/revanced/revanced-patches/commit/3419baed489ce231f84b3e2d600cf123cdfa7ff7))
|
||||
* **twitch:** `block-video-ads` patch ([#1040](https://github.com/revanced/revanced-patches/issues/1040)) ([b47bf24](https://github.com/revanced/revanced-patches/commit/b47bf24d1b52cfa1883a942894a6216ae81b8325))
|
||||
|
||||
# [2.108.0](https://github.com/revanced/revanced-patches/compare/v2.107.0...v2.108.0) (2022-11-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **twitch:** `debug-mode` patch ([#1031](https://github.com/revanced/revanced-patches/issues/1031)) ([c514860](https://github.com/revanced/revanced-patches/commit/c514860bc4a46295b11f09df9ffc1c556b798eb3))
|
||||
|
||||
# [2.107.0](https://github.com/revanced/revanced-patches/compare/v2.106.1...v2.107.0) (2022-11-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **ticktick:** `unlock-themes` patch ([#1028](https://github.com/revanced/revanced-patches/issues/1028)) ([7f1fedc](https://github.com/revanced/revanced-patches/commit/7f1fedcddd4330a5f884b813a20f2f8e84e2c9da))
|
||||
* **twitch/show-deleted-messages:** `show-deleted-messages` patch ([#1030](https://github.com/revanced/revanced-patches/issues/1030)) ([7e6b453](https://github.com/revanced/revanced-patches/commit/7e6b4534013a03ddc7eb11a1f911fa0564372118))
|
||||
|
||||
## [2.106.1](https://github.com/revanced/revanced-patches/compare/v2.106.0...v2.106.1) (2022-11-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/custom-branding:** use high resolution icons ([#1018](https://github.com/revanced/revanced-patches/issues/1018)) ([1c9d1ac](https://github.com/revanced/revanced-patches/commit/1c9d1acf2b7aff4cd52d17009ff01246f74d2214))
|
||||
|
||||
# [2.106.0](https://github.com/revanced/revanced-patches/compare/v2.105.0...v2.106.0) (2022-11-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube:** `open-links-directly` patch ([#999](https://github.com/revanced/revanced-patches/issues/999)) ([bf85f62](https://github.com/revanced/revanced-patches/commit/bf85f62f30242f91bdaf53b44ae6a9a2b3b6e1b4))
|
||||
|
||||
# [2.105.0](https://github.com/revanced/revanced-patches/compare/v2.104.2...v2.105.0) (2022-11-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **nyx:** `unlock-pro` patch ([#1004](https://github.com/revanced/revanced-patches/issues/1004)) ([9dd8239](https://github.com/revanced/revanced-patches/commit/9dd82391f3f97247224e09e0143b2272a3d47053))
|
||||
|
||||
## [2.104.2](https://github.com/revanced/revanced-patches/compare/v2.104.1...v2.104.2) (2022-11-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/hide-endscreen-cards:** restore functionality ([#993](https://github.com/revanced/revanced-patches/issues/993)) ([eb1bae2](https://github.com/revanced/revanced-patches/commit/eb1bae2c55e65ad29030dce6746a18662dd0fe25))
|
||||
|
||||
## [2.104.1](https://github.com/revanced/revanced-patches/compare/v2.104.0...v2.104.1) (2022-11-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/general-ads:** incorrect description for info panels ([77b029e](https://github.com/revanced/revanced-patches/commit/77b029e82e481a13516b1c8a888c42817507cdea))
|
||||
* **youtube/hide-info-cards:** remove initial popup of info-cards ([#992](https://github.com/revanced/revanced-patches/issues/992)) ([19f3f03](https://github.com/revanced/revanced-patches/commit/19f3f038585c313a969adf3d4095a60ab4c83ede))
|
||||
|
||||
# [2.104.0](https://github.com/revanced/revanced-patches/compare/v2.103.0...v2.104.0) (2022-11-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **hexeditor:** `disable-ads` patch ([#973](https://github.com/revanced/revanced-patches/issues/973)) ([a48e5fd](https://github.com/revanced/revanced-patches/commit/a48e5fd50dcf9ee061ffd5c5ed0b997067f40652))
|
||||
|
||||
# [2.103.0](https://github.com/revanced/revanced-patches/compare/v2.102.1...v2.103.0) (2022-11-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* apply multiple changes from integrations, refactor package structure, class names and implementations ([e756fac](https://github.com/revanced/revanced-patches/commit/e756face362e4abf2c7b17afa536feed9b0cd631))
|
||||
* **youtube/video-information:** use correct compatibility annotation ([b42e048](https://github.com/revanced/revanced-patches/commit/b42e04884bb9a60c3df30b668bfba55b1cf8eaa4))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **debugging:** simplify patch name and description ([61762f7](https://github.com/revanced/revanced-patches/commit/61762f76c457f348ef599e146f3853e941d4c45c))
|
||||
|
||||
## [2.102.1](https://github.com/revanced/revanced-patches/compare/v2.102.0...v2.102.1) (2022-11-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* use original app name ([#977](https://github.com/revanced/revanced-patches/issues/977)) ([ffc3c08](https://github.com/revanced/revanced-patches/commit/ffc3c08d96734893121397d506a97bd50b06bc1d))
|
||||
|
||||
# [2.102.0](https://github.com/revanced/revanced-patches/compare/v2.101.0...v2.102.0) (2022-11-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube-music:** bump patches compatibility to v5.31.50 ([#962](https://github.com/revanced/revanced-patches/issues/962)) ([476fcc8](https://github.com/revanced/revanced-patches/commit/476fcc87ca0d33cfbf251e4307755f02ed8f8baa))
|
||||
|
||||
# [2.101.0](https://github.com/revanced/revanced-patches/compare/v2.100.3...v2.101.0) (2022-11-01)
|
||||
|
||||
|
||||
|
||||
73
README.md
73
README.md
@@ -4,6 +4,14 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
|
||||
> Looking for the JSON variant of this? [Click here](patches.json).
|
||||
|
||||
### 📦 `ginlemon.iconpackstudio`
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `unlock-pro` | Unlocks all pro features. | all |
|
||||
</details>
|
||||
|
||||
### 📦 `com.ss.android.ugc.trill`
|
||||
<details>
|
||||
|
||||
@@ -50,6 +58,14 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all |
|
||||
</details>
|
||||
|
||||
### 📦 `com.myprog.hexedit`
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `disable-ads` | Disables ads in HexEditor. | all |
|
||||
</details>
|
||||
|
||||
### 📦 `com.spotify.music`
|
||||
<details>
|
||||
|
||||
@@ -73,6 +89,7 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.43.36 |
|
||||
| `hide-create-button` | Hides the create button in the navigation bar. | 17.43.36 |
|
||||
| `disable-startup-shorts-player` | Disables playing YouTube Shorts when launching YouTube. | 17.43.36 |
|
||||
| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 17.43.36 |
|
||||
| `hide-cast-button` | Hides the cast button in the video player. | all |
|
||||
| `sponsorblock` | Integrate SponsorBlock. | 17.43.36 |
|
||||
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.43.36 |
|
||||
@@ -88,25 +105,26 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `hide-email-address` | Hides the email address in the account switcher. | 17.43.36 |
|
||||
| `tablet-mini-player` | Enables the tablet mini player layout. | 17.43.36 |
|
||||
| `hide-watermark` | Hides creator's watermarks on videos. | 17.43.36 |
|
||||
| `hide-info-cards` | Hides info-cards in videos. | 17.43.36 |
|
||||
| `hide-my-mix` | Hides mix playlists. | 17.43.36 |
|
||||
| `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all |
|
||||
| `premium-heading` | Shows premium branding on the home screen. | all |
|
||||
| `old-quality-layout` | Enables the original quality flyout menu. | 17.43.36 |
|
||||
| `general-ads` | Removes general ads. | 17.43.36 |
|
||||
| `video-ads` | Removes ads in the video player. | 17.43.36 |
|
||||
| `hide-infocard-suggestions` | Hides infocards in videos. | 17.43.36 |
|
||||
| `swipe-controls` | Adds volume and brightness swipe controls. | 17.43.36 |
|
||||
| `downloads` | Enables downloading music and videos from YouTube. | 17.43.36 |
|
||||
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.43.36 |
|
||||
| `settings` | Adds settings for ReVanced to YouTube. | all |
|
||||
| `open-links-directly` | Bypasses redirect links and allows opening links directly. | 17.43.36 |
|
||||
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 17.43.36 |
|
||||
| `custom-video-buffer` | Lets you change the buffers of videos. | 17.43.36 |
|
||||
| `debugging` | Adds debugging options. | all |
|
||||
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
|
||||
| `always-autorepeat` | Always repeats the playing video again. | 17.43.36 |
|
||||
| `enable-debugging` | Enables app debugging by patching the manifest file. | all |
|
||||
| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.43.36 |
|
||||
| `minimized-playback` | Enables minimized and background playback. | 17.43.36 |
|
||||
| `custom-playback-speed` | Adds more video playback speed options. | 17.43.36 |
|
||||
| `custom-video-speed` | Adds more video speed options. | 17.43.36 |
|
||||
| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 17.43.36 |
|
||||
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 17.43.36 |
|
||||
</details>
|
||||
|
||||
@@ -118,6 +136,25 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
|
||||
</details>
|
||||
|
||||
### 📦 `com.ticktick.task`
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `unlock-themes` | Unlocks all themes. | all |
|
||||
</details>
|
||||
|
||||
### 📦 `tv.twitch.android.app`
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `debug-mode` | Enables Twitch's internal debugging mode. | all |
|
||||
| `block-audio-ads` | Blocks audio ads in streams and VODs. | all |
|
||||
| `block-video-ads` | Blocks video ads in streams and VODs. | all |
|
||||
| `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | all |
|
||||
</details>
|
||||
|
||||
### 📦 `com.garzotto.pflotsh.ecmwf_a`
|
||||
<details>
|
||||
|
||||
@@ -131,16 +168,16 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | 5.29.52 |
|
||||
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.29.52 |
|
||||
| `minimized-playback-music` | Enables minimized playback on Kids music. | 5.29.52 |
|
||||
| `compact-header` | Hides the music category bar at the top of the homepage. | 5.29.52 |
|
||||
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.29.52 |
|
||||
| `music-video-ads` | Removes ads in the music player. | 5.29.52 |
|
||||
| `background-play` | Enables playing music in the background. | 5.29.52 |
|
||||
| `exclusive-audio-playback` | Enables the option to play music without video. | 5.29.52 |
|
||||
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.29.52 |
|
||||
| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.29.52 |
|
||||
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | 5.31.50 |
|
||||
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.31.50 |
|
||||
| `minimized-playback-music` | Enables minimized playback on Kids music. | 5.31.50 |
|
||||
| `compact-header` | Hides the music category bar at the top of the homepage. | 5.31.50 |
|
||||
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.31.50 |
|
||||
| `music-video-ads` | Removes ads in the music player. | 5.31.50 |
|
||||
| `background-play` | Enables playing music in the background. | 5.31.50 |
|
||||
| `exclusive-audio-playback` | Enables the option to play music without video. | 5.31.50 |
|
||||
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.31.50 |
|
||||
| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.31.50 |
|
||||
</details>
|
||||
|
||||
### 📦 `com.reddit.frontpage`
|
||||
@@ -152,6 +189,14 @@ The official Patch bundle provided by ReVanced and the community.
|
||||
| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | all |
|
||||
</details>
|
||||
|
||||
### 📦 `com.awedea.nyx`
|
||||
<details>
|
||||
|
||||
| 💊 Patch | 📜 Description | 🏹 Target Version |
|
||||
|:--------:|:--------------:|:-----------------:|
|
||||
| `unlock-pro` | Unlocks all pro features. | all |
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
## 📝 JSON Format
|
||||
|
||||
@@ -20,7 +20,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("app.revanced:revanced-patcher:6.0.0")
|
||||
implementation("app.revanced:revanced-patcher:6.0.2")
|
||||
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
||||
// Required for meta
|
||||
implementation("com.google.code.gson:gson:2.9.1")
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
kotlin.code.style = official
|
||||
version = 2.101.0
|
||||
version = 2.111.3
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -18,17 +18,6 @@ import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
||||
import org.w3c.dom.Node
|
||||
import java.nio.file.Files
|
||||
|
||||
// TODO: this method does not make sense here
|
||||
internal fun MutableMethodImplementation.injectHideCall(
|
||||
index: Int,
|
||||
register: Int
|
||||
) {
|
||||
this.addInstruction(
|
||||
index,
|
||||
"invoke-static { v$register }, Lapp/revanced/integrations/patches/HideHomeAdsPatch;->HideHomeAds(Landroid/view/View;)V".toInstruction()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* traverse the class hierarchy starting from the given root class
|
||||
*
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.hexeditor.ad.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[
|
||||
Package("com.myprog.hexedit")
|
||||
]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class HexEditorAdsCompatibility
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.hexeditor.ad.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility
|
||||
|
||||
@Name("ads-fingerprint-primary")
|
||||
@HexEditorAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
object PrimaryAdsFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("PreferencesHelper;") && methodDef.name == "isAdsDisabled"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,39 @@
|
||||
package app.revanced.patches.hexeditor.ad.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.removeInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility
|
||||
import app.revanced.patches.hexeditor.ad.fingerprints.PrimaryAdsFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("disable-ads")
|
||||
@Description("Disables ads in HexEditor.")
|
||||
@HexEditorAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
class HexEditorAdsPatch : BytecodePatch(
|
||||
listOf(
|
||||
PrimaryAdsFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val method = PrimaryAdsFingerprint.result!!.mutableMethod
|
||||
|
||||
method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.iconpackstudio.misc.pro.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("ginlemon.iconpackstudio")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class UnlockProCompatibility
|
||||
@@ -0,0 +1,14 @@
|
||||
package app.revanced.patches.iconpackstudio.misc.pro.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.iconpackstudio.misc.pro.annotations.UnlockProCompatibility
|
||||
|
||||
@Name("check-pro-fingerprint")
|
||||
@UnlockProCompatibility
|
||||
@Version("0.0.1")
|
||||
object CheckProFingerprint : MethodFingerprint(
|
||||
"Z",
|
||||
customFingerprint = { it.definingClass.endsWith("IPSPurchaseRepository;")}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
package app.revanced.patches.iconpackstudio.misc.pro.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.removeInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.iconpackstudio.misc.pro.annotations.UnlockProCompatibility
|
||||
import app.revanced.patches.iconpackstudio.misc.pro.fingerprints.CheckProFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("unlock-pro")
|
||||
@Description("Unlocks all pro features.")
|
||||
@UnlockProCompatibility
|
||||
@Version("0.0.1")
|
||||
class UnlockProPatch : BytecodePatch(
|
||||
listOf(
|
||||
CheckProFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val method = CheckProFingerprint.result!!.mutableMethod
|
||||
method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -10,7 +10,7 @@ import app.revanced.patcher.annotation.Package
|
||||
*/
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package app.revanced.patches.music.misc.microg.shared
|
||||
|
||||
object Constants {
|
||||
internal const val REVANCED_MUSIC_APP_NAME = "YouTube Music ReVanced"
|
||||
internal const val REVANCED_MUSIC_APP_NAME = "YT Music ReVanced"
|
||||
internal const val REVANCED_MUSIC_PACKAGE_NAME = "app.revanced.android.apps.youtube.music"
|
||||
internal const val MUSIC_PACKAGE_NAME = "com.google.android.apps.youtube.music"
|
||||
internal const val SPOOFED_PACKAGE_NAME = MUSIC_PACKAGE_NAME
|
||||
internal const val SPOOFED_PACKAGE_SIGNATURE = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52")
|
||||
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51", "5.21.52", "5.22.54", "5.23.50", "5.25.51", "5.25.52", "5.26.52", "5.27.51", "5.28.52", "5.29.52", "5.31.50")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.nyx.misc.pro.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.awedea.nyx")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class UnlockProCompatibility
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.nyx.misc.pro.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.nyx.misc.pro.annotations.UnlockProCompatibility
|
||||
|
||||
@Name("check-pro-fingerprint")
|
||||
@UnlockProCompatibility
|
||||
@Version("0.0.1")
|
||||
object CheckProFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("BillingManager;") && methodDef.name == "isProVersion"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
package app.revanced.patches.nyx.misc.pro.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.removeInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.nyx.misc.pro.annotations.UnlockProCompatibility
|
||||
import app.revanced.patches.nyx.misc.pro.fingerprints.CheckProFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("unlock-pro")
|
||||
@Description("Unlocks all pro features.")
|
||||
@UnlockProCompatibility
|
||||
@Version("0.0.1")
|
||||
class UnlockProPatch : BytecodePatch(
|
||||
listOf(
|
||||
CheckProFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val method = CheckProFingerprint.result!!.mutableMethod
|
||||
method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.ticktick.misc.themeunlock.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("com.ticktick.task")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class UnlockThemesCompatibility
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.ticktick.misc.themeunlock.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
|
||||
|
||||
@Name("check-locked-theme-fingerprint")
|
||||
@UnlockThemesCompatibility
|
||||
@Version("0.0.1")
|
||||
object CheckLockedThemesFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("Theme;") && methodDef.name == "isLockedTheme"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.ticktick.misc.themeunlock.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
|
||||
|
||||
@Name("set-theme-fingerprint")
|
||||
@UnlockThemesCompatibility
|
||||
@Version("0.0.1")
|
||||
object SetThemeFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("ThemePreviewActivity;") && methodDef.name == "lambda\$updateUserBtn\$1"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
package app.revanced.patches.ticktick.misc.themeunlock.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.removeInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
|
||||
import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.CheckLockedThemesFingerprint
|
||||
import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.SetThemeFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("unlock-themes")
|
||||
@Description("Unlocks all themes.")
|
||||
@UnlockThemesCompatibility
|
||||
@Version("0.0.1")
|
||||
class UnlockProPatch : BytecodePatch(
|
||||
listOf(
|
||||
CheckLockedThemesFingerprint,
|
||||
SetThemeFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val lockedThemesMethod = CheckLockedThemesFingerprint.result!!.mutableMethod
|
||||
lockedThemesMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
|
||||
val setThemeMethod = SetThemeFingerprint.result!!.mutableMethod
|
||||
setThemeMethod.removeInstructions(0, 9)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class AudioAdsCompatibility
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.twitch.ad.audio.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.ad.audio.annotations.AudioAdsCompatibility
|
||||
|
||||
@Name("audio-ads-presenter-play-fingerprint")
|
||||
@AudioAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
object AudioAdsPresenterPlayFingerprint : MethodFingerprint(
|
||||
customFingerprint = { method ->
|
||||
method.definingClass.endsWith("AudioAdsPlayerPresenter;") && method.name == "playAd"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,31 @@
|
||||
package app.revanced.patches.twitch.ad.audio.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.twitch.ad.audio.annotations.AudioAdsCompatibility
|
||||
import app.revanced.patches.twitch.ad.audio.fingerprints.AudioAdsPresenterPlayFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("block-audio-ads")
|
||||
@Description("Blocks audio ads in streams and VODs.")
|
||||
@AudioAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
class AudioAdsPatch : BytecodePatch(
|
||||
listOf(AudioAdsPresenterPlayFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
// Block playAds call
|
||||
with(AudioAdsPresenterPlayFingerprint.result!!) {
|
||||
mutableMethod.addInstruction(0, "return-void")
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class VideoAdsCompatibility
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.twitch.ad.video.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||
|
||||
@Name("ads-manager-play-fingerprint")
|
||||
@VideoAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
object AdsManagerFingerprint : MethodFingerprint(
|
||||
customFingerprint = { method ->
|
||||
method.definingClass.endsWith("AdsManagerImpl;") && method.name == "playAds"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
package app.revanced.patches.twitch.ad.video.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
@Name("check-ad-eligibility-fingerprint")
|
||||
@VideoAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
object CheckAdEligibilityLambdaFingerprint : MethodFingerprint(
|
||||
"L",
|
||||
AccessFlags.PRIVATE or AccessFlags.FINAL or AccessFlags.STATIC,
|
||||
listOf("L", "L", "L"),
|
||||
customFingerprint = { method ->
|
||||
method.definingClass.endsWith("AdEligibilityFetcher;") &&
|
||||
method.name.contains("shouldRequestAd")
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.twitch.ad.video.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||
|
||||
@Name("content-config-show-ads-fingerprint")
|
||||
@VideoAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
object ContentConfigShowAdsFingerprint : MethodFingerprint(
|
||||
customFingerprint = { method ->
|
||||
method.definingClass.endsWith("ContentConfigData;") && method.name == "getShowAds"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,60 @@
|
||||
package app.revanced.patches.twitch.ad.video.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.twitch.ad.video.annotations.VideoAdsCompatibility
|
||||
import app.revanced.patches.twitch.ad.video.fingerprints.AdsManagerFingerprint
|
||||
import app.revanced.patches.twitch.ad.video.fingerprints.CheckAdEligibilityLambdaFingerprint
|
||||
import app.revanced.patches.twitch.ad.video.fingerprints.ContentConfigShowAdsFingerprint
|
||||
|
||||
@Patch
|
||||
@Name("block-video-ads")
|
||||
@Description("Blocks video ads in streams and VODs.")
|
||||
@VideoAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
class VideoAdsPatch : BytecodePatch(
|
||||
listOf(
|
||||
ContentConfigShowAdsFingerprint,
|
||||
AdsManagerFingerprint,
|
||||
CheckAdEligibilityLambdaFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
// Pretend our player is ineligible for all ads
|
||||
with(CheckAdEligibilityLambdaFingerprint.result!!) {
|
||||
mutableMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0
|
||||
invoke-static {v0}, Lio/reactivex/Single;->just(Ljava/lang/Object;)Lio/reactivex/Single;
|
||||
move-result-object p0
|
||||
return-object p0
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// Spoof showAds JSON field
|
||||
with(ContentConfigShowAdsFingerprint.result!!) {
|
||||
mutableMethod.addInstructions(0, """
|
||||
const/4 v0, 0
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// Block playAds call
|
||||
with(AdsManagerFingerprint.result!!) {
|
||||
mutableMethod.addInstruction(0, "return-void")
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class ShowDeletedMessagesCompatibility
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package app.revanced.patches.twitch.chat.antidelete.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
@Name("deleted-msg-span-ctor-fingerprint")
|
||||
@ShowDeletedMessagesCompatibility
|
||||
@Version("0.0.1")
|
||||
object DeletedMessageClickableSpanCtorFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("DeletedMessageClickableSpan;")
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.twitch.chat.antidelete.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
||||
|
||||
@Name("has-mod-access-fingerprint")
|
||||
@ShowDeletedMessagesCompatibility
|
||||
@Version("0.0.1")
|
||||
object SetHasModAccessFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("DeletedMessageClickableSpan;") && methodDef.name == "setHasModAccess"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,45 @@
|
||||
package app.revanced.patches.twitch.chat.antidelete.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.*
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
|
||||
import app.revanced.patches.twitch.chat.antidelete.fingerprints.*
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction10x
|
||||
|
||||
@Patch
|
||||
@Name("show-deleted-messages")
|
||||
@Description("Shows deleted chat messages behind a clickable spoiler.")
|
||||
@ShowDeletedMessagesCompatibility
|
||||
@Version("0.0.1")
|
||||
class ShowDeletedMessagesPatch : BytecodePatch(
|
||||
listOf(
|
||||
SetHasModAccessFingerprint,
|
||||
DeletedMessageClickableSpanCtorFingerprint,
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
// Force set hasModAccess member to true in constructor
|
||||
with(DeletedMessageClickableSpanCtorFingerprint.result!!.mutableMethod) {
|
||||
addInstructions(
|
||||
implementation!!.instructions.lastIndex, /* place in front of return-void */
|
||||
"""
|
||||
const/4 v0, 1
|
||||
iput-boolean v0, p0, $definingClass->hasModAccess:Z
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// Disable setHasModAccess setter
|
||||
with(SetHasModAccessFingerprint.result!!.mutableMethod.implementation!!) {
|
||||
addInstruction(0, BuilderInstruction10x(Opcode.RETURN_VOID))
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.twitch.debug.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility([Package("tv.twitch.android.app")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class DebugModeCompatibility
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.twitch.debug.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||
|
||||
@Name("is-debug-config-enabled-fingerprint")
|
||||
@DebugModeCompatibility
|
||||
@Version("0.0.1")
|
||||
object IsDebugConfigEnabledFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "isDebugConfigEnabled"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.twitch.debug.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||
|
||||
@Name("is-om-verification-enabled-fingerprint")
|
||||
@DebugModeCompatibility
|
||||
@Version("0.0.1")
|
||||
object IsOmVerificationEnabledFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "isOmVerificationEnabled"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.twitch.debug.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||
|
||||
@Name("should-show-debug-options-fingerprint")
|
||||
@DebugModeCompatibility
|
||||
@Version("0.0.1")
|
||||
object ShouldShowDebugOptionsFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.definingClass.endsWith("BuildConfigUtil;") && methodDef.name == "shouldShowDebugOptions"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,49 @@
|
||||
package app.revanced.patches.twitch.debug.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.twitch.debug.annotations.DebugModeCompatibility
|
||||
import app.revanced.patches.twitch.debug.fingerprints.IsDebugConfigEnabledFingerprint
|
||||
import app.revanced.patches.twitch.debug.fingerprints.IsOmVerificationEnabledFingerprint
|
||||
import app.revanced.patches.twitch.debug.fingerprints.ShouldShowDebugOptionsFingerprint
|
||||
|
||||
@Patch(false)
|
||||
@Name("debug-mode")
|
||||
@Description("Enables Twitch's internal debugging mode.")
|
||||
@DebugModeCompatibility
|
||||
@Version("0.0.1")
|
||||
class DebugModePatch : BytecodePatch(
|
||||
listOf(
|
||||
IsDebugConfigEnabledFingerprint,
|
||||
IsOmVerificationEnabledFingerprint,
|
||||
ShouldShowDebugOptionsFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
listOf(
|
||||
IsDebugConfigEnabledFingerprint,
|
||||
IsOmVerificationEnabledFingerprint,
|
||||
ShouldShowDebugOptionsFingerprint
|
||||
).forEach {
|
||||
with(it.result!!) {
|
||||
with(mutableMethod) {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package app.revanced.patches.youtube.ad.general.bytecode.extensions
|
||||
|
||||
import app.revanced.patcher.extensions.softCompareTo
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
|
||||
import org.jf.dexlib2.iface.Method
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.reference.FieldReference
|
||||
import org.jf.dexlib2.iface.reference.MethodReference
|
||||
import org.jf.dexlib2.iface.reference.Reference
|
||||
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
||||
|
||||
internal object MethodExtensions {
|
||||
internal fun MutableClass.findMutableMethodOf(
|
||||
method: Method
|
||||
) = this.methods.first {
|
||||
it.softCompareTo(
|
||||
ImmutableMethodReference(
|
||||
method.definingClass, method.name, method.parameters, method.returnType
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
internal inline fun <reified T : Reference> Instruction.toDescriptor(): String {
|
||||
val reference = (this as ReferenceInstruction).reference
|
||||
return when (T::class) {
|
||||
MethodReference::class -> {
|
||||
val methodReference = reference as MethodReference
|
||||
"${methodReference.definingClass}->${methodReference.name}(${
|
||||
methodReference.parameterTypes.joinToString(
|
||||
""
|
||||
) { it }
|
||||
})${methodReference.returnType}"
|
||||
}
|
||||
|
||||
FieldReference::class -> {
|
||||
val fieldReference = reference as FieldReference
|
||||
"${fieldReference.definingClass}->${fieldReference.name}:${fieldReference.type}"
|
||||
}
|
||||
|
||||
else -> throw PatchResultError("Unsupported reference type")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,383 +0,0 @@
|
||||
package app.revanced.patches.youtube.ad.general.bytecode.patch
|
||||
|
||||
import app.revanced.extensions.injectHideCall
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
||||
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.findMutableMethodOf
|
||||
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.toDescriptor
|
||||
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralResourceAdsPatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction10x
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import org.jf.dexlib2.iface.reference.FieldReference
|
||||
import org.jf.dexlib2.iface.reference.MethodReference
|
||||
import org.jf.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Patch
|
||||
@DependsOn([ResourceMappingResourcePatch::class, IntegrationsPatch::class, SettingsPatch::class, GeneralResourceAdsPatch::class])
|
||||
@Name("general-ads")
|
||||
@Description("Removes general ads.")
|
||||
@GeneralAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
class GeneralBytecodeAdsPatch : BytecodePatch() {
|
||||
// a constant used by litho
|
||||
private val lithoConstant = 0xaed2868
|
||||
|
||||
// list of resource names to get the id of
|
||||
private val resourceIds = arrayOf(
|
||||
"ad_attribution",
|
||||
"reel_multiple_items_shelf",
|
||||
"info_cards_drawer_header",
|
||||
"endscreen_element_layout_video",
|
||||
"endscreen_element_layout_circle",
|
||||
"endscreen_element_layout_icon",
|
||||
"promoted_video_item_land",
|
||||
"promoted_video_item_full_bleed",
|
||||
).map { name ->
|
||||
ResourceMappingResourcePatch.resourceMappings.single { it.name == name }.id
|
||||
}
|
||||
|
||||
private val stringReferences = arrayOf(
|
||||
"Claiming to use more elements than provided",
|
||||
"loadVideo() called on LocalDirector in wrong state",
|
||||
"LoggingProperties are not in proto format"
|
||||
)
|
||||
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.ADS.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_home_ads_removal",
|
||||
StringResource("revanced_home_ads_removal_title", "Remove home ads"),
|
||||
true,
|
||||
StringResource("revanced_home_ads_removal_summary_on", "Home ads are hidden"),
|
||||
StringResource("revanced_home_ads_removal_summary_off", "Home ads are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_ad_removal",
|
||||
StringResource("revanced_adremover_ad_removal_enabled_title", "Remove general ads"),
|
||||
true,
|
||||
StringResource("revanced_adremover_ad_removal_enabled_summary_on", "General ads are hidden"),
|
||||
StringResource("revanced_adremover_ad_removal_enabled_summary_off", "General ads are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_merchandise",
|
||||
StringResource("revanced_adremover_merchandise_enabled_title", "Remove merchandise banners"),
|
||||
true,
|
||||
StringResource("revanced_adremover_merchandise_enabled_summary_on", "Merchandise banners are hidden"),
|
||||
StringResource("revanced_adremover_merchandise_enabled_summary_off", "Merchandise banners are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_community_posts_removal",
|
||||
StringResource("revanced_adremover_community_posts_enabled_title", "Remove community posts"),
|
||||
false,
|
||||
StringResource("revanced_adremover_community_posts_enabled_summary_on", "Community posts are hidden"),
|
||||
StringResource("revanced_adremover_community_posts_enabled_summary_off", "Community posts are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_compact_banner_removal",
|
||||
StringResource("revanced_adremover_compact_banner_enabled_title", "Remove compact banners"),
|
||||
true,
|
||||
StringResource("revanced_adremover_compact_banner_enabled_summary_on", "Compact banners are hidden"),
|
||||
StringResource("revanced_adremover_compact_banner_enabled_summary_off", "Compact banners are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_movie",
|
||||
StringResource("revanced_adremover_movie_enabled_title", "Remove movies section"),
|
||||
true,
|
||||
StringResource("revanced_adremover_movie_enabled_summary_on", "Movies section is hidden"),
|
||||
StringResource("revanced_adremover_movie_enabled_summary_off", "Movies section is shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_feed_survey",
|
||||
StringResource("revanced_adremover_feed_survey_enabled_title", "Remove feed surveys"),
|
||||
true,
|
||||
StringResource("revanced_adremover_feed_survey_enabled_summary_on", "Feed surveys are hidden"),
|
||||
StringResource("revanced_adremover_feed_survey_enabled_summary_off", "Feed surveys are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_shorts_shelf",
|
||||
StringResource("revanced_adremover_shorts_shelf_enabled_title", "Remove shorts shelf"),
|
||||
true,
|
||||
StringResource("revanced_adremover_shorts_shelf_enabled_summary_on", "Shorts shelves are hidden"),
|
||||
StringResource("revanced_adremover_shorts_shelf_enabled_summary_off", "Shorts shelves are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_community_guidelines",
|
||||
StringResource("revanced_adremover_community_guidelines_enabled_title", "Remove community guidelines"),
|
||||
true,
|
||||
StringResource("revanced_adremover_community_guidelines_enabled_summary_on", "Community guidelines are hidden"),
|
||||
StringResource("revanced_adremover_community_guidelines_enabled_summary_off", "Community guidelines are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_emergency_box_removal",
|
||||
StringResource("revanced_adremover_emergency_box_enabled_title", "Remove emergency boxes"),
|
||||
true,
|
||||
StringResource("revanced_adremover_emergency_box_enabled_summary_on", "Emergency boxes are hidden"),
|
||||
StringResource("revanced_adremover_emergency_box_enabled_summary_off", "Emergency boxes are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_info_panel",
|
||||
StringResource("revanced_adremover_info_panel_enabled_title", "Remove info panels"),
|
||||
true,
|
||||
StringResource("revanced_adremover_info_panel_enabled_summary_on", "Merchandise banners are hidden"),
|
||||
StringResource("revanced_adremover_info_panel_enabled_summary_off", "Merchandise banners are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_medical_panel",
|
||||
StringResource("revanced_adremover_medical_panel_enabled_title", "Remove medical panels"),
|
||||
true,
|
||||
StringResource("revanced_adremover_medical_panel_enabled_summary_on", "Medical panels are hidden"),
|
||||
StringResource("revanced_adremover_medical_panel_enabled_summary_off", "Medical panels are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_paid_content",
|
||||
StringResource("revanced_adremover_paid_content_enabled_title", "Remove paid content"),
|
||||
true,
|
||||
StringResource("revanced_adremover_paid_content_enabled_summary_on", "Paid content is hidden"),
|
||||
StringResource("revanced_adremover_paid_content_enabled_summary_off", "Paid content is shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_hide_suggestions",
|
||||
StringResource("revanced_adremover_hide_suggestions_enabled_title", "Hide suggestions"),
|
||||
true,
|
||||
StringResource("revanced_adremover_hide_suggestions_enabled_summary_on", "Suggestions are hidden"),
|
||||
StringResource("revanced_adremover_hide_suggestions_enabled_summary_off", "Suggestions are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_hide_latest_posts",
|
||||
StringResource("revanced_adremover_hide_latest_posts_enabled_title", "Hide latest posts"),
|
||||
true,
|
||||
StringResource("revanced_adremover_hide_latest_posts_enabled_summary_on", "Latest posts are hidden"),
|
||||
StringResource("revanced_adremover_hide_latest_posts_enabled_summary_off", "Latest posts are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_hide_channel_guidelines",
|
||||
StringResource("revanced_adremover_hide_channel_guidelines_enabled_title", "Hide channel guidelines"),
|
||||
true,
|
||||
StringResource("revanced_adremover_hide_channel_guidelines_enabled_summary_on", "Channel guidelines are hidden"),
|
||||
StringResource("revanced_adremover_hide_channel_guidelines_enabled_summary_off", "Channel guidelines are shown")
|
||||
),
|
||||
)
|
||||
|
||||
// iterating through all classes is expensive
|
||||
for (classDef in context.classes) {
|
||||
var mutableClass: MutableClass? = null
|
||||
|
||||
method@ for (method in classDef.methods) {
|
||||
var mutableMethod: MutableMethod? = null
|
||||
|
||||
if (method.implementation == null) continue@method
|
||||
|
||||
val instructions = method.implementation!!.instructions
|
||||
instructions.forEachIndexed { index, instruction ->
|
||||
when (instruction.opcode) {
|
||||
Opcode.CONST -> {
|
||||
// TODO: find a way to de-duplicate code.
|
||||
// The issue is we need to save mutableClass and mutableMethod to the existing fields
|
||||
when ((instruction as Instruction31i).wideLiteral) {
|
||||
resourceIds[0] -> { // general ads
|
||||
// and is followed by an instruction with the mnemonic INVOKE_VIRTUAL
|
||||
val insertIndex = index + 1
|
||||
val invokeInstruction = instructions.elementAt(insertIndex)
|
||||
if (invokeInstruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
|
||||
|
||||
// create proxied method, make sure to not re-resolve() the current class
|
||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
||||
if (mutableMethod == null) mutableMethod =
|
||||
mutableClass!!.findMutableMethodOf(method)
|
||||
|
||||
// insert hide call to hide the view corresponding to the resource
|
||||
val viewRegister = (invokeInstruction as Instruction35c).registerC
|
||||
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
|
||||
|
||||
}
|
||||
|
||||
resourceIds[1] -> { // reel ads
|
||||
// and is followed by an instruction at insertIndex with the mnemonic IPUT_OBJECT
|
||||
val insertIndex = index + 4
|
||||
val iPutInstruction = instructions.elementAt(insertIndex)
|
||||
if (iPutInstruction.opcode != Opcode.IPUT_OBJECT) return@forEachIndexed
|
||||
|
||||
// create proxied method, make sure to not re-resolve() the current class
|
||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
||||
if (mutableMethod == null) mutableMethod =
|
||||
mutableClass!!.findMutableMethodOf(method)
|
||||
|
||||
val viewRegister = (iPutInstruction as Instruction22c).registerA
|
||||
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
|
||||
}
|
||||
|
||||
resourceIds[2] -> { // info cards ads
|
||||
// and is followed by an instruction with the mnemonic INVOKE_VIRTUAL
|
||||
val removeIndex = index - 1
|
||||
val invokeInstruction = instructions.elementAt(removeIndex)
|
||||
if (invokeInstruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
|
||||
|
||||
// create proxied method, make sure to not re-resolve() the current class
|
||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
||||
if (mutableMethod == null) mutableMethod =
|
||||
mutableClass!!.findMutableMethodOf(method)
|
||||
|
||||
//ToDo: Add Settings toggle for whatever this is
|
||||
mutableMethod!!.implementation!!.removeInstruction(removeIndex)
|
||||
}
|
||||
|
||||
resourceIds[3], resourceIds[4], resourceIds[5] -> { // end screen ads
|
||||
// and is followed by an instruction with the mnemonic IPUT_OBJECT
|
||||
val insertIndex = index + 7
|
||||
val invokeInstruction = instructions.elementAt(insertIndex)
|
||||
if (invokeInstruction.opcode != Opcode.IPUT_OBJECT) return@forEachIndexed
|
||||
|
||||
// create proxied method, make sure to not re-resolve() the current class
|
||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
||||
if (mutableMethod == null) mutableMethod =
|
||||
mutableClass!!.findMutableMethodOf(method)
|
||||
|
||||
// TODO: dynamically get registers
|
||||
mutableMethod!!.addInstructions(
|
||||
insertIndex, """
|
||||
const/16 v1, 0x8
|
||||
invoke-virtual {v0,v1}, Landroid/widget/FrameLayout;->setVisibility(I)V
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
resourceIds[6] -> {
|
||||
// and is followed by an instruction with the mnemonic INVOKE_DIRECT
|
||||
val insertIndex = index + 3
|
||||
val invokeInstruction = instructions.elementAt(insertIndex)
|
||||
if (invokeInstruction.opcode != Opcode.INVOKE_DIRECT) return@forEachIndexed
|
||||
|
||||
// create proxied method, make sure to not re-resolve() the current class
|
||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
||||
if (mutableMethod == null) mutableMethod =
|
||||
mutableClass!!.findMutableMethodOf(method)
|
||||
|
||||
// insert hide call to hide the view corresponding to the resource
|
||||
val viewRegister = (invokeInstruction as Instruction35c).registerE
|
||||
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
|
||||
}
|
||||
|
||||
resourceIds[7] -> {
|
||||
// TODO, go to class, hide the inflated view
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Opcode.CONST_STRING -> {
|
||||
when (((instruction as Instruction21c).reference as StringReference).string) {
|
||||
stringReferences[0] -> {
|
||||
val stringInstruction = instructions.elementAt(3)
|
||||
if (stringInstruction.opcode == Opcode.CONST_STRING) return@forEachIndexed
|
||||
|
||||
// create proxied method, make sure to not re-resolve() the current class
|
||||
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
|
||||
if (mutableMethod == null) mutableMethod =
|
||||
mutableClass!!.findMutableMethodOf(method)
|
||||
|
||||
// return the method
|
||||
val insertIndex = 1 // after super constructor
|
||||
//ToDo: Add setting here
|
||||
mutableMethod!!.implementation!!.addInstruction(
|
||||
insertIndex, BuilderInstruction10x(Opcode.RETURN_VOID)
|
||||
)
|
||||
}
|
||||
|
||||
stringReferences[1] -> {
|
||||
// TODO: migrate video ads patch to here if necessary
|
||||
}
|
||||
|
||||
stringReferences[2] -> { // Litho ads
|
||||
val proxy = context.proxy(classDef)
|
||||
val proxiedClass = proxy.mutableClass
|
||||
|
||||
val lithoMethod = getLithoMethod(proxiedClass)
|
||||
?: return PatchResultError("Could not find required Litho method to patch.")
|
||||
|
||||
val instructionWithNeededDescriptor =
|
||||
lithoMethod.implementation!!.instructions.indexOfFirst {
|
||||
it.opcode == Opcode.INVOKE_STATIC_RANGE
|
||||
}
|
||||
|
||||
// get required descriptors
|
||||
val createEmptyComponentDescriptor =
|
||||
lithoMethod.instruction(instructionWithNeededDescriptor)
|
||||
.toDescriptor<MethodReference>()
|
||||
val emptyComponentFieldDescriptor =
|
||||
lithoMethod.instruction(instructionWithNeededDescriptor + 2)
|
||||
.toDescriptor<FieldReference>()
|
||||
|
||||
val pathBuilderAnchorFingerprint = object : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_16,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IPUT_OBJECT
|
||||
)
|
||||
) {}
|
||||
|
||||
val pathBuilderScanResult = pathBuilderAnchorFingerprint.also {
|
||||
it.resolve(context, lithoMethod, classDef)
|
||||
}.result!!.scanResult.patternScanResult!!
|
||||
|
||||
val clobberedRegister =
|
||||
(lithoMethod.instruction(pathBuilderScanResult.startIndex) as OneRegisterInstruction).registerA
|
||||
|
||||
val insertIndex = pathBuilderScanResult.endIndex + 1
|
||||
lithoMethod.addInstructions(
|
||||
insertIndex, // right after setting the component.pathBuilder field,
|
||||
"""
|
||||
invoke-static {v5, v2}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z
|
||||
move-result v$clobberedRegister
|
||||
if-eqz v$clobberedRegister, :not_an_ad
|
||||
move-object/from16 v2, p1
|
||||
invoke-static {v2}, $createEmptyComponentDescriptor
|
||||
move-result-object v0
|
||||
iget-object v0, v0, $emptyComponentFieldDescriptor
|
||||
return-object v0
|
||||
""",
|
||||
listOf(ExternalLabel("not_an_ad", lithoMethod.instruction(insertIndex)))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else -> return@forEachIndexed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private fun getLithoMethod(mutableClass: MutableClass) = mutableClass.methods.firstOrNull {
|
||||
it.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode == Opcode.CONST && (instruction as Instruction31i).narrowLiteral == lithoConstant
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package app.revanced.patches.youtube.ad.general.bytecode.utils
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.iface.MethodImplementation
|
||||
import org.jf.dexlib2.immutable.ImmutableMethod
|
||||
import org.jf.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
internal object MethodUtils {
|
||||
internal fun createMutableMethod(
|
||||
definingClass: String, name: String, returnType: String, parameter: String, implementation: MethodImplementation
|
||||
) = ImmutableMethod(
|
||||
definingClass, name, listOf(
|
||||
ImmutableMethodParameter(
|
||||
parameter, null, null
|
||||
)
|
||||
), returnType, AccessFlags.PRIVATE or AccessFlags.STATIC, null, null, implementation
|
||||
).toMutable()
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package app.revanced.patches.youtube.ad.general.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
||||
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
|
||||
@Patch
|
||||
@DependsOn(dependencies = [FixLocaleConfigErrorPatch::class, LithoFilterPatch::class, SettingsPatch::class])
|
||||
@Name("general-ads")
|
||||
@Description("Removes general ads.")
|
||||
@GeneralAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
class GeneralAdsPatch : ResourcePatch {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.ADS.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_home_ads_removal",
|
||||
StringResource("revanced_home_ads_removal_title", "Remove home ads"),
|
||||
true,
|
||||
StringResource("revanced_home_ads_removal_summary_on", "Home ads are hidden"),
|
||||
StringResource("revanced_home_ads_removal_summary_off", "Home ads are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_ad_removal",
|
||||
StringResource("revanced_adremover_ad_removal_enabled_title", "Remove general ads"),
|
||||
true,
|
||||
StringResource("revanced_adremover_ad_removal_enabled_summary_on", "General ads are hidden"),
|
||||
StringResource("revanced_adremover_ad_removal_enabled_summary_off", "General ads are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_merchandise",
|
||||
StringResource("revanced_adremover_merchandise_enabled_title", "Remove merchandise banners"),
|
||||
true,
|
||||
StringResource("revanced_adremover_merchandise_enabled_summary_on", "Merchandise banners are hidden"),
|
||||
StringResource("revanced_adremover_merchandise_enabled_summary_off", "Merchandise banners are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_community_posts_removal",
|
||||
StringResource("revanced_adremover_community_posts_enabled_title", "Remove community posts"),
|
||||
false,
|
||||
StringResource("revanced_adremover_community_posts_enabled_summary_on", "Community posts are hidden"),
|
||||
StringResource("revanced_adremover_community_posts_enabled_summary_off", "Community posts are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_compact_banner_removal",
|
||||
StringResource("revanced_adremover_compact_banner_enabled_title", "Remove compact banners"),
|
||||
true,
|
||||
StringResource("revanced_adremover_compact_banner_enabled_summary_on", "Compact banners are hidden"),
|
||||
StringResource("revanced_adremover_compact_banner_enabled_summary_off", "Compact banners are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_movie",
|
||||
StringResource("revanced_adremover_movie_enabled_title", "Remove movies section"),
|
||||
true,
|
||||
StringResource("revanced_adremover_movie_enabled_summary_on", "Movies section is hidden"),
|
||||
StringResource("revanced_adremover_movie_enabled_summary_off", "Movies section is shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_feed_survey",
|
||||
StringResource("revanced_adremover_feed_survey_enabled_title", "Remove feed surveys"),
|
||||
true,
|
||||
StringResource("revanced_adremover_feed_survey_enabled_summary_on", "Feed surveys are hidden"),
|
||||
StringResource("revanced_adremover_feed_survey_enabled_summary_off", "Feed surveys are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_shorts",
|
||||
StringResource("revanced_adremover_shorts_enabled_title", "Remove shorts"),
|
||||
true,
|
||||
StringResource("revanced_adremover_shorts_enabled_summary_on", "Shorts are hidden"),
|
||||
StringResource("revanced_adremover_shorts_enabled_summary_off", "Shorts are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_community_guidelines",
|
||||
StringResource("revanced_adremover_community_guidelines_enabled_title", "Remove community guidelines"),
|
||||
true,
|
||||
StringResource(
|
||||
"revanced_adremover_community_guidelines_enabled_summary_on",
|
||||
"Community guidelines are hidden"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_adremover_community_guidelines_enabled_summary_off",
|
||||
"Community guidelines are shown"
|
||||
)
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_emergency_box_removal",
|
||||
StringResource("revanced_adremover_emergency_box_enabled_title", "Remove emergency boxes"),
|
||||
true,
|
||||
StringResource("revanced_adremover_emergency_box_enabled_summary_on", "Emergency boxes are hidden"),
|
||||
StringResource("revanced_adremover_emergency_box_enabled_summary_off", "Emergency boxes are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_info_panel",
|
||||
StringResource("revanced_adremover_info_panel_enabled_title", "Remove info panels"),
|
||||
true,
|
||||
StringResource("revanced_adremover_info_panel_enabled_summary_on", "Info panels are hidden"),
|
||||
StringResource("revanced_adremover_info_panel_enabled_summary_off", "Info panels are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_medical_panel",
|
||||
StringResource("revanced_adremover_medical_panel_enabled_title", "Remove medical panels"),
|
||||
true,
|
||||
StringResource("revanced_adremover_medical_panel_enabled_summary_on", "Medical panels are hidden"),
|
||||
StringResource("revanced_adremover_medical_panel_enabled_summary_off", "Medical panels are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_paid_content",
|
||||
StringResource("revanced_adremover_paid_content_enabled_title", "Remove paid content"),
|
||||
true,
|
||||
StringResource("revanced_adremover_paid_content_enabled_summary_on", "Paid content is hidden"),
|
||||
StringResource("revanced_adremover_paid_content_enabled_summary_off", "Paid content is shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_hide_suggestions",
|
||||
StringResource("revanced_adremover_hide_suggestions_enabled_title", "Hide suggestions"),
|
||||
true,
|
||||
StringResource("revanced_adremover_hide_suggestions_enabled_summary_on", "Suggestions are hidden"),
|
||||
StringResource("revanced_adremover_hide_suggestions_enabled_summary_off", "Suggestions are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_hide_latest_posts",
|
||||
StringResource("revanced_adremover_hide_latest_posts_enabled_title", "Hide latest posts"),
|
||||
true,
|
||||
StringResource("revanced_adremover_hide_latest_posts_enabled_summary_on", "Latest posts are hidden"),
|
||||
StringResource("revanced_adremover_hide_latest_posts_enabled_summary_off", "Latest posts are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_hide_channel_guidelines",
|
||||
StringResource("revanced_adremover_hide_channel_guidelines_enabled_title", "Hide channel guidelines"),
|
||||
true,
|
||||
StringResource(
|
||||
"revanced_adremover_hide_channel_guidelines_enabled_summary_on",
|
||||
"Channel guidelines are hidden"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_adremover_hide_channel_guidelines_enabled_summary_off",
|
||||
"Channel guidelines are shown"
|
||||
)
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_self_sponsor",
|
||||
StringResource("revanced_adremover_self_sponsor_enabled_title", "Hide self sponsored cards"),
|
||||
true,
|
||||
StringResource("revanced_adremover_self_sponsor_enabled_summary_on", "Self sponsored cards are hidden"),
|
||||
StringResource("revanced_adremover_self_sponsor_enabled_summary_off", "Self sponsored cards are shown")
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_adremover_chapter_teaser",
|
||||
StringResource(
|
||||
"revanced_adremover_chapter_teaser_enabled_title",
|
||||
"Hide chapter teaser under videos"
|
||||
),
|
||||
true,
|
||||
StringResource(
|
||||
"revanced_adremover_chapter_teaser_enabled_summary_on",
|
||||
"Chapter teasers are hidden"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_adremover_chapter_teaser_enabled_summary_off",
|
||||
"Chapter teasers are shown"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package app.revanced.patches.youtube.ad.general.resource.patch
|
||||
|
||||
import app.revanced.extensions.doRecursively
|
||||
import app.revanced.extensions.startsWithAny
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
||||
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@DependsOn(dependencies = [FixLocaleConfigErrorPatch::class])
|
||||
@Name("general-resource-ads")
|
||||
@Description("Patch to remove general ads in resources.")
|
||||
@GeneralAdsCompatibility
|
||||
@Version("0.0.1")
|
||||
class GeneralResourceAdsPatch : ResourcePatch {
|
||||
// list of resource file names which need to be hidden
|
||||
private val resourceFileNames = arrayOf(
|
||||
"compact_promoted_",
|
||||
"promoted_video_",
|
||||
)
|
||||
|
||||
// the attributes to change the value of
|
||||
private val replacements = arrayOf(
|
||||
"height",
|
||||
"width",
|
||||
"marginTop",
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
context.forEach {
|
||||
if (!it.name.startsWithAny(*resourceFileNames)) return@forEach
|
||||
|
||||
// for each file in the "layouts" directory replace all necessary attributes content
|
||||
context.xmlEditor[it.absolutePath].use { editor ->
|
||||
editor.file.doRecursively { node ->
|
||||
replacements.forEach replacement@{ replacement ->
|
||||
if (node !is Element) return@replacement
|
||||
|
||||
node.getAttributeNode("android:layout_$replacement")?.let { attribute ->
|
||||
attribute.textContent = "1.0dip"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
@Name("hide-infocard-suggestions-fingerprint")
|
||||
@FuzzyPatternScanMethod(2)
|
||||
@HideInfocardSuggestionsCompatibility
|
||||
@Version("0.0.1")
|
||||
object HideInfocardSuggestionsFingerprint : MethodFingerprint(
|
||||
"Ljava/lang/Boolean;",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf("vibrator")
|
||||
)
|
||||
@@ -1,19 +0,0 @@
|
||||
package app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
@Name("hide-infocard-suggestions-parent-fingerprint")
|
||||
@FuzzyPatternScanMethod(2)
|
||||
@HideInfocardSuggestionsCompatibility
|
||||
@Version("0.0.1")
|
||||
object HideInfocardSuggestionsParentFingerprint : MethodFingerprint(
|
||||
"Ljava/lang/String;",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf("player_overlay_info_card_teaser"),
|
||||
)
|
||||
@@ -1,67 +0,0 @@
|
||||
package app.revanced.patches.youtube.ad.infocardsuggestions.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
||||
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsFingerprint
|
||||
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsParentFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
|
||||
|
||||
@Patch
|
||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||
@Name("hide-infocard-suggestions")
|
||||
@Description("Hides infocards in videos.")
|
||||
@HideInfocardSuggestionsCompatibility
|
||||
@Version("0.0.1")
|
||||
class HideInfocardSuggestionsPatch : BytecodePatch(
|
||||
listOf(
|
||||
HideInfocardSuggestionsParentFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.ADS.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_info_cards_enabled",
|
||||
StringResource("revanced_info_cards_enabled_title", "Show info-cards"),
|
||||
false,
|
||||
StringResource("revanced_info_cards_enabled_summary_on", "Info-cards are shown"),
|
||||
StringResource("revanced_info_cards_enabled_summary_off", "Info-cards are hidden")
|
||||
)
|
||||
)
|
||||
|
||||
val parentResult = HideInfocardSuggestionsParentFingerprint.result
|
||||
?: return PatchResultError("Parent fingerprint not resolved!")
|
||||
|
||||
|
||||
HideInfocardSuggestionsFingerprint.resolve(context, parentResult.classDef)
|
||||
val result = HideInfocardSuggestionsFingerprint.result
|
||||
?: return PatchResultError("Required parent method could not be found.")
|
||||
|
||||
val method = result.mutableMethod
|
||||
val implementation = method.implementation
|
||||
?: return PatchResultError("Implementation not found.")
|
||||
|
||||
val index = implementation.instructions.indexOfFirst { ((it as? BuilderInstruction35c)?.reference.toString() == "Landroid/view/View;->setVisibility(I)V") }
|
||||
|
||||
method.replaceInstruction(index, """
|
||||
invoke-static {p1}, Lapp/revanced/integrations/patches/HideInfoCardSuggestionsPatch;->hideInfoCardSuggestions(Landroid/view/View;)V
|
||||
""")
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
|
||||
import app.revanced.patches.youtube.ad.video.fingerprints.LoadVideoAdsFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playback.patch.FixPlaybackPatch
|
||||
import app.revanced.patches.youtube.misc.playback.fix.patch.FixPlaybackPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
|
||||
@@ -12,7 +12,7 @@ import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.interaction.downloads.annotation.DownloadsCompatibility
|
||||
import app.revanced.patches.youtube.interaction.downloads.resource.patch.DownloadsResourcePatch
|
||||
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
|
||||
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
||||
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
||||
|
||||
@Patch
|
||||
@Name("downloads")
|
||||
|
||||
@@ -9,7 +9,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.ad.general.bytecode.patch.GeneralBytecodeAdsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.layout.buttons.annotations.HideButtonsCompatibility
|
||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
@@ -18,7 +18,7 @@ import app.revanced.patches.youtube.misc.settings.framework.components.impl.Stri
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
|
||||
@Patch
|
||||
@DependsOn([ResourceMappingResourcePatch::class, GeneralBytecodeAdsPatch::class])
|
||||
@DependsOn([ResourceMappingResourcePatch::class, LithoFilterPatch::class])
|
||||
@Name("hide-video-buttons")
|
||||
@Description("Adds options to hide action buttons under a video.")
|
||||
@HideButtonsCompatibility
|
||||
|
||||
@@ -13,16 +13,10 @@ import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.ad.general.bytecode.patch.GeneralBytecodeAdsPatch
|
||||
import app.revanced.patches.youtube.layout.comments.annotations.CommentsCompatibility
|
||||
import app.revanced.patches.youtube.layout.comments.bytecode.fingerprints.ShortsCommentsButtonFingerprint
|
||||
import app.revanced.patches.youtube.layout.comments.resource.patch.CommentsResourcePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.ad.general.bytecode.patch.GeneralBytecodeAdsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.layout.buttons.annotations.HideArtistCardCompatibility
|
||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.misc.settings.framework.components.impl.Stri
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
|
||||
@Patch
|
||||
@DependsOn([ResourceMappingResourcePatch::class, GeneralBytecodeAdsPatch::class])
|
||||
@DependsOn([ResourceMappingResourcePatch::class, LithoFilterPatch::class])
|
||||
@Name("hide-artist-card")
|
||||
@Description("Hides the artist card below the searchbar.")
|
||||
@HideArtistCardCompatibility
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package app.revanced.patches.youtube.misc.quality.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class DefaultVideoQualityCompatibility
|
||||
package app.revanced.patches.youtube.layout.hideendscreencards.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class HideEndscreenCardsCompatibility
|
||||
@@ -0,0 +1,28 @@
|
||||
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
|
||||
@Name("layout-circle-fingerprint")
|
||||
@HideEndscreenCardsCompatibility
|
||||
@Version("0.0.1")
|
||||
object LayoutCircleFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.CONST,
|
||||
Opcode.CONST_4,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutCircle
|
||||
} == true
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
|
||||
@Name("layout-icon-fingerprint")
|
||||
@HideEndscreenCardsCompatibility
|
||||
@Version("0.0.1")
|
||||
object LayoutIconFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_4,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutIcon
|
||||
} == true
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
|
||||
@Name("layout-video-fingerprint")
|
||||
@HideEndscreenCardsCompatibility
|
||||
@Version("0.0.1")
|
||||
object LayoutVideoFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.CONST,
|
||||
Opcode.CONST_4,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutVideo
|
||||
} == true
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,57 @@
|
||||
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.fingerprint.Fingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutCircleFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutIconFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutVideoFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
|
||||
|
||||
@Patch
|
||||
@DependsOn([IntegrationsPatch::class, HideEndscreenCardsResourcePatch::class])
|
||||
@Name("hide-endscreen-cards")
|
||||
@Description("Hides the suggested video cards at the end of a video in fullscreen.")
|
||||
@HideEndscreenCardsCompatibility
|
||||
@Version("0.0.1")
|
||||
class HideEndscreenCardsPatch : BytecodePatch(
|
||||
listOf(
|
||||
LayoutCircleFingerprint,
|
||||
LayoutIconFingerprint,
|
||||
LayoutVideoFingerprint,
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
fun MethodFingerprint.injectHideCall() {
|
||||
val layoutResult = result!!
|
||||
val layoutMethod = layoutResult.mutableMethod
|
||||
|
||||
val checkCastIndex = layoutResult.scanResult.patternScanResult!!.endIndex
|
||||
val viewRegister = (layoutMethod.instruction(checkCastIndex) as Instruction21c).registerA
|
||||
|
||||
layoutMethod.addInstruction(
|
||||
checkCastIndex + 1,
|
||||
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideEndscreenCardsPatch;->hideEndscreen(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
|
||||
listOf(LayoutCircleFingerprint, LayoutIconFingerprint, LayoutVideoFingerprint).forEach(MethodFingerprint::injectHideCall)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package app.revanced.patches.youtube.layout.hideendscreencards.resource.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
|
||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
|
||||
@Name("hide-endscreen-cards-resource-patch")
|
||||
@HideEndscreenCardsCompatibility
|
||||
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
|
||||
@Version("0.0.1")
|
||||
class HideEndscreenCardsResourcePatch : ResourcePatch {
|
||||
internal companion object {
|
||||
var layoutCircle: Long = -1
|
||||
var layoutIcon: Long = -1
|
||||
var layoutVideo: Long = -1
|
||||
}
|
||||
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_hide_endscreen_cards",
|
||||
StringResource("revanced_hide_endscreen_cards_title", "Hide end-screen cards"),
|
||||
true,
|
||||
StringResource("revanced_hide_endscreen_cards_summary_on", "End-screen cards are hidden"),
|
||||
StringResource("revanced_hide_endscreen_cards_summary_off", "End-screen cards are shown")
|
||||
),
|
||||
)
|
||||
|
||||
fun findEndscreenResourceId(name: String) = ResourceMappingResourcePatch.resourceMappings.single {
|
||||
it.type == "layout" && it.name == "endscreen_element_layout_$name"
|
||||
}.id
|
||||
|
||||
layoutCircle = findEndscreenResourceId("circle")
|
||||
layoutIcon = findEndscreenResourceId("icon")
|
||||
layoutVideo = findEndscreenResourceId("video")
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.ad.infocardsuggestions.annotations
|
||||
package app.revanced.patches.youtube.layout.hideinfocards.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
@@ -10,4 +10,4 @@ import app.revanced.patcher.annotation.Package
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class HideInfocardSuggestionsCompatibility
|
||||
internal annotation class HideInfocardsCompatibility
|
||||
@@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
@Name("infocards-incognito-fingerprint")
|
||||
@HideInfocardsCompatibility
|
||||
@Version("0.0.1")
|
||||
object InfocardsIncognitoFingerprint : MethodFingerprint(
|
||||
"Ljava/lang/Boolean;",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf("vibrator")
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
@Name("infocards-incognito-parent-fingerprint")
|
||||
@HideInfocardsCompatibility
|
||||
@Version("0.0.1")
|
||||
object InfocardsIncognitoParentFingerprint : MethodFingerprint(
|
||||
"Ljava/lang/String;",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf("player_overlay_info_card_teaser"),
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.resource.patch.HideInfocardsResourcePatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
|
||||
@Name("infocards-method-call-fingerprint")
|
||||
@HideInfocardsCompatibility
|
||||
@Version("0.0.1")
|
||||
object InfocardsMethodCallFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
(instruction as? WideLiteralInstruction)?.wideLiteral == HideInfocardsResourcePatch.drawerResourceId
|
||||
} == true
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,77 @@
|
||||
package app.revanced.patches.youtube.layout.hideinfocards.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
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.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsIncognitoFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsIncognitoParentFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsMethodCallFingerprint
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.resource.patch.HideInfocardsResourcePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
|
||||
|
||||
@Patch
|
||||
@DependsOn([IntegrationsPatch::class, HideInfocardsResourcePatch::class])
|
||||
@Name("hide-info-cards")
|
||||
@Description("Hides info-cards in videos.")
|
||||
@HideInfocardsCompatibility
|
||||
@Version("0.0.1")
|
||||
class HideInfocardsPatch : BytecodePatch(
|
||||
listOf(
|
||||
InfocardsIncognitoParentFingerprint,
|
||||
InfocardsMethodCallFingerprint,
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
with(InfocardsIncognitoFingerprint.also {
|
||||
it.resolve(context, InfocardsIncognitoParentFingerprint.result!!.classDef)
|
||||
}.result!!.mutableMethod) {
|
||||
val invokeInstructionIndex = implementation!!.instructions.indexOfFirst {
|
||||
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal &&
|
||||
((it as? BuilderInstruction35c)?.reference.toString() ==
|
||||
"Landroid/view/View;->setVisibility(I)V")
|
||||
}
|
||||
|
||||
replaceInstruction(
|
||||
invokeInstructionIndex,
|
||||
"invoke-static {v${(instruction(invokeInstructionIndex) as? BuilderInstruction35c)?.registerC}}," +
|
||||
" Lapp/revanced/integrations/patches/HideInfocardsPatch;->hideInfocardsIncognito(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
|
||||
with(InfocardsMethodCallFingerprint.result!!) {
|
||||
val hideInfocardsCallMethod = mutableMethod
|
||||
|
||||
val invokeInterfaceIndex = scanResult.patternScanResult!!.endIndex
|
||||
val toggleRegister = hideInfocardsCallMethod.implementation!!.registerCount - 1
|
||||
|
||||
hideInfocardsCallMethod.addInstructions(
|
||||
invokeInterfaceIndex, """
|
||||
invoke-static {}, Lapp/revanced/integrations/patches/HideInfocardsPatch;->hideInfocardsMethodCall()Z
|
||||
move-result v$toggleRegister
|
||||
if-nez v$toggleRegister, :hide_info_cards
|
||||
""",
|
||||
listOf(
|
||||
ExternalLabel(
|
||||
"hide_info_cards", hideInfocardsCallMethod.instruction(invokeInterfaceIndex + 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package app.revanced.patches.youtube.layout.hideinfocards.resource.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
|
||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
|
||||
@HideInfocardsCompatibility
|
||||
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
|
||||
@Version("0.0.1")
|
||||
class HideInfocardsResourcePatch : ResourcePatch {
|
||||
internal companion object {
|
||||
var drawerResourceId: Long = -1
|
||||
}
|
||||
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_hide_infocards",
|
||||
StringResource("revanced_hide_infocards_title", "Hide info-cards"),
|
||||
true,
|
||||
StringResource("revanced_hide_infocards_summary_on", "Info-cards are hidden"),
|
||||
StringResource("revanced_hide_infocards_summary_off", "Info-cards are shown")
|
||||
)
|
||||
)
|
||||
|
||||
drawerResourceId = ResourceMappingResourcePatch.resourceMappings.single {
|
||||
it.type == "id" && it.name == "info_cards_drawer_header"
|
||||
}.id
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class OldQualityLayoutPatch : BytecodePatch(
|
||||
// insert the integrations method
|
||||
method.addInstruction(
|
||||
listenerInvokeRegister, // insert the integrations instructions right before the listener
|
||||
"invoke-static { v$onItemClickViewRegister }, Lapp/revanced/integrations/patches/OldQualityLayoutPatch;->showOldQualityMenu(Landroid/widget/ListView;)V"
|
||||
"invoke-static { v$onItemClickViewRegister }, Lapp/revanced/integrations/patches/playback/quality/OldQualityLayoutPatch;->showOldQualityMenu(Landroid/widget/ListView;)V"
|
||||
)
|
||||
|
||||
return PatchResultSuccess()
|
||||
|
||||
@@ -18,7 +18,7 @@ import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.Retu
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.*
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch.ReturnYouTubeDislikeResourcePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
||||
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
||||
|
||||
@Patch
|
||||
@DependsOn([IntegrationsPatch::class, VideoIdPatch::class, ReturnYouTubeDislikeResourcePatch::class])
|
||||
|
||||
@@ -8,7 +8,6 @@ import app.revanced.patcher.data.toMethodWalker
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
@@ -23,9 +22,9 @@ import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.*
|
||||
import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
|
||||
import app.revanced.patches.youtube.misc.playercontroller.patch.PlayerControllerPatch
|
||||
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch
|
||||
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
||||
import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch
|
||||
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
||||
import org.jf.dexlib2.Opcode
|
||||
import org.jf.dexlib2.iface.instruction.*
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||
@@ -36,7 +35,7 @@ import org.jf.dexlib2.iface.reference.StringReference
|
||||
@Patch
|
||||
@DependsOn(
|
||||
dependencies = [
|
||||
PlayerControllerPatch::class, // updates video length and adds method to seek in video
|
||||
VideoInformationPatch::class, // updates video information and adds method to seek in video
|
||||
PlayerControlsBytecodePatch::class,
|
||||
IntegrationsPatch::class,
|
||||
SponsorBlockResourcePatch::class,
|
||||
@@ -49,9 +48,7 @@ import org.jf.dexlib2.iface.reference.StringReference
|
||||
@Version("0.0.1")
|
||||
class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
listOf(
|
||||
PlayerControllerSetTimeReferenceFingerprint,
|
||||
CreateVideoPlayerSeekbarFingerprint,
|
||||
VideoTimeFingerprint,
|
||||
NextGenWatchLayoutFingerprint,
|
||||
AppendTimeFingerprint,
|
||||
PlayerOverlaysLayoutInitFingerprint,
|
||||
@@ -59,36 +56,31 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
StartVideoInformerFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {/*
|
||||
Set current video time
|
||||
*/
|
||||
val referenceResult = PlayerControllerSetTimeReferenceFingerprint.result!!
|
||||
val playerControllerSetTimeMethod =
|
||||
context.toMethodWalker(referenceResult.method)
|
||||
.nextMethod(referenceResult.scanResult.patternScanResult!!.startIndex, true)
|
||||
.getMethod() as MutableMethod
|
||||
playerControllerSetTimeMethod.addInstruction(
|
||||
2,
|
||||
"invoke-static {p1, p2}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setCurrentVideoTime(J)V"
|
||||
)
|
||||
|
||||
private companion object {
|
||||
const val INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/sponsorblock/PlayerController;"
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
/*
|
||||
Set current video time high precision
|
||||
Hook the video time methods
|
||||
*/
|
||||
val constructorFingerprint =
|
||||
object : MethodFingerprint("V", null, listOf("J", "J", "J", "J", "I", "L"), null) {}
|
||||
constructorFingerprint.resolve(context, VideoTimeFingerprint.result!!.classDef)
|
||||
|
||||
val constructor = constructorFingerprint.result!!.mutableMethod
|
||||
constructor.addInstruction(
|
||||
0,
|
||||
"invoke-static {p1, p2}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setCurrentVideoTimeHighPrecision(J)V"
|
||||
)
|
||||
with(VideoInformationPatch) {
|
||||
videoTimeHook(
|
||||
INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR,
|
||||
"setVideoTime"
|
||||
)
|
||||
highPrecisionTimeHook(
|
||||
INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR,
|
||||
"setHighPrecisionVideoTime"
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
Set current video id
|
||||
*/
|
||||
VideoIdPatch.injectCall("Lapp/revanced/integrations/sponsorblock/PlayerController;->setCurrentVideoId(Ljava/lang/String;)V")
|
||||
VideoIdPatch.injectCall("$INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")
|
||||
|
||||
/*
|
||||
Seekbar drawing
|
||||
@@ -104,7 +96,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
if (instruction.opcode != Opcode.MOVE_OBJECT_FROM16) continue
|
||||
seekbarMethod.addInstruction(
|
||||
index + 1,
|
||||
"invoke-static {v0}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setSponsorBarRect(Ljava/lang/Object;)V"
|
||||
"invoke-static {v0}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V"
|
||||
)
|
||||
break
|
||||
}
|
||||
@@ -120,7 +112,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
// set the thickness of the segment
|
||||
seekbarMethod.addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static {v${invokeInstruction.registerC}}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setSponsorBarThickness(I)V"
|
||||
"invoke-static {v${invokeInstruction.registerC}}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V"
|
||||
)
|
||||
break
|
||||
}
|
||||
@@ -141,11 +133,11 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
// the reason for that is that we get the index, add instructions and then the offset would be wrong
|
||||
seekbarMethod.addInstruction(
|
||||
indexLeft + 1,
|
||||
"invoke-static {v$rectangleLeftRegister}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setSponsorBarAbsoluteLeft(Landroid/graphics/Rect;)V"
|
||||
"invoke-static {v$rectangleLeftRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteLeft(Landroid/graphics/Rect;)V"
|
||||
)
|
||||
seekbarMethod.addInstruction(
|
||||
indexRight + 1,
|
||||
"invoke-static {v$rectangleRightRegister}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setSponsorBarAbsoluteRight(Landroid/graphics/Rect;)V"
|
||||
"invoke-static {v$rectangleRightRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteRight(Landroid/graphics/Rect;)V"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -157,7 +149,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
}
|
||||
seekbarMethod.addInstruction(
|
||||
drawSegmentInstructionInsertIndex,
|
||||
"invoke-static {v$canvasInstance, v$centerY}, Lapp/revanced/integrations/sponsorblock/PlayerController;->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
|
||||
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -215,7 +207,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
val instanceRegister = 0
|
||||
NextGenWatchLayoutFingerprint.result!!.mutableMethod.addInstruction(
|
||||
3, // after super call
|
||||
"invoke-static/range {p$instanceRegister}, Lapp/revanced/integrations/sponsorblock/PlayerController;->addSkipSponsorView15(Landroid/view/View;)V"
|
||||
"invoke-static/range {p$instanceRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->addSkipSponsorView15(Landroid/view/View;)V"
|
||||
)
|
||||
|
||||
// append the new time to the player layout
|
||||
@@ -232,7 +224,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
)
|
||||
|
||||
// initialize the player controller
|
||||
PlayerControllerPatch.onCreateHook("Lapp/revanced/integrations/sponsorblock/PlayerController;", "initialize")
|
||||
VideoInformationPatch.onCreateHook(INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR, "initialize")
|
||||
|
||||
// initialize the sponsorblock view
|
||||
PlayerOverlaysLayoutInitFingerprint.result!!.mutableMethod.addInstruction(
|
||||
@@ -277,7 +269,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
startVideoInformerMethod.addInstructions(
|
||||
0, """
|
||||
const/4 v0, 0x0
|
||||
sput-boolean v0, Lapp/revanced/integrations/sponsorblock/PlayerController;->shorts_playing:Z
|
||||
sput-boolean v0, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->shorts_playing:Z
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -286,7 +278,7 @@ class SponsorBlockBytecodePatch : BytecodePatch(
|
||||
shortsPlayerConstructorMethod.addInstructions(
|
||||
0, """
|
||||
const/4 v0, 0x1
|
||||
sput-boolean v0, Lapp/revanced/integrations/sponsorblock/PlayerController;->shorts_playing:Z
|
||||
sput-boolean v0, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->shorts_playing:Z
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.misc.enabledebugging.annotations
|
||||
package app.revanced.patches.youtube.misc.debugging.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
@@ -6,4 +6,4 @@ import app.revanced.patcher.annotation.Package
|
||||
@Compatibility([Package("com.google.android.youtube")])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class EnableDebuggingCompatibility
|
||||
internal annotation class DebuggingCompatibility
|
||||
@@ -1,51 +1,60 @@
|
||||
package app.revanced.patches.youtube.misc.enabledebugging.patch
|
||||
package app.revanced.patches.youtube.misc.debugging.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patches.youtube.misc.enabledebugging.annotations.EnableDebuggingCompatibility
|
||||
import app.revanced.patches.youtube.misc.debugging.annotations.DebuggingCompatibility
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@Patch(false)
|
||||
@Name("enable-debugging")
|
||||
@Patch
|
||||
@Name("debugging")
|
||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||
@Description("Enables app debugging by patching the manifest file.")
|
||||
@EnableDebuggingCompatibility
|
||||
@Description("Adds debugging options.")
|
||||
@DebuggingCompatibility
|
||||
@Version("0.0.1")
|
||||
class EnableDebuggingPatch : ResourcePatch {
|
||||
class DebuggingPatch : ResourcePatch {
|
||||
override fun execute(context: ResourceContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_debug_enabled",
|
||||
StringResource("revanced_debug_title", "Debug"),
|
||||
StringResource("revanced_debug_title", "Debugging"),
|
||||
false,
|
||||
StringResource("revanced_debug_on", "Debug logs are enabled"),
|
||||
StringResource("revanced_debug_off", "Debug logs are disabled")
|
||||
)
|
||||
)
|
||||
|
||||
// create an xml editor instance
|
||||
context.xmlEditor["AndroidManifest.xml"].use { dom ->
|
||||
// get the application node
|
||||
val applicationNode = dom
|
||||
.file
|
||||
.getElementsByTagName("application")
|
||||
.item(0) as Element
|
||||
if (debuggable == true) {
|
||||
context.xmlEditor["AndroidManifest.xml"].use { dom ->
|
||||
val applicationNode = dom
|
||||
.file
|
||||
.getElementsByTagName("application")
|
||||
.item(0) as Element
|
||||
|
||||
// set application as debuggable
|
||||
applicationNode.setAttribute("android:debuggable", "true")
|
||||
// set application as debuggable
|
||||
applicationNode.setAttribute("android:debuggable", "true")
|
||||
}
|
||||
}
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
companion object : OptionsContainer() {
|
||||
var debuggable: Boolean? by option(
|
||||
PatchOption.BooleanOption(
|
||||
key = "debuggable",
|
||||
default = false,
|
||||
title = "App debugging",
|
||||
description = "Whether to make the app debuggable on Android.",
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.annotation
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class LithoFilterCompatibility
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("component-context-parser-fingerprint")
|
||||
@LithoFilterCompatibility
|
||||
@Version("0.0.1")
|
||||
object ComponentContextParserFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.GOTO,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.CONST_16,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.NEW_INSTANCE
|
||||
),
|
||||
strings = listOf("LoggingProperties are not in proto format")
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("empty-component-builder-fingerprint")
|
||||
@LithoFilterCompatibility
|
||||
@Version("0.0.1")
|
||||
object EmptyComponentBuilderFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC_RANGE
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,78 @@
|
||||
package app.revanced.patches.youtube.misc.litho.filter.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultError
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility
|
||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ComponentContextParserFingerprint
|
||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.EmptyComponentBuilderFingerprint
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.reference.FieldReference
|
||||
import org.jf.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@DependsOn([IntegrationsPatch::class])
|
||||
@Description("Hooks the method which parses the bytes into a ComponentContext to filter components.")
|
||||
@LithoFilterCompatibility
|
||||
@Version("0.0.1")
|
||||
class LithoFilterPatch : BytecodePatch(
|
||||
listOf(ComponentContextParserFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
ComponentContextParserFingerprint.result?.let { result ->
|
||||
val builderMethodIndex = EmptyComponentBuilderFingerprint
|
||||
.also { it.resolve(context, result.mutableMethod, result.mutableClass) }
|
||||
.let { it.result!!.scanResult.patternScanResult!!.startIndex }
|
||||
|
||||
val emptyComponentFieldIndex = builderMethodIndex + 2
|
||||
|
||||
with(result.mutableMethod) {
|
||||
val insertHookIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
val clobberedRegister = (instruction(insertHookIndex - 3) as OneRegisterInstruction).registerA
|
||||
|
||||
val builderMethodDescriptor = instruction(builderMethodIndex).toDescriptor()
|
||||
val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).toDescriptor()
|
||||
|
||||
addInstructions(
|
||||
insertHookIndex, // right after setting the component.pathBuilder field,
|
||||
"""
|
||||
invoke-static {v5, v2}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z
|
||||
move-result v$clobberedRegister
|
||||
if-eqz v$clobberedRegister, :not_an_ad
|
||||
move-object/from16 v2, p1
|
||||
invoke-static {v2}, $builderMethodDescriptor
|
||||
move-result-object v0
|
||||
iget-object v0, v0, $emptyComponentFieldDescriptor
|
||||
return-object v0
|
||||
""",
|
||||
listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex)))
|
||||
)
|
||||
}
|
||||
} ?: return PatchResultError("Could not find the method to hook.")
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
fun Instruction.toDescriptor() = when (val reference = (this as? ReferenceInstruction)?.reference) {
|
||||
is MethodReference -> "${reference.definingClass}->${reference.name}(${
|
||||
reference.parameterTypes.joinToString(
|
||||
""
|
||||
) { it }
|
||||
})${reference.returnType}"
|
||||
is FieldReference -> "${reference.definingClass}->${reference.name}:${reference.type}"
|
||||
else -> throw PatchResultError("Unsupported reference type")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.misc.openlinksdirectly.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf("17.34.36", "17.36.39", "17.38.36", "17.39.35" , "17.40.41", "17.42.35", "17.43.36")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class OpenLinksDirectlyCompatibility
|
||||
@@ -0,0 +1,23 @@
|
||||
package app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.openlinksdirectly.annotations.OpenLinksDirectlyCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("open-links-directly-primary-fingerprint")
|
||||
@OpenLinksDirectlyCompatibility
|
||||
@Version("0.0.1")
|
||||
object OpenLinksDirectlyFingerprintPrimary : MethodFingerprint(
|
||||
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.SGET
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
package app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.openlinksdirectly.annotations.OpenLinksDirectlyCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("open-links-directly-secondary-fingerprint")
|
||||
@OpenLinksDirectlyCompatibility
|
||||
@Version("0.0.1")
|
||||
object OpenLinksDirectlyFingerprintSecondary : MethodFingerprint(
|
||||
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.RETURN_OBJECT,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.CONST_STRING
|
||||
),
|
||||
strings = listOf("Uri must have an absolute scheme")
|
||||
)
|
||||
@@ -0,0 +1,72 @@
|
||||
package app.revanced.patches.youtube.misc.openlinksdirectly.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.openlinksdirectly.annotations.OpenLinksDirectlyCompatibility
|
||||
import app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints.OpenLinksDirectlyFingerprintPrimary
|
||||
import app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints.OpenLinksDirectlyFingerprintSecondary
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction11x
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||
|
||||
@Patch
|
||||
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
|
||||
@Name("open-links-directly")
|
||||
@Description("Bypasses redirect links and allows opening links directly.")
|
||||
@OpenLinksDirectlyCompatibility
|
||||
@Version("0.0.1")
|
||||
class OpenLinksDirectlyPatch : BytecodePatch(
|
||||
listOf(
|
||||
OpenLinksDirectlyFingerprintPrimary, OpenLinksDirectlyFingerprintSecondary
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_uri_redirect",
|
||||
StringResource("revanced_uri_redirect_title", "Open links directly"),
|
||||
true,
|
||||
StringResource("revanced_uri_redirect_summary_on", "Enabled"),
|
||||
StringResource("revanced_uri_redirect_summary_off", "Disabled")
|
||||
)
|
||||
)
|
||||
|
||||
OpenLinksDirectlyFingerprintPrimary.hookUriParser(true)
|
||||
OpenLinksDirectlyFingerprintSecondary.hookUriParser(false)
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
fun MethodFingerprint.hookUriParser(isPrimaryFingerprint: Boolean) {
|
||||
fun getTargetRegister(instruction: Instruction): Int {
|
||||
if (isPrimaryFingerprint) return (instruction as Instruction35c).registerC
|
||||
return (instruction as Instruction11x).registerA
|
||||
}
|
||||
with(this.result!!) {
|
||||
val startIndex = scanResult.patternScanResult!!.startIndex
|
||||
val instruction = method.implementation!!.instructions.elementAt(startIndex + 1)
|
||||
val insertIndex = if (isPrimaryFingerprint) 1 else 2
|
||||
val targetRegister = getTargetRegister(instruction)
|
||||
|
||||
mutableMethod.addInstructions(
|
||||
startIndex + insertIndex, """
|
||||
invoke-static {v$targetRegister}, Lapp/revanced/integrations/patches/OpenLinksDirectlyPatch;->parseRedirectUri(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.misc.playback.annotations
|
||||
package app.revanced.patches.youtube.misc.playback.fix.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.misc.playback.patch
|
||||
package app.revanced.patches.youtube.misc.playback.fix.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
@@ -9,16 +9,16 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playback.annotations.FixPlaybackCompatibility
|
||||
import app.revanced.patches.youtube.misc.playercontroller.patch.PlayerControllerPatch
|
||||
import app.revanced.patches.youtube.misc.playback.fix.annotations.FixPlaybackCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
|
||||
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
|
||||
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
||||
|
||||
@DependsOn([
|
||||
IntegrationsPatch::class,
|
||||
PlayerControllerPatch::class, // updates video length and adds method to seek in video, necessary for this patch
|
||||
VideoInformationPatch::class, // updates video length and adds method to seek in video, necessary for this patch
|
||||
SettingsPatch::class,
|
||||
VideoIdPatch::class
|
||||
])
|
||||
@@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.misc.playercontroller.annotation
|
||||
package app.revanced.patches.youtube.misc.video.information.annotation
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
@@ -10,4 +10,4 @@ import app.revanced.patcher.annotation.Package
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class PlayerControllerCompatibility
|
||||
internal annotation class VideoInformationCompatibility
|
||||
@@ -1,13 +1,14 @@
|
||||
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||
package app.revanced.patches.youtube.misc.video.information.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility
|
||||
|
||||
@Name("create-video-player-seekbar-fingerprint")
|
||||
@SponsorBlockCompatibility
|
||||
@VideoInformationCompatibility
|
||||
@Version("0.0.1")
|
||||
object CreateVideoPlayerSeekbarFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
@@ -1,15 +1,15 @@
|
||||
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
|
||||
package app.revanced.patches.youtube.misc.video.information.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("player-controller-set-time-reference-fingerprint")
|
||||
|
||||
@SponsorBlockCompatibility
|
||||
@VideoInformationCompatibility
|
||||
@Version("0.0.1")
|
||||
object PlayerControllerSetTimeReferenceFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE, Opcode.IGET_OBJECT),
|
||||
@@ -1,14 +1,14 @@
|
||||
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||
package app.revanced.patches.youtube.misc.video.information.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility
|
||||
|
||||
@Name("player-init-fingerprint")
|
||||
|
||||
@SponsorBlockCompatibility
|
||||
@VideoInformationCompatibility
|
||||
@Version("0.0.1")
|
||||
object PlayerInitFingerprint : MethodFingerprint(
|
||||
strings = listOf(
|
||||
@@ -1,14 +1,14 @@
|
||||
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||
package app.revanced.patches.youtube.misc.video.information.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility
|
||||
|
||||
@Name("seek-fingerprint")
|
||||
|
||||
@SponsorBlockCompatibility
|
||||
@VideoInformationCompatibility
|
||||
@Version("0.0.1")
|
||||
object SeekFingerprint : MethodFingerprint(
|
||||
strings = listOf("Attempting to seek during an ad")
|
||||
@@ -1,15 +1,15 @@
|
||||
package app.revanced.patches.youtube.misc.playercontroller.fingerprint
|
||||
package app.revanced.patches.youtube.misc.video.information.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-length-fingerprint")
|
||||
|
||||
@SponsorBlockCompatibility
|
||||
@VideoInformationCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoLengthFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
@@ -1,13 +1,14 @@
|
||||
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
|
||||
package app.revanced.patches.youtube.misc.video.information.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility
|
||||
|
||||
@Name("video-time-fingerprint")
|
||||
@SponsorBlockCompatibility
|
||||
@VideoInformationCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoTimeFingerprint : MethodFingerprint(
|
||||
strings = listOf("MedialibPlayerTimeInfo{currentPositionMillis=")
|
||||
@@ -1,13 +1,15 @@
|
||||
package app.revanced.patches.youtube.misc.playercontroller.patch
|
||||
package app.revanced.patches.youtube.misc.video.information.patch
|
||||
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.data.toMethodWalker
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
@@ -16,11 +18,8 @@ import app.revanced.patcher.patch.annotations.DependsOn
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playercontroller.annotation.PlayerControllerCompatibility
|
||||
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.CreateVideoPlayerSeekbarFingerprint
|
||||
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.PlayerInitFingerprint
|
||||
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.SeekFingerprint
|
||||
import app.revanced.patches.youtube.misc.playercontroller.fingerprint.VideoLengthFingerprint
|
||||
import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility
|
||||
import app.revanced.patches.youtube.misc.video.information.fingerprints.*
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.builder.MutableMethodImplementation
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@@ -28,15 +27,17 @@ import org.jf.dexlib2.immutable.ImmutableMethod
|
||||
import org.jf.dexlib2.immutable.ImmutableMethodParameter
|
||||
import org.jf.dexlib2.util.MethodUtil
|
||||
|
||||
@Name("player-controller-hook")
|
||||
@Description("Hooks the player controller")
|
||||
@PlayerControllerCompatibility
|
||||
@Name("video-information")
|
||||
@Description("Hooks YouTube to get information about the current playing video.")
|
||||
@VideoInformationCompatibility
|
||||
@Version("0.0.1")
|
||||
@DependsOn([IntegrationsPatch::class])
|
||||
class PlayerControllerPatch : BytecodePatch(
|
||||
class VideoInformationPatch : BytecodePatch(
|
||||
listOf(
|
||||
PlayerInitFingerprint,
|
||||
CreateVideoPlayerSeekbarFingerprint
|
||||
CreateVideoPlayerSeekbarFingerprint,
|
||||
PlayerControllerSetTimeReferenceFingerprint,
|
||||
VideoTimeFingerprint,
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
@@ -88,29 +89,90 @@ class PlayerControllerPatch : BytecodePatch(
|
||||
|
||||
addInstruction(
|
||||
videoLengthMethodResult.scanResult.patternScanResult!!.endIndex,
|
||||
"invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, $INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentVideoLength(J)V"
|
||||
"invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, $INTEGRATIONS_CLASS_DESCRIPTOR->setVideoLength(J)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Set the video time method
|
||||
*/
|
||||
with(PlayerControllerSetTimeReferenceFingerprint.result!!) {
|
||||
timeMethod = context.toMethodWalker(method)
|
||||
.nextMethod(scanResult.patternScanResult!!.startIndex, true)
|
||||
.getMethod() as MutableMethod
|
||||
}
|
||||
|
||||
/*
|
||||
Set the high precision video time method
|
||||
*/
|
||||
highPrecisionTimeMethod =
|
||||
(object : MethodFingerprint("V", null, listOf("J", "J", "J", "J", "I", "L"), null) {}).also {
|
||||
it.resolve(context, VideoTimeFingerprint.result!!.classDef)
|
||||
}.result!!.mutableMethod
|
||||
|
||||
/*
|
||||
Hook the methods which set the time
|
||||
*/
|
||||
highPrecisionTimeHook(INTEGRATIONS_CLASS_DESCRIPTOR, "setVideoTime")
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/PlayerControllerPatch;"
|
||||
private const val INSERT_INDEX = 4
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/VideoInformation;"
|
||||
|
||||
private lateinit var playerInitMethod: MutableMethod
|
||||
private lateinit var timeMethod: MutableMethod
|
||||
private lateinit var highPrecisionTimeMethod: MutableMethod
|
||||
|
||||
private fun MutableMethod.insert(insert: InsertIndex, register: String, descriptor: String) =
|
||||
addInstruction(insert.index, "invoke-static { $register }, $descriptor")
|
||||
|
||||
private fun MutableMethod.insertTimeHook(insert: InsertIndex, descriptor: String) =
|
||||
insert(insert, "p1, p2", descriptor)
|
||||
|
||||
/**
|
||||
* Hook the player controller.
|
||||
*
|
||||
* @param targetMethodClass The descriptor for the static method to invoke when the player controller is created.
|
||||
* @param targetMethodClass The descriptor for the class to invoke when the player controller is created.
|
||||
* @param targetMethodName The name of the static method to invoke when the player controller is created.
|
||||
*/
|
||||
internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) =
|
||||
playerInitMethod.addInstruction(
|
||||
INSERT_INDEX,
|
||||
"invoke-static { v0 }, $targetMethodClass->$targetMethodName(Ljava/lang/Object;)V"
|
||||
playerInitMethod.insert(
|
||||
InsertIndex.CREATE,
|
||||
"v0",
|
||||
"$targetMethodClass->$targetMethodName(Ljava/lang/Object;)V"
|
||||
)
|
||||
|
||||
/**
|
||||
* Hook the video time.
|
||||
*
|
||||
* @param targetMethodClass The descriptor for the static method to invoke when the player controller is created.
|
||||
* @param targetMethodName The name of the static method to invoke when the player controller is created.
|
||||
*/
|
||||
internal fun videoTimeHook(targetMethodClass: String, targetMethodName: String) =
|
||||
timeMethod.insertTimeHook(
|
||||
InsertIndex.TIME,
|
||||
"$targetMethodClass->$targetMethodName(J)V"
|
||||
)
|
||||
|
||||
/**
|
||||
* Hook the high precision video time.
|
||||
*
|
||||
* @param targetMethodClass The descriptor for the static method to invoke when the player controller is created.
|
||||
* @param targetMethodName The name of the static method to invoke when the player controller is created.
|
||||
*/
|
||||
internal fun highPrecisionTimeHook(targetMethodClass: String, targetMethodName: String) =
|
||||
highPrecisionTimeMethod.insertTimeHook(
|
||||
InsertIndex.HIGH_PRECISION_TIME,
|
||||
"$targetMethodClass->$targetMethodName(J)V"
|
||||
)
|
||||
|
||||
enum class InsertIndex(internal val index: Int) {
|
||||
CREATE(4),
|
||||
TIME(2),
|
||||
HIGH_PRECISION_TIME(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.misc.video.quality.annotations
|
||||
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
|
||||
)]
|
||||
)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class RememberVideoQualityCompatibility
|
||||
@@ -1,18 +1,18 @@
|
||||
package app.revanced.patches.youtube.misc.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.quality.annotations.DefaultVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-quality-reference-fingerprint")
|
||||
@DefaultVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoQualityReferenceFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
|
||||
Opcode.IPUT_OBJECT, Opcode.RETURN_VOID
|
||||
)
|
||||
package app.revanced.patches.youtube.misc.video.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.video.quality.annotations.RememberVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-quality-reference-fingerprint")
|
||||
@RememberVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoQualityReferenceFingerprint : MethodFingerprint(
|
||||
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
|
||||
Opcode.IPUT_OBJECT, Opcode.RETURN_VOID
|
||||
)
|
||||
)
|
||||
@@ -1,27 +1,27 @@
|
||||
|
||||
package app.revanced.patches.youtube.misc.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.quality.annotations.DefaultVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-quality-setter-fingerprint")
|
||||
@DefaultVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoQualitySetterFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf("[L", "I", "I", "Z", "I"),
|
||||
listOf(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
)
|
||||
|
||||
package app.revanced.patches.youtube.misc.video.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.video.quality.annotations.RememberVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-quality-setter-fingerprint")
|
||||
@RememberVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoQualitySetterFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf("[L", "I", "I", "Z", "I"),
|
||||
listOf(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
)
|
||||
)
|
||||
@@ -1,26 +1,26 @@
|
||||
|
||||
package app.revanced.patches.youtube.misc.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
import app.revanced.patches.youtube.misc.quality.annotations.DefaultVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-user-quality-change-fingerprint")
|
||||
@DefaultVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoUserQualityChangeFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf("L","L","I","J"),
|
||||
listOf(
|
||||
Opcode.MOVE,
|
||||
Opcode.MOVE_WIDE,
|
||||
Opcode.INVOKE_INTERFACE_RANGE,
|
||||
Opcode.RETURN_VOID
|
||||
)
|
||||
|
||||
package app.revanced.patches.youtube.misc.video.quality.fingerprints
|
||||
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
import app.revanced.patches.youtube.misc.video.quality.annotations.RememberVideoQualityCompatibility
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
@Name("video-user-quality-change-fingerprint")
|
||||
@RememberVideoQualityCompatibility
|
||||
@Version("0.0.1")
|
||||
object VideoUserQualityChangeFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
listOf("L","L","I","J"),
|
||||
listOf(
|
||||
Opcode.MOVE,
|
||||
Opcode.MOVE_WIDE,
|
||||
Opcode.INVOKE_INTERFACE_RANGE,
|
||||
Opcode.RETURN_VOID
|
||||
)
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user