Compare commits

..

6 Commits

Author SHA1 Message Date
semantic-release-bot
902754363c chore(release): 2.6.0-dev.2 [skip ci]
# [2.6.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.6.0-dev.1...v2.6.0-dev.2) (2022-07-02)

### Bug Fixes

* remove refreshing home screen not working ([42def27](42def27fa5))
2022-07-02 22:41:07 +00:00
oSumAtrIX
42def27fa5 fix: remove refreshing home screen not working 2022-07-03 00:39:27 +02:00
oSumAtrIX
7986c57a6f refactor: add package for fingerprints 2022-07-02 16:15:48 +02:00
semantic-release-bot
3de6790e9f chore(release): 2.6.0-dev.1 [skip ci]
# [2.6.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.1-dev.1...v2.6.0-dev.1) (2022-07-02)

### Features

* migrate to breaking changes of patcher ([c95c241](c95c241887))
2022-07-02 02:24:43 +00:00
oSumAtrIX
c95c241887 feat: migrate to breaking changes of patcher 2022-07-02 04:21:48 +02:00
semantic-release-bot
0f05fbfad9 chore(release): 2.5.1-dev.1 [skip ci]
## [2.5.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.5.1-dev.1) (2022-06-30)

### Bug Fixes

* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([d3e1419](d3e1419d0e))
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([c21e177](c21e177ed1))
2022-06-30 19:33:13 +00:00
148 changed files with 193 additions and 3899 deletions

View File

@@ -1,24 +0,0 @@
---
name: Bug report
about: Create a bug report on patches
title: 'problem: `some-patch`'
labels: bug
assignees: ''
---
## 🐞 Issue
<!-- Describe your issue in detail here -->
## ⚙ Reproduce
<!-- Include your environment and steps to reproduce the issue as detailed as possible -->
## 🛠 Solution
<!-- If applicable, add a possible solution -->
## ⚠ Additional context
<!-- Add any other context about the problem here -->

View File

@@ -1,24 +0,0 @@
---
name: Feature request
about: Suggest a change to some patch. Do not submit suggestions for patches here.
title: 'feat: some feature'
labels: feature-request
assignees: ''
---
## 🐞 Issue
<!-- Explain here, what the current problem is and why it leads you to request a feature change -->
## ❗ Solution
<!-- Explain how your current issue can be solved -->
## ❓ Motivation
<!-- Explain why your feature should be considered -->
## ⚠ Additional context
<!-- Add any other context or screenshots about the feature request here -->

View File

@@ -33,7 +33,7 @@ jobs:
- name: Build with Gradle - name: Build with Gradle
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build clean generateReadme run: ./gradlew build clean
- name: Install Android build-tools - name: Install Android build-tools
run: sdkmanager "build-tools;32.0.0" run: sdkmanager "build-tools;32.0.0"
- name: Setup semantic-release - name: Setup semantic-release

View File

@@ -7,11 +7,7 @@
} }
], ],
"plugins": [ "plugins": [
["@semantic-release/commit-analyzer", { "@semantic-release/commit-analyzer",
"releaseRules": [
{"type": "build", "release": "patch"}
]
}],
"@semantic-release/release-notes-generator", "@semantic-release/release-notes-generator",
"@semantic-release/changelog", "@semantic-release/changelog",
"gradle-semantic-release-plugin", "gradle-semantic-release-plugin",
@@ -19,7 +15,6 @@
"@semantic-release/git", "@semantic-release/git",
{ {
"assets": [ "assets": [
"README.md",
"CHANGELOG.md", "CHANGELOG.md",
"gradle.properties" "gradle.properties"
] ]

View File

@@ -1,253 +1,3 @@
# [2.18.0](https://github.com/revanced/revanced-patches/compare/v2.17.0...v2.18.0) (2022-07-18)
### Features
* `hide-get-premium` patch ([#195](https://github.com/revanced/revanced-patches/issues/195)) ([639aab4](https://github.com/revanced/revanced-patches/commit/639aab411ee514b50840c15c8e9a1a889854403f))
# [2.17.0](https://github.com/revanced/revanced-patches/compare/v2.16.1...v2.17.0) (2022-07-17)
### Bug Fixes
* check if node has attributes before accessing them ([2d2ed87](https://github.com/revanced/revanced-patches/commit/2d2ed870dacfe092eb6acbcaae5e51775c611322))
### Features
* `sponsorblock` patch ([#101](https://github.com/revanced/revanced-patches/issues/101)) ([36af4cc](https://github.com/revanced/revanced-patches/commit/36af4cc14ff8057c10b99019cb23acc6e5aec3f2)), closes [#89](https://github.com/revanced/revanced-patches/issues/89) [#90](https://github.com/revanced/revanced-patches/issues/90)
## [2.16.1](https://github.com/revanced/revanced-patches/compare/v2.16.0...v2.16.1) (2022-07-17)
### Bug Fixes
* bump youtube version to 17.27.39 ([b93401a](https://github.com/revanced/revanced-patches/commit/b93401a391c0ed4887dd1376ac253f74f98a8d7e))
# [2.16.0](https://github.com/revanced/revanced-patches/compare/v2.15.1...v2.16.0) (2022-07-17)
### Features
* `force-vp9-codec` patch ([#157](https://github.com/revanced/revanced-patches/issues/157)) ([07806a1](https://github.com/revanced/revanced-patches/commit/07806a16e5368118949e0e476e901987433ad403))
## [2.15.1](https://github.com/revanced/revanced-patches/compare/v2.15.0...v2.15.1) (2022-07-17)
### Bug Fixes
* `old-quality-layout` patch ([2497425](https://github.com/revanced/revanced-patches/commit/2497425c9f11b8b14c861c2f0f34ff47bdbfac53))
* references to integrations in `return-youtube-dislike` patch ([5824c2c](https://github.com/revanced/revanced-patches/commit/5824c2cdfb1a2d7b8d68044388e5e0746ef2ca09))
# [2.15.0](https://github.com/revanced/revanced-patches/compare/v2.14.1...v2.15.0) (2022-07-16)
### Features
* `return-youtube-dislikes` patch ([#175](https://github.com/revanced/revanced-patches/issues/175)) ([18a66d8](https://github.com/revanced/revanced-patches/commit/18a66d8454cf6e7cfdd4183631a6870c80d16b90))
## [2.14.1](https://github.com/revanced/revanced-patches/compare/v2.14.0...v2.14.1) (2022-07-15)
### Bug Fixes
* `codecs-unlock` patch and update Music patches to `5.14.53` ([2437d30](https://github.com/revanced/revanced-patches/commit/2437d3070f6a630d353619f642cefebd47abee20))
# [2.14.0](https://github.com/revanced/revanced-patches/compare/v2.13.6...v2.14.0) (2022-07-15)
### Features
* `music-video-ads` patch ([#172](https://github.com/revanced/revanced-patches/issues/172)) ([cbb71b5](https://github.com/revanced/revanced-patches/commit/cbb71b5faf1386ed31dd9e0387f6cf0509d92d31))
## [2.13.6](https://github.com/revanced/revanced-patches/compare/v2.13.5...v2.13.6) (2022-07-14)
## [2.13.5](https://github.com/revanced/revanced-patches/compare/v2.13.4...v2.13.5) (2022-07-14)
### Bug Fixes
* `swipe-controls` with active engagement panel ([#177](https://github.com/revanced/revanced-patches/issues/177)) ([000ec6d](https://github.com/revanced/revanced-patches/commit/000ec6d8f6ecbb910a06ec852564ee9e5f03dcf8))
## [2.13.4](https://github.com/revanced/revanced-patches/compare/v2.13.3...v2.13.4) (2022-07-13)
### Bug Fixes
* constrain `old-quality-layout` to older version ([add7232](https://github.com/revanced/revanced-patches/commit/add72326199e90f677b450b553b9d88c0bb4c490))
## [2.13.3](https://github.com/revanced/revanced-patches/compare/v2.13.2...v2.13.3) (2022-07-11)
### Bug Fixes
* `exclusive-audio-playback` patch ([#153](https://github.com/revanced/revanced-patches/issues/153)) ([9beff95](https://github.com/revanced/revanced-patches/commit/9beff9567f1586e5c58690c1f1d2f7f204025ab7))
## [2.13.2](https://github.com/revanced/revanced-patches/compare/v2.13.1...v2.13.2) (2022-07-11)
### Bug Fixes
* `hrd-auto-brightness` ([#152](https://github.com/revanced/revanced-patches/issues/152)) ([5f2e9ba](https://github.com/revanced/revanced-patches/commit/5f2e9ba30b7432be04bdc9f9f7ec7ac75fdc4b34))
## [2.13.1](https://github.com/revanced/revanced-patches/compare/v2.13.0...v2.13.1) (2022-07-11)
### Bug Fixes
* bump youtube version for swipe-controls patch ([ff207a5](https://github.com/revanced/revanced-patches/commit/ff207a57af7d3c15a8127f4465e97da23878b0d6))
# [2.13.0](https://github.com/revanced/revanced-patches/compare/v2.12.4...v2.13.0) (2022-07-11)
### Features
* `swipe-controls` rewrite ([#131](https://github.com/revanced/revanced-patches/issues/131)) ([b7dba09](https://github.com/revanced/revanced-patches/commit/b7dba09927ba15a9eacb06dcb4bf1f268560c96e))
## [2.12.4](https://github.com/revanced/revanced-patches/compare/v2.12.3...v2.12.4) (2022-07-11)
### Bug Fixes
* `autorepeat-by-default` patch ([#148](https://github.com/revanced/revanced-patches/issues/148)) ([fe628ba](https://github.com/revanced/revanced-patches/commit/fe628ba909d89ea0bf3d95fe94ca78ef819677da))
## [2.12.3](https://github.com/revanced/revanced-patches/compare/v2.12.2...v2.12.3) (2022-07-11)
### Bug Fixes
* listing of wrong fingerprint class ([#147](https://github.com/revanced/revanced-patches/issues/147)) ([95c2bbd](https://github.com/revanced/revanced-patches/commit/95c2bbdd1deb1d76f1177b48286fa6a3bc9f7663))
## [2.12.2](https://github.com/revanced/revanced-patches/compare/v2.12.1...v2.12.2) (2022-07-10)
### Bug Fixes
* display codename for patch names ([10c53f7](https://github.com/revanced/revanced-patches/commit/10c53f720df3e70b9d59e8bc3219d56b996f03db))
* incorrect package name in gradle task ([152b2c9](https://github.com/revanced/revanced-patches/commit/152b2c90cf102170648fcc168da10f46743bdc63))
* invalid regex ([26bf1d8](https://github.com/revanced/revanced-patches/commit/26bf1d818f953abc061126d8b91f17cd9008ba1d))
## [2.12.1](https://github.com/revanced/revanced-patches/compare/v2.12.0...v2.12.1) (2022-07-10)
# [2.12.0](https://github.com/revanced/revanced-patches/compare/v2.11.0...v2.12.0) (2022-07-10)
### Bug Fixes
* update patches to `17.26.35` ([#142](https://github.com/revanced/revanced-patches/issues/142)) ([b04112c](https://github.com/revanced/revanced-patches/commit/b04112c8562a7b95e7555e894b665913094b33eb))
* wording [skip ci] ([ba64d9e](https://github.com/revanced/revanced-patches/commit/ba64d9efc3ee606e9bda30ad7f8017af34b1dc3f))
### Features
* issue templates ([b82b0aa](https://github.com/revanced/revanced-patches/commit/b82b0aad88b7ab9d86f1bcc8e007f6a76a9aa1a5))
# [2.11.0](https://github.com/revanced/revanced-patches/compare/v2.10.2...v2.11.0) (2022-07-09)
### Features
* `autorepeat-by-default` patch ([#106](https://github.com/revanced/revanced-patches/issues/106)) ([e0ac9f3](https://github.com/revanced/revanced-patches/commit/e0ac9f385fc360f4dd2451e26676633120356c10))
## [2.10.2](https://github.com/revanced/revanced-patches/compare/v2.10.1...v2.10.2) (2022-07-08)
### Bug Fixes
* trigger release on `build` commits ([be8bd1b](https://github.com/revanced/revanced-patches/commit/be8bd1b2a4b91f9763448661a802a5dc4a6b1d1d))
## [2.10.1](https://github.com/revanced/revanced-patches/compare/v2.10.0...v2.10.1) (2022-07-08)
### Bug Fixes
* patch description consistency ([#134](https://github.com/revanced/revanced-patches/issues/134)) ([da5896d](https://github.com/revanced/revanced-patches/commit/da5896dde0a2b2b9ffe65e486402e4ef92ec1ce9))
# [2.10.0](https://github.com/revanced/revanced-patches/compare/v2.9.4...v2.10.0) (2022-07-07)
### Features
* implement `wide-searchbar` Patch ([#130](https://github.com/revanced/revanced-patches/issues/130)) ([332f4d1](https://github.com/revanced/revanced-patches/commit/332f4d12d06316d65db252a280fe1f263e65c3a8))
## [2.9.4](https://github.com/revanced/revanced-patches/compare/v2.9.3...v2.9.4) (2022-07-06)
### Bug Fixes
* add 17.25.34 as supported version for swipe-controls patch ([4d84c19](https://github.com/revanced/revanced-patches/commit/4d84c1914f8ecf51cee25667219bc6cf635a6c1c))
## [2.9.3](https://github.com/revanced/revanced-patches/compare/v2.9.2...v2.9.3) (2022-07-06)
### Bug Fixes
* Readd `swipe-controls` patch ([#123](https://github.com/revanced/revanced-patches/issues/123)) ([7f2a2b2](https://github.com/revanced/revanced-patches/commit/7f2a2b2ee4e6045d53aba4e7705431b643981107))
## [2.9.2](https://github.com/revanced/revanced-patches/compare/v2.9.1...v2.9.2) (2022-07-05)
### Bug Fixes
* revert `swipe-controls` patch ([66e1f33](https://github.com/revanced/revanced-patches/commit/66e1f3384a58361737ba889d946be875b23f3163))
## [2.9.1](https://github.com/revanced/revanced-patches/compare/v2.9.0...v2.9.1) (2022-07-05)
### Bug Fixes
* make `minimized-playback-manager-fingerprint` unique ([#120](https://github.com/revanced/revanced-patches/issues/120)) ([cd5e911](https://github.com/revanced/revanced-patches/commit/cd5e911f4ed9ad95b02c13c30cd9466d250e8904))
# [2.9.0](https://github.com/revanced/revanced-patches/compare/v2.8.2...v2.9.0) (2022-07-05)
### Features
* `swipe-controls` patch ([#115](https://github.com/revanced/revanced-patches/issues/115)) ([1d0a7dc](https://github.com/revanced/revanced-patches/commit/1d0a7dcc0cc3ea2bcd8ce0221d5e2f53d6eb0ae5))
## [2.8.2](https://github.com/revanced/revanced-patches/compare/v2.8.1...v2.8.2) (2022-07-05)
### Bug Fixes
* show minimized playback options in settings ([#118](https://github.com/revanced/revanced-patches/issues/118)) ([6e1a538](https://github.com/revanced/revanced-patches/commit/6e1a538d34291d75f19bf66a188bc69241de3a7a))
## [2.8.1](https://github.com/revanced/revanced-patches/compare/v2.8.0...v2.8.1) (2022-07-05)
### Bug Fixes
* remove unnecessary version constraints ([#117](https://github.com/revanced/revanced-patches/issues/117)) ([1cddf8d](https://github.com/revanced/revanced-patches/commit/1cddf8d9063da3bbdba0fd7080c8c93768b83a4c))
# [2.8.0](https://github.com/revanced/revanced-patches/compare/v2.7.0...v2.8.0) (2022-07-04)
### Features
* `enable-debugging` patch ([#116](https://github.com/revanced/revanced-patches/issues/116)) ([bb355e7](https://github.com/revanced/revanced-patches/commit/bb355e7b7e78e602a10b346fe7e5795463615a81))
# [2.7.0](https://github.com/revanced/revanced-patches/compare/v2.6.0...v2.7.0) (2022-07-03)
### Features
* `hdr-max-brightness` patch ([#105](https://github.com/revanced/revanced-patches/issues/105)) ([1310573](https://github.com/revanced/revanced-patches/commit/131057366a777786d6016d3385584b4e17bc4a8b))
* `hide-infocard-suggestions` patch ([#107](https://github.com/revanced/revanced-patches/issues/107)) ([31a767a](https://github.com/revanced/revanced-patches/commit/31a767adbb152906303ab0ae5250769fc38d0625))
# [2.6.0](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.6.0) (2022-07-02)
### Bug Fixes
* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([f5d4f6c](https://github.com/revanced/revanced-patches/commit/f5d4f6c3419916c6a9cf67babc6be8a64c854d3b))
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([df43547](https://github.com/revanced/revanced-patches/commit/df435475cdd0494a1e4ea9e2980c2998c9bc7048))
* remove refreshing home screen not working ([6c24ebe](https://github.com/revanced/revanced-patches/commit/6c24ebef2fb4f0d58e369ac5bf63e4cab6ca0e80))
### Features
* migrate to breaking changes of patcher ([d9147cd](https://github.com/revanced/revanced-patches/commit/d9147cd60c0c25d0c5cc05409b8889dfacd89af9))
# [2.6.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.6.0-dev.1...v2.6.0-dev.2) (2022-07-02) # [2.6.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.6.0-dev.1...v2.6.0-dev.2) (2022-07-02)

View File

@@ -1,9 +0,0 @@
# ReVanced Patches
🧩 Official patches by ReVanced
# List of available patches
| 💊 Patch | 📜 Description | 🎯 Target Package | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|:-----------------:|
{{ table }}

View File

@@ -1,41 +1 @@
# ReVanced Patches Repo for all ReVanced patches
🧩 Official patches by ReVanced
# List of available patches
| 💊 Patch | 📜 Description | 🎯 Target Package | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|:-----------------:|
| `music-video-ads` | Removes ads in the music player. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `exclusive-audio-playback` | Enables the option to play music without video. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `background-play` | Enables playing music in the background. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | `com.google.android.apps.youtube.music` | 5.14.53 |
| `hide-infocard-suggestions` | Hides infocards in videos. | `com.google.android.youtube` | 17.27.39 |
| `video-ads` | Removes ads in the video player. | `com.google.android.youtube` | 17.27.39 |
| `general-ads` | Removes general ads. | `com.google.android.youtube` | 17.27.39 |
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | `com.google.android.youtube` | 17.27.39 |
| `swipe-controls` | Adds volume and brightness swipe controls. | `com.google.android.youtube` | 17.27.39 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG | `com.google.android.youtube` | 17.27.39 |
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | `com.google.android.youtube` | 17.27.39 |
| `autorepeat-by-default` | Enables auto repeating of videos by default. | `com.google.android.youtube` | 17.27.39 |
| `custom-playback-speed` | Adds more video playback speed options. | `com.google.android.youtube` | 17.27.39 |
| `enable-debugging` | Enables app debugging by patching the manifest file. | `com.google.android.youtube` | all |
| `force-vp9-codec` | Forces the VP9 codec for videos. | `com.google.android.youtube` | 17.27.39 |
| `sponsorblock` | Integrate SponsorBlock. | `com.google.android.youtube` | 17.27.39 |
| `old-quality-layout` | Enables the original quality flyout menu. | `com.google.android.youtube` | 17.27.39 |
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | `com.google.android.youtube` | 17.27.39 |
| `hide-cast-button` | Hides the cast button in the video player. | `com.google.android.youtube` | all |
| `amoled` | Enables pure black theme. | `com.google.android.youtube` | 17.27.39 |
| `hide-autoplay-button` | Hides the autoplay button in the video player. | `com.google.android.youtube` | 17.27.39 |
| `minimized-playback` | Enables minimized and background playback. | `com.google.android.youtube` | 17.27.39 |
| `premium-heading` | Shows premium branding on the home screen. | `com.google.android.youtube` | all |
| `custom-branding` | Changes the YouTube launcher icon to be ReVanced's. | `com.google.android.youtube` | all |
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | `com.google.android.youtube` | 17.27.39 |
| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | `com.google.android.youtube` | 17.27.39 |
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | `com.google.android.youtube` | 17.27.39 |
| `disable-create-button` | Hides the create button in the navigation bar. | `com.google.android.youtube` | 17.27.39 |
| `hide-watermark` | Hides creator's watermarks on videos. | `com.google.android.youtube` | 17.27.39 |

View File

@@ -22,7 +22,7 @@ repositories {
dependencies { dependencies {
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))
implementation("app.revanced:revanced-patcher:2.4.0") implementation("app.revanced:revanced-patcher:2.1.2")
implementation("app.revanced:multidexlib2:2.5.2.r2") implementation("app.revanced:multidexlib2:2.5.2.r2")
} }
@@ -49,19 +49,12 @@ tasks {
} }
} }
} }
register<JavaExec>("generateReadme") {
description = "Generate README.md"
dependsOn(build)
classpath = sourceSets["main"].runtimeClasspath
mainClass.set("app.revanced.meta.readme.Generator")
}
// Dummy task to fix the Gradle semantic-release plugin. // Dummy task to fix the Gradle semantic-release plugin.
// Remove this if you forked it to support building only. // Remove this if you forked it to support building only.
// Tracking issue: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435 // Tracking issue: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
register<DefaultTask>("publish") { register<DefaultTask>("publish") {
group = "publish" group = "publish"
description = "Dummy task" description = "Dummy task"
dependsOn(named("generateDex"), named("generateReadme")) dependsOn(named("generateDex"))
} }
} }

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.18.0 version = 2.6.0-dev.2

View File

@@ -1,23 +1,9 @@
package app.revanced.extensions package app.revanced.extensions
import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.toInstruction import app.revanced.patcher.util.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.MutableMethodImplementation import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.builder.instruction.BuilderInstruction11n
import org.jf.dexlib2.builder.instruction.BuilderInstruction11x
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
import org.w3c.dom.Node import org.w3c.dom.Node
import java.io.OutputStream
import java.nio.file.Files
// TODO: this method does not make sense here
internal fun MutableMethodImplementation.injectHideCall( internal fun MutableMethodImplementation.injectHideCall(
index: Int, index: Int,
register: Int register: Int
@@ -28,143 +14,6 @@ internal fun MutableMethodImplementation.injectHideCall(
) )
} }
/**
* Insert an event hook at the top of the method. If the hook returns true, the event is consumed and the method will return with true
*
* the hook method MUST return a boolean and MUST take two parameters, like so:
* fun hook(thisRef: Object, eventData: Object): Boolean {}
*
* The final injected code will resemble the following logic:
* if( YouHook(this, event) ) { return true; }
* ...
*
* @param hookRef reference to the hook method
*/
internal fun MutableMethod.injectConsumableEventHook(hookRef: ImmutableMethodReference) {
val isStaticMethod = AccessFlags.STATIC.isSet(this.accessFlags)
this.implementation?.let { impl ->
// create label to index 0 to continue to the normal program flow
val lblContinueNormalFlow = impl.newLabelForIndex(0)
// define registers
/** V0 */
val regV0 = 0
/** this */
val regP0 = impl.registerCount - this.parameters.size - (if (isStaticMethod) 0 else 1)
/** motionEvent */
val regP1 = regP0 + 1
// insert instructions at the start of the method:
// if( Hook(this, event) ) { return true; }
impl.addInstructions(
0, listOf(
// invoke-static { p0, p1 } <hook>
BuilderInstruction35c(
Opcode.INVOKE_STATIC,
2,
regP0,
regP1,
0, 0, 0,
hookRef
),
// move-result v0
BuilderInstruction11x(
Opcode.MOVE_RESULT,
regV0
),
// if-eqz v0, :continue_normal_flow
BuilderInstruction21t(
Opcode.IF_EQZ,
regV0,
lblContinueNormalFlow
),
// const/4 v0, 0x1
BuilderInstruction11n(
Opcode.CONST_4,
regV0,
0x1
),
// return v0
BuilderInstruction11x(
Opcode.RETURN,
regV0
)
// :continue_normal_flow
)
)
}
}
/**
* inject resources into the patched app
*
* @param classLoader classloader to use for loading the resources
* @param patchDirectoryPath path to the files. this will be the directory you created under the 'resources' source folder
* @param resourceType the resource type, for example 'drawable'. this has to match both the source and the target
* @param resourceFileNames names of all resources of this type to inject
*/
fun ResourceData.injectResources(
classLoader: ClassLoader,
patchDirectoryPath: String,
resourceType: String,
resourceFileNames: List<String>
) {
resourceFileNames.forEach { name ->
val relativePath = "$resourceType/$name"
val sourceRes = classLoader.getResourceAsStream("$patchDirectoryPath/$relativePath")
?: throw PatchResultError("could not open resource '$patchDirectoryPath/$relativePath'")
Files.copy(
sourceRes,
this["res"].resolve(relativePath).toPath()
)
}
}
/**
* inject strings into the patched app
*
* @param classLoader classloader to use for loading the resources
* @param patchDirectoryPath path to the files. this will be the directory you created under the 'resources' source folder
* @param languageIdentifier ISO 639-2 two- letter language code identifier (aka the one android uses for values directory)
*/
fun ResourceData.injectStrings(
classLoader: ClassLoader,
patchDirectoryPath: String,
languageIdentifier: String? = null,
) {
val relativePath =
if (languageIdentifier.isNullOrBlank()) "values/strings.xml" else "values/strings-$languageIdentifier.xml"
// open source strings.xml
val sourceInputStream = classLoader.getResourceAsStream("$patchDirectoryPath/$relativePath")
?: throw PatchResultError("failed to open '$patchDirectoryPath/$relativePath'")
xmlEditor[sourceInputStream, OutputStream.nullOutputStream()].use { sourceStringsXml ->
val strings = sourceStringsXml.file.getElementsByTagName("resources").item(0).childNodes
// open target strings.xml
xmlEditor["res/$relativePath"].use { targetStringsXml ->
val targetFile = targetStringsXml.file
val targetRootNode = targetFile.getElementsByTagName("resources").item(0)
// process all children strings in the source
for (i in 0 until strings.length) {
// clone the node from source to target
val node = strings.item(i).cloneNode(true)
targetFile.adoptNode(node)
targetRootNode.appendChild(node)
}
}
}
}
internal fun Node.doRecursively(action: (Node) -> Unit) { internal fun Node.doRecursively(action: (Node) -> Unit) {
action(this) action(this)
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action) for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)

View File

@@ -1,41 +0,0 @@
package app.revanced.meta.readme
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.description
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.util.patch.implementation.JarPatchBundle
import java.io.File
class Generator {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val buildDir = File("build/libs/")
val buildJar =
buildDir.listFiles()?.first { it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar") }!!
val bundle = JarPatchBundle(buildJar.absolutePath).loadPatches()
val patches = StringBuilder()
for (patch in bundle) {
val patchName = patch.patchName
val compatiblePackage = patch.compatiblePackages?.first()
val latestVersion =
compatiblePackage?.versions?.map { SemanticVersion.fromString(it) }?.maxWithOrNull(
SemanticVersionComparator
) ?: "all"
patches.appendLine("| `$patchName` | ${patch.description} | `${compatiblePackage?.name}` | $latestVersion |")
}
val readMeTemplateFile = File("README-template.md")
val readmeTemplate = Template(readMeTemplateFile.readText())
readmeTemplate.replaceVariable("table", patches.toString())
val readme = File("README.md")
readme.writeText(readmeTemplate.toString())
}
}
}

View File

@@ -1,24 +0,0 @@
package app.revanced.meta.readme
data class SemanticVersion(val major: Int, val minor: Int, val patch: Int) {
companion object {
fun fromString(version: String): SemanticVersion {
var parts = version.split(".")
if (parts.count() != 3) throw IllegalArgumentException("Invalid semantic version")
val versionNumbers = parts.map { it.toInt() }
return SemanticVersion(versionNumbers[0], versionNumbers[1], versionNumbers[2])
}
}
override fun toString(): String = "$major.$minor.$patch"
}
object SemanticVersionComparator : Comparator<SemanticVersion> {
override fun compare(a: SemanticVersion, b: SemanticVersion): Int = when {
a.major != b.major -> a.major - b.major
a.minor != b.minor -> a.minor - b.minor
else -> a.patch - b.patch
}
}

View File

@@ -1,14 +0,0 @@
package app.revanced.meta.readme
class Template(template: String) {
val result: StringBuilder = StringBuilder(template)
fun replaceVariable(name: String, value: String) {
val regex = Regex("\\{\\{\\s?$name\\s?}}")
val range = regex.find(result)!!.range
result.replace(range.first, range.last + 1, value)
}
override fun toString(): String = result.toString()
}

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.music.ad.video.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class MusicVideoAdsCompatibility

View File

@@ -1,39 +0,0 @@
package app.revanced.patches.music.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.music.ad.video.annotations.MusicVideoAdsCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("show-video-ads-constructor-fingerprint")
@MatchingMethod(
"Laghd;",
"<init>",
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@MusicVideoAdsCompatibility
@Version("0.0.1")
object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf(
Opcode.INVOKE_DIRECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.CONST_4,
Opcode.IPUT_BOOLEAN,
Opcode.RETURN_VOID
)
)

View File

@@ -1,26 +0,0 @@
package app.revanced.patches.music.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.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.music.ad.video.annotations.MusicVideoAdsCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("show-video-ads-method-fingerprint")
@MatchingMethod(
"Laghd;", "d"
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@MusicVideoAdsCompatibility
@Version("0.0.1")
object ShowMusicVideoAdsFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), listOf(
Opcode.IPUT_BOOLEAN,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
)
)

View File

@@ -1,40 +0,0 @@
package app.revanced.patches.music.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.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.music.ad.video.annotations.MusicVideoAdsCompatibility
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsConstructorFingerprint
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerprint
@Patch
@Name("music-video-ads")
@Description("Removes ads in the music player.")
@MusicVideoAdsCompatibility
@Version("0.0.1")
class MusicVideoAdsPatch : BytecodePatch(
listOf(
ShowMusicVideoAdsConstructorFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
ShowMusicVideoAdsFingerprint.resolve(data, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef)
val result = ShowMusicVideoAdsFingerprint.result!!
result.mutableMethod.addInstructions(
result.patternScanResult!!.startIndex, """
const/4 p1, 0x0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53") "com.google.android.apps.youtube.music", arrayOf("5.03.50")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -20,9 +20,8 @@ import org.jf.dexlib2.Opcode
@Version("0.0.1") @Version("0.0.1")
object CodecsLockFingerprint : MethodFingerprint( object CodecsLockFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf( "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
@@ -30,11 +29,18 @@ object CodecsLockFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.SGET_OBJECT, Opcode.SGET,
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.RETURN_OBJECT Opcode.RETURN_OBJECT
) )

View File

@@ -16,7 +16,7 @@ import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprin
@Patch @Patch
@Name("codecs-unlock") @Name("codecs-unlock")
@Description("Adds more audio codec options. The new audio codecs usually result in better audio quality.") @Description("Enables more audio codecs. Usually results in better audio quality but may depend on song and device.")
@CodecsUnlockCompatibility @CodecsUnlockCompatibility
@Version("0.0.1") @Version("0.0.1")
class CodecsUnlockPatch : BytecodePatch( class CodecsUnlockPatch : BytecodePatch(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53") "com.google.android.apps.youtube.music", arrayOf("5.03.50")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -17,16 +17,18 @@ import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.ExclusiveAud
@Patch @Patch
@Name("exclusive-audio-playback") @Name("exclusive-audio-playback")
@Description("Enables the option to play music without video.") @Description("Add the option to play music without video.")
@ExclusiveAudioCompatibility @ExclusiveAudioCompatibility
@Version("0.0.1") @Version("0.0.1")
class ExclusiveAudioPatch : BytecodePatch( class ExclusiveAudioPatch : BytecodePatch(
listOf( listOf(
AudioOnlyEnablerFingerprint ExclusiveAudioFingerprint
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
val method = AudioOnlyEnablerFingerprint.result!!.mutableMethod ExclusiveAudioFingerprint.resolve(data, AudioOnlyEnablerFingerprint.result!!.classDef)
val method = ExclusiveAudioFingerprint.result!!.mutableMethod
method.replaceInstruction(method.implementation!!.instructions.count() - 1, "const/4 v0, 0x1") method.replaceInstruction(method.implementation!!.instructions.count() - 1, "const/4 v0, 0x1")
method.addInstruction("return v0") method.addInstruction("return v0")

View File

@@ -1,14 +0,0 @@
package app.revanced.patches.music.layout.premium.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HideGetPremiumCompatibility

View File

@@ -1,26 +0,0 @@
package app.revanced.patches.music.layout.premium.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.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.music.layout.premium.annotations.HideGetPremiumCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("hide-get-premium-fingerprint")
@MatchingMethod(
"Lktn;", "k"
)
@HideGetPremiumCompatibility
@Version("0.0.1")
object HideGetPremiumFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
Opcode.IF_NEZ,
Opcode.CONST_16,
Opcode.GOTO,
Opcode.NOP,
Opcode.INVOKE_VIRTUAL
)
)

View File

@@ -1,29 +0,0 @@
package app.revanced.patches.music.layout.premium.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.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.music.layout.premium.annotations.HideGetPremiumCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("hide-get-premium-parent-fingerprint")
@MatchingMethod(
"Lktn;", "k"
)
@HideGetPremiumCompatibility
@Version("0.0.1")
object HideGetPremiumParentFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC
),
listOf("FEmusic_history"),
)

View File

@@ -1,49 +0,0 @@
package app.revanced.patches.music.layout.premium.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.music.layout.premium.annotations.HideGetPremiumCompatibility
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumParentFingerprint
@Patch
@Name("hide-get-premium")
@Description("Removes all \"Get Premium\" evidences from the avatar menu.")
@HideGetPremiumCompatibility
@Version("0.0.1")
class HideGetPremiumPatch : BytecodePatch(
listOf(
HideGetPremiumParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val parentResult = HideGetPremiumParentFingerprint.result!!
HideGetPremiumFingerprint.resolve(data, parentResult.classDef)
val parentMethod = parentResult.mutableMethod
parentMethod.replaceInstruction(
parentResult.patternScanResult!!.startIndex, """
const/4 v1, 0x0
"""
)
val result = HideGetPremiumFingerprint.result!!
val method = result.mutableMethod
method.addInstructions(
result.patternScanResult!!.startIndex, """
const/16 v0, 0x8
"""
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53") "com.google.android.apps.youtube.music", arrayOf("5.03.50")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -15,7 +15,7 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction22c
@Patch @Patch
@Name("tasteBuilder-remover") @Name("tasteBuilder-remover")
@Description("Removes the \"Tell us which artists you like\" card from the home screen.") @Description("Removes the \"Tell us which artists you like\" card from the Home screen. The same functionality can be triggered from the settings anyway.")
@RemoveTasteBuilderCompatibility @RemoveTasteBuilderCompatibility
@Version("0.0.1") @Version("0.0.1")
class RemoveTasteBuilderPatch : BytecodePatch( class RemoveTasteBuilderPatch : BytecodePatch(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53") "com.google.android.apps.youtube.music", arrayOf("5.03.50")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -20,7 +20,7 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch @Patch
@Name("upgrade-button-remover") @Name("upgrade-button-remover")
@Description("Removes the upgrade tab from the pivot bar.") @Description("Remove the upgrade tab from the pivot bar in YouTube music.")
@RemoveUpgradeButtonCompatibility @RemoveUpgradeButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class RemoveUpgradeButtonPatch : BytecodePatch( class RemoveUpgradeButtonPatch : BytecodePatch(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53") "com.google.android.apps.youtube.music", arrayOf("5.03.50")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -14,7 +14,7 @@ import app.revanced.patches.music.premium.backgroundplay.fingerprints.Background
@Patch @Patch
@Name("background-play") @Name("background-play")
@Description("Enables playing music in the background.") @Description("Enable playing music in the background.")
@BackgroundPlayCompatibility @BackgroundPlayCompatibility
@Version("0.0.1") @Version("0.0.1")
class BackgroundPlayPatch : BytecodePatch( class BackgroundPlayPatch : BytecodePatch(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -38,12 +38,16 @@ import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
@Patch @Patch
@Dependencies([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class]) @Dependencies(
dependencies = [ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class]
)
@Name("general-ads") @Name("general-ads")
@Description("Removes general ads.") @Description("Patch to remove general ads in bytecode.")
@GeneralAdsCompatibility @GeneralAdsCompatibility
@Version("0.0.1") @Version("0.0.1")
class GeneralBytecodeAdsPatch : BytecodePatch() { class GeneralBytecodeAdsPatch : BytecodePatch(
listOf()
) {
// a constant used by litho // a constant used by litho
private val lithoConstant = 0xaed2868 private val lithoConstant = 0xaed2868
@@ -58,7 +62,7 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
"promoted_video_item_land", "promoted_video_item_land",
"promoted_video_item_full_bleed", "promoted_video_item_full_bleed",
).map { name -> ).map { name ->
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.name == name }.id ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.name == name }.id
} }
private val stringReferences = arrayOf( private val stringReferences = arrayOf(

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.youtube.ad.infocardsuggestions.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HideInfocardSuggestionsCompatibility

View File

@@ -1,24 +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.annotation.MatchingMethod
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")
@MatchingMethod("Liff;", "i")
@FuzzyPatternScanMethod(2)
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
object HideInfocardSuggestionsFingerprint : MethodFingerprint(
"Ljava/lang/Boolean;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
null,
listOf("vibrator"),
null
)

View File

@@ -1,24 +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.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("hide-infocard-suggestions-parent-fingerprint")
@MatchingMethod("Liff;", "lE")
@FuzzyPatternScanMethod(2)
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
object HideInfocardSuggestionsParentFingerprint : MethodFingerprint(
"Ljava/lang/String;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
null,
listOf("player_overlay_info_card_teaser"),
null
)

View File

@@ -1,63 +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.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
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 org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch
@Dependencies([IntegrationsPatch::class])
@Name("hide-infocard-suggestions")
@Description("Hides infocards in videos.")
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
class HideInfocardSuggestionsPatch : BytecodePatch(
listOf(
HideInfocardSuggestionsParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val parentResult = HideInfocardSuggestionsParentFingerprint.result
?: return PatchResultError("Parent fingerprint not resolved!")
HideInfocardSuggestionsFingerprint.resolve(data, 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") }
val register = "v" + (implementation.instructions.get(index) as FiveRegisterInstruction).registerD
method.removeInstruction(index)
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/HideInfoCardSuggestionsPatch;->hideInfoCardSuggestions()I
move-result $register
invoke-virtual {p1, $register}, Landroid/view/View;->setVisibility(I)V
"""
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -17,9 +17,9 @@ import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsFingerprin
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @Dependencies(dependencies = [IntegrationsPatch::class])
@Name("video-ads") @Name("video-ads")
@Description("Removes ads in the video player.") @Description("Patch to remove ads in the YouTube video player.")
@VideoAdsCompatibility @VideoAdsCompatibility
@Version("0.0.1") @Version("0.0.1")
class VideoAdsPatch : BytecodePatch( class VideoAdsPatch : BytecodePatch(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -22,9 +22,9 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction11n
import org.jf.dexlib2.iface.instruction.formats.Instruction35c import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @Dependencies(dependencies = [IntegrationsPatch::class])
@Name("seekbar-tapping") @Name("seekbar-tapping")
@Description("Enables tap-to-seek on the seekbar of the video player.") @Description("Enable tapping on the seekbar of the YouTube player.")
@SeekbarTappingCompatibility @SeekbarTappingCompatibility
@Version("0.0.1") @Version("0.0.1")
class EnableSeekbarTappingPatch : BytecodePatch( class EnableSeekbarTappingPatch : BytecodePatch(

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.youtube.interaction.swipecontrols.annotation
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class SwipeControlsCompatibility

View File

@@ -1,21 +0,0 @@
package app.revanced.patches.youtube.interaction.swipecontrols.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
@Name("watch-while-onStart-fingerprint")
@MatchingMethod(
"LWatchWhileActivity;", "onCreate"
)
@DirectPatternScanMethod
@SwipeControlsCompatibility
@Version("0.0.1")
object WatchWhileOnStartFingerprint : MethodFingerprint(
null, null, null, null, null, { methodDef ->
methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "onStart"
}
)

View File

@@ -1,45 +0,0 @@
package app.revanced.patches.youtube.interaction.swipecontrols.patch.bytecode
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.WatchWhileOnStartFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.patch.resource.SwipeControlsResourcePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playeroverlay.patch.PlayerOverlaysHookPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
@Patch
@Name("swipe-controls")
@Description("Adds volume and brightness swipe controls.")
@SwipeControlsCompatibility
@Version("0.0.2")
@Dependencies(
[
IntegrationsPatch::class,
PlayerTypeHookPatch::class,
PlayerOverlaysHookPatch::class,
SwipeControlsResourcePatch::class
]
)
class SwipeControlsBytecodePatch : BytecodePatch(
listOf(
WatchWhileOnStartFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
WatchWhileOnStartFingerprint.result!!.mutableMethod.addInstruction(
0,
"invoke-static { p0 }, Lapp/revanced/integrations/patches/SwipeControlsPatch;->WatchWhileActivity_onStartHookEX(Ljava/lang/Object;)V"
)
return PatchResultSuccess()
}
}

View File

@@ -1,32 +0,0 @@
package app.revanced.patches.youtube.interaction.swipecontrols.patch.resource
import app.revanced.extensions.injectResources
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.interaction.swipecontrols.annotation.SwipeControlsCompatibility
@Name("swipe-controls-resource-patch")
@SwipeControlsCompatibility
@Version("0.0.1")
class SwipeControlsResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult {
val resourcesDir = "swipecontrols"
data.injectResources(
this.javaClass.classLoader,
resourcesDir,
"drawable",
listOf(
"ic_sc_brightness_auto",
"ic_sc_brightness_manual",
"ic_sc_volume_mute",
"ic_sc_volume_normal"
).map { "$it.xml" }
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -15,7 +15,11 @@ import org.w3c.dom.Element
import java.io.File import java.io.File
@Patch @Patch
@Dependencies([FixLocaleConfigErrorPatch::class]) @Dependencies(
dependencies = [
FixLocaleConfigErrorPatch::class
]
)
@Name("amoled") @Name("amoled")
@Description("Enables pure black theme.") @Description("Enables pure black theme.")
@AmoledCompatibility @AmoledCompatibility

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -18,9 +18,9 @@ import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProvider
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Patch @Patch
@Dependencies([ResourceIdMappingProviderResourcePatch::class]) @Dependencies(dependencies = [ResourceIdMappingProviderResourcePatch::class])
@Name("hide-autoplay-button") @Name("hide-autoplay-button")
@Description("Hides the autoplay button in the video player.") @Description("Disable the autoplay button.")
@AutoplayButtonCompatibility @AutoplayButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideAutoplayButton : BytecodePatch( class HideAutoplayButton : BytecodePatch(
@@ -32,9 +32,9 @@ class HideAutoplayButton : BytecodePatch(
val layoutGenMethod = LayoutConstructorFingerprint.result!!.mutableMethod val layoutGenMethod = LayoutConstructorFingerprint.result!!.mutableMethod
val autonavToggle = val autonavToggle =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "autonav_toggle" } ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.type == "id" && it.name == "autonav_toggle" }
val autonavPreviewStub = val autonavPreviewStub =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "autonav_preview_stub" } ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.type == "id" && it.name == "autonav_preview_stub" }
val autonavToggleConstIndex = val autonavToggleConstIndex =
layoutGenMethod.implementation!!.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavToggle.id } layoutGenMethod.implementation!!.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavToggle.id }

View File

@@ -17,9 +17,11 @@ import java.nio.file.StandardCopyOption
import kotlin.io.path.exists import kotlin.io.path.exists
@Patch @Patch
@Dependencies([FixLocaleConfigErrorPatch::class]) @Dependencies(
dependencies = [FixLocaleConfigErrorPatch::class]
)
@Name("premium-heading") @Name("premium-heading")
@Description("Shows premium branding on the home screen.") @Description("Show the premium branding on the the YouTube home screen.")
@PremiumHeadingCompatibility @PremiumHeadingCompatibility
@Version("0.0.1") @Version("0.0.1")
class PremiumHeadingPatch : ResourcePatch() { class PremiumHeadingPatch : ResourcePatch() {
@@ -32,7 +34,7 @@ class PremiumHeadingPatch : ResourcePatch() {
arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi").forEach { size -> arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi").forEach { size ->
val headingDirectory = resDirectory.resolve("drawable-$size") val headingDirectory = resDirectory.resolve("drawable-$size")
modes.forEach { mode -> modes.forEach {mode ->
val fromPath = headingDirectory.resolve("${original}_$mode.png").toPath() val fromPath = headingDirectory.resolve("${original}_$mode.png").toPath()
val toPath = headingDirectory.resolve("${replacement}_$mode.png").toPath() val toPath = headingDirectory.resolve("${replacement}_$mode.png").toPath()

View File

@@ -15,9 +15,11 @@ import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatc
import java.nio.file.Files import java.nio.file.Files
@Patch @Patch
@Dependencies([FixLocaleConfigErrorPatch::class]) @Dependencies(
dependencies = [FixLocaleConfigErrorPatch::class]
)
@Name("custom-branding") @Name("custom-branding")
@Description("Changes the YouTube launcher icon to be ReVanced's.") @Description("Change the branding of YouTube.")
@CustomBrandingCompatibility @CustomBrandingCompatibility
@Version("0.0.1") @Version("0.0.1")
class CustomBrandingPatch : ResourcePatch() { class CustomBrandingPatch : ResourcePatch() {

View File

@@ -14,12 +14,12 @@ import app.revanced.patches.youtube.layout.castbutton.annotations.CastButtonComp
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @Dependencies(dependencies = [IntegrationsPatch::class])
@Name("hide-cast-button") @Name("hide-cast-button")
@Description("Hides the cast button in the video player.") @Description("Patch to hide the cast button.")
@CastButtonCompatibility @CastButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideCastButtonPatch : BytecodePatch() { class HideCastButtonPatch : BytecodePatch(listOf()) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
data.classes.forEach { classDef -> data.classes.forEach { classDef ->
classDef.methods.forEach { method -> classDef.methods.forEach { method ->

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -22,9 +22,9 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Dependencies([IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class]) @Dependencies(dependencies = [IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class])
@Name("disable-create-button") @Name("disable-create-button")
@Description("Hides the create button in the navigation bar.") @Description("Disable the create button.")
@CreateButtonCompatibility @CreateButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class CreateButtonRemoverPatch : BytecodePatch( class CreateButtonRemoverPatch : BytecodePatch(
@@ -39,7 +39,7 @@ class CreateButtonRemoverPatch : BytecodePatch(
val implementation = result.mutableMethod.implementation!! val implementation = result.mutableMethod.implementation!!
val imageOnlyLayout = val imageOnlyLayout =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "layout" && it.name == "image_only_tab" } ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.type == "layout" && it.name == "image_only_tab" }
val imageOnlyLayoutConstIndex = val imageOnlyLayoutConstIndex =
implementation.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == imageOnlyLayout.id } implementation.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == imageOnlyLayout.id }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -19,7 +19,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Name("disable-fullscreen-panels") @Name("disable-fullscreen-panels")
@Description("Disables video description and comments panel in fullscreen view.") @Description("Disable comments panel in fullscreen view.")
@FullscreenPanelsCompatibility @FullscreenPanelsCompatibility
@Version("0.0.1") @Version("0.0.1")
class FullscreenPanelsRemovalPatch : BytecodePatch( class FullscreenPanelsRemovalPatch : BytecodePatch(

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -1,37 +0,0 @@
package app.revanced.patches.youtube.layout.minimizedplayback.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("minimized-playback-manager-fingerprint")
@MatchingMethod(
"Ladj", "w"
)
@FuzzyPatternScanMethod(2)
@MinimizedPlaybackCompatibility
@Version("0.0.1")
object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST
),
)

View File

@@ -3,30 +3,24 @@ package app.revanced.patches.youtube.layout.minimizedplayback.patch
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility
import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Name("minimized-playback") @Name("minimized-playback")
@Description("Enables minimized and background playback.") @Description("Enable minimized and background playback.")
@MinimizedPlaybackCompatibility @MinimizedPlaybackCompatibility
@Version("0.0.1") @Version("0.0.1")
class MinimizedPlaybackPatch : BytecodePatch( class MinimizedPlaybackPatch : BytecodePatch(
listOf( listOf(
MinimizedPlaybackManagerFingerprint, MinimizedPlaybackSettingsFingerprint MinimizedPlaybackManagerFingerprint
) )
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
@@ -38,22 +32,6 @@ class MinimizedPlaybackPatch : BytecodePatch(
return v0 return v0
""" """
) )
val method = MinimizedPlaybackSettingsFingerprint.result!!.mutableMethod
val booleanCalls = method.implementation!!.instructions.withIndex()
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }
val settingsBooleanIndex = booleanCalls.elementAt(1).index
val settingsBooleanMethod =
data.toMethodWalker(method).nextMethod(settingsBooleanIndex, true).getMethod() as MutableMethod
settingsBooleanMethod.addInstructions(
0, """
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -3,37 +3,27 @@ package app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
@Name("quality-menu-view-inflate-fingerprint") @Name("old-quality-fingerprint")
@MatchingMethod("Lkhp;", "K") @MatchingMethod(definingClass = "Libh")
@FuzzyPatternScanMethod(2)
@OldQualityLayoutCompatibility @OldQualityLayoutCompatibility
@Version("0.0.1") @Version("0.0.1")
object QualityMenuViewInflateFingerprint : MethodFingerprint( object OldQualityFingerprint : MethodFingerprint(
"L", AccessFlags.FINAL or AccessFlags.PUBLIC, listOf("L", "L", "L"), listOf( "L", AccessFlags.FINAL or AccessFlags.PRIVATE, listOf("Z"), listOf(
Opcode.INVOKE_SUPER,
Opcode.CONST,
Opcode.CONST_4, Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.CONST_STRING, Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.GOTO,
Opcode.IGET_OBJECT,
) )
) )

View File

@@ -0,0 +1,50 @@
package app.revanced.patches.youtube.layout.oldqualitylayout.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("old-quality-parent-method-fingerprint")
@MatchingMethod(
"Libh", "<init>"
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@OldQualityLayoutCompatibility
@Version("0.0.1")
object OldQualityParentFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L", "L", "L", "L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
)
)

View File

@@ -4,41 +4,49 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.QualityMenuViewInflateFingerprint import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.OldQualityFingerprint
import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.OldQualityParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @Dependencies(dependencies = [IntegrationsPatch::class])
@Name("old-quality-layout") @Name("old-quality-layout")
@Description("Enables the original quality flyout menu.") @Description("Enable the original quality flyout menu.")
@OldQualityLayoutCompatibility @OldQualityLayoutCompatibility
@Version("0.0.1") @Version("0.0.1")
class OldQualityLayoutPatch : BytecodePatch( class OldQualityLayoutPatch : BytecodePatch(
listOf(QualityMenuViewInflateFingerprint) listOf(
OldQualityParentFingerprint
)
) { ) {
override fun execute(data: BytecodeData): PatchResult { override fun execute(data: BytecodeData): PatchResult {
val inflateFingerprintResult = QualityMenuViewInflateFingerprint.result!! OldQualityFingerprint.resolve(data, OldQualityParentFingerprint.result!!.classDef)
val method = inflateFingerprintResult.mutableMethod val result = OldQualityFingerprint.result
val instructions = method.implementation!!.instructions ?: return PatchResultError("Required parent method could not be found.")
// at this index the listener is added to the list view val implementation = result.mutableMethod.implementation!!
val listenerInvokeRegister = instructions.size - 1 - 1
// get the register which stores the quality menu list view // if useOldStyleQualitySettings == true, jump over all instructions
val onItemClickViewRegister = (instructions[listenerInvokeRegister] as FiveRegisterInstruction).registerC val jmpInstruction = BuilderInstruction21t(
Opcode.IF_NEZ, 0, implementation.instructions[result.patternScanResult!!.endIndex].location.labels.first()
// insert the integrations method )
method.addInstruction( implementation.addInstruction(5, jmpInstruction)
listenerInvokeRegister, // insert the integrations instructions right before the listener result.mutableMethod.addInstructions(
"invoke-static { v$onItemClickViewRegister }, Lapp/revanced/integrations/patches/OldQualityLayoutPatch;->showOldQualityMenu(Landroid/widget/ListView;)V" 0, """
invoke-static { }, Lapp/revanced/integrations/patches/OldStyleQualityPatch;->useOldStyleQualitySettings()Z
move-result v0
"""
) )
return PatchResultSuccess() return PatchResultSuccess()

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -13,7 +13,7 @@ import app.revanced.patches.youtube.layout.reels.fingerprints.HideReelsFingerpri
//@Patch TODO: this is currently in the general-bytecode-ads patch due to the integrations having a preference for including reels or not. Move it here. //@Patch TODO: this is currently in the general-bytecode-ads patch due to the integrations having a preference for including reels or not. Move it here.
@Name("hide-reels") @Name("hide-reels")
@Description("Hides reels on the home page.") @Description("Hide reels on the page.")
@HideReelsCompatibility @HideReelsCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideReelsPatch : BytecodePatch( class HideReelsPatch : BytecodePatch(

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ReturnYouTubeDislikeCompatibility

View File

@@ -1,25 +0,0 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import org.jf.dexlib2.AccessFlags
@Name("dislike-fingerprint")
@MatchingMethod(
"Luqs;", "<init>"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
object DislikeFingerprint : MethodFingerprint(
"V",
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
null,
null,
listOf("like/dislike")
)

View File

@@ -1,25 +0,0 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import org.jf.dexlib2.AccessFlags
@Name("like-fingerprint")
@MatchingMethod(
"Luqt;", "<init>"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
object LikeFingerprint : MethodFingerprint(
"V",
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
null,
null,
listOf("like/like")
)

View File

@@ -1,25 +0,0 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import org.jf.dexlib2.AccessFlags
@Name("remove-like-fingerprint")
@MatchingMethod(
"Luqw;", "<init>"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
object RemoveLikeFingerprint : MethodFingerprint(
"V",
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
null,
null,
listOf("like/removelike")
)

View File

@@ -1,23 +0,0 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
@Name("text-component-spec-parent-fingerprint")
@MatchingMethod(
"Lnvy;", "e"
)
@DirectPatternScanMethod
@ReturnYouTubeDislikeCompatibility
@Version("0.0.1")
object TextComponentSpecParentFingerprint : MethodFingerprint(
null,
null,
null,
null,
listOf("TextComponentSpec: No converter for extension: ")
)

View File

@@ -1,79 +0,0 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.TextComponentSpecParentFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.DislikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.LikeFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RemoveLikeFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
@Patch
@Dependencies([IntegrationsPatch::class, VideoIdPatch::class])
@Name("return-youtube-dislike")
@Description("Shows the dislike count of videos using the Return YouTube Dislike API.")
@ReturnYouTubeDislikeCompatibility
@Version("0.0.1")
class ReturnYouTubeDislikePatch : BytecodePatch(
listOf(
TextComponentSpecParentFingerprint, LikeFingerprint, DislikeFingerprint, RemoveLikeFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
LikeFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, 1
invoke-static {v0}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->sendVote(I)V
"""
)
DislikeFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, -1
invoke-static {v0}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->sendVote(I)V
"""
)
RemoveLikeFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, 0
invoke-static {v0}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->sendVote(I)V
"""
)
VideoIdPatch.injectCall("Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->newVideoLoaded(Ljava/lang/String;)V")
val parentResult = TextComponentSpecParentFingerprint.result!!
val createComponentMethod = parentResult.mutableClass.methods.find { method ->
method.parameters.size >= 19 && method.parameterTypes.takeLast(4)
.all { param -> param == "Ljava/util/concurrent/atomic/AtomicReference;" }
}
?: return PatchResultError("TextComponentSpec.createComponent not found")
val conversionContextParam = 5
val textRefParam = createComponentMethod.parameters.size - 2
createComponentMethod.addInstructions(
0,
"""
move-object/from16 v0, p$conversionContextParam
move-object/from16 v1, p$textRefParam
invoke-static {v0, v1}, Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V
"""
)
return PatchResultSuccess()
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -17,9 +17,9 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @Dependencies(dependencies = [IntegrationsPatch::class])
@Name("hide-shorts-button") @Name("hide-shorts-button")
@Description("Hides the shorts button on the navigation bar.") @Description("Hide the shorts button.")
@ShortsButtonCompatibility @ShortsButtonCompatibility
@Version("0.0.1") @Version("0.0.1")
class ShortsButtonRemoverPatch : BytecodePatch( class ShortsButtonRemoverPatch : BytecodePatch(

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.22.36", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class SponsorBlockCompatibility

View File

@@ -1,41 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.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.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("append-time-fingerprint")
@MatchingMethod(
"Liet;", "e"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object AppendTimeFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L", "L", "L"),
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
)
)

View File

@@ -1,21 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
@Name("create-video-player-seekbar-fingerprint")
@MatchingMethod(
"Lfcm;", "onDraw"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object CreateVideoPlayerSeekbarFingerprint : MethodFingerprint(
"V", null, null,
null,
listOf("timed_markers_width")
)

View File

@@ -1,24 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import org.jf.dexlib2.util.MethodUtil
@Name("next-gen-watch-layout-fingerprint")
@MatchingMethod(
"LNextGenWatchLayout;", "<init>"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object NextGenWatchLayoutFingerprint : MethodFingerprint(
"V", // constructors return void, in favour of speed of matching, this fingerprint has been added
null,
null,
null,
customFingerprint = { methodDef -> MethodUtil.isConstructor(methodDef) && methodDef.parameterTypes.size == 3 && methodDef.definingClass.endsWith("NextGenWatchLayout;") }
)

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import org.jf.dexlib2.Opcode
@Name("player-controller-set-time-reference-fingerprint")
@MatchingMethod(
"Lxqm;", "<init>"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object PlayerControllerSetTimeReferenceFingerprint : MethodFingerprint(
null, null, null,
listOf(Opcode.INVOKE_DIRECT_RANGE, Opcode.IGET_OBJECT),
listOf("Media progress reported outside media playback: ")
)

View File

@@ -1,23 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
@Name("player-init-fingerprint")
@MatchingMethod(
"Laajv;", "aG"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object PlayerInitFingerprint : MethodFingerprint(
null, null, null,
null,
strings = listOf(
"playVideo called on player response with no videoStreamingData."
),
)

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
@Name("player-overlays-layout-init-fingerprint")
@MatchingMethod(
"Lihh;", "u"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object PlayerOverlaysLayoutInitFingerprint : MethodFingerprint(
null, null, null,
null,
null,
{ methodDef -> methodDef.returnType.endsWith("YouTubePlayerOverlaysLayout;") }
)

View File

@@ -1,37 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.MethodReference
@Name("rectangle-field-invalidator-fingerprint")
@MatchingMethod(
"Lfcm;", "kY"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object RectangleFieldInvalidatorFingerprint : MethodFingerprint(
"V",
null,
null,
null,
null,
custom@{ methodDef ->
val instructions = methodDef.implementation?.instructions!!
val instructionCount = instructions.count()
// the method has definitely more than 5 instructions
if (instructionCount < 5) return@custom false
val referenceInstruction = instructions.elementAt(instructionCount - 2) // the second to last instruction
val reference = ((referenceInstruction as? ReferenceInstruction)?.reference as? MethodReference)
reference?.parameterTypes?.size == 1 && reference.name == "invalidate" // the reference is the invalidate(..) method
}
)

View File

@@ -1,23 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
@Name("seek-fingerprint")
@MatchingMethod(
"Laajv;", "af"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object SeekFingerprint : MethodFingerprint(
null,
null,
null,
null,
listOf("Attempting to seek during an ad")
)

View File

@@ -1,19 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
@Name("show-player-controls-fingerprint")
@MatchingMethod(
"LYouTubeControlsOverlay;", "ac"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object ShowPlayerControlsFingerprint : MethodFingerprint(
"V", null, listOf("Z","Z"), null, null
)

View File

@@ -1,34 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import org.jf.dexlib2.Opcode
@Name("video-length-fingerprint")
@MatchingMethod(
"Lyfh;", "z"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object VideoLengthFingerprint : MethodFingerprint(
null, null, null,
listOf(
Opcode.MOVE_RESULT_WIDE,
Opcode.CMP_LONG,
Opcode.IF_LEZ,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_WIDE,
Opcode.GOTO,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_WIDE,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL
)
)

View File

@@ -1,20 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
@Name("video-time-fingerprint")
@MatchingMethod(
"Lwyh;", "<init>"
)
@DirectPatternScanMethod
@SponsorBlockCompatibility
@Version("0.0.1")
object VideoTimeFingerprint : MethodFingerprint(
null, null, null, null,
listOf("MedialibPlayerTimeInfo{currentPositionMillis=")
)

View File

@@ -1,335 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.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.impl.BytecodeData
import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
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.ResourceIdMappingProviderResourcePatch
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.iface.instruction.*
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
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodParameter
import org.jf.dexlib2.util.MethodUtil
@Patch
@Dependencies(
dependencies = [IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class, SponsorBlockResourcePatch::class, VideoIdPatch::class]
)
@Name("sponsorblock")
@Description("Integrate SponsorBlock.")
@SponsorBlockCompatibility
@Version("0.0.1")
class SponsorBlockBytecodePatch : BytecodePatch(
listOf(
PlayerControllerSetTimeReferenceFingerprint,
CreateVideoPlayerSeekbarFingerprint,
VideoTimeFingerprint,
NextGenWatchLayoutFingerprint,
AppendTimeFingerprint,
PlayerInitFingerprint,
PlayerOverlaysLayoutInitFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {/*
Set current video time
*/
val referenceResult = PlayerControllerSetTimeReferenceFingerprint.result!!
val playerControllerSetTimeMethod =
data.toMethodWalker(referenceResult.method).nextMethod(referenceResult.patternScanResult!!.startIndex, true)
.getMethod() as MutableMethod
playerControllerSetTimeMethod.addInstruction(
2,
"invoke-static {p1, p2}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setCurrentVideoTime(J)V"
)
/*
Set current video time high precision
*/
val constructorFingerprint =
object : MethodFingerprint("V", null, listOf("J", "J", "J", "J", "I", "L"), null) {}
constructorFingerprint.resolve(data, VideoTimeFingerprint.result!!.classDef)
val constructor = constructorFingerprint.result!!.mutableMethod
constructor.addInstruction(
0,
"invoke-static {p1, p2}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setCurrentVideoTimeHighPrecision(J)V"
)
/*
Set current video id
*/
VideoIdPatch.injectCall("Lapp/revanced/integrations/sponsorblock/PlayerController;->setCurrentVideoId(Ljava/lang/String;)V")
/*
Seekbar drawing
*/
val seekbarSignatureResult = CreateVideoPlayerSeekbarFingerprint.result!!
val seekbarMethod = seekbarSignatureResult.mutableMethod
val seekbarMethodInstructions = seekbarMethod.implementation!!.instructions
/*
Get the instance of the seekbar rectangle
*/
seekbarMethod.addInstruction(
1,
"invoke-static {v0}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setSponsorBarRect(Ljava/lang/Object;)V"
)
for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_STATIC) continue
val invokeInstruction = instruction as Instruction35c
if ((invokeInstruction.reference as MethodReference).name != "round") continue
val insertIndex = index + 2
// set the thickness of the segment
seekbarMethod.addInstruction(
insertIndex,
"invoke-static {v${invokeInstruction.registerC}}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setSponsorBarThickness(I)V"
)
break
}
/*
Set rectangle absolute left and right positions
*/
val drawRectangleInstructions = seekbarMethodInstructions.filter {
it is ReferenceInstruction && (it.reference as? MethodReference)?.name == "drawRect" && it is FiveRegisterInstruction
}.map { // TODO: improve code
seekbarMethodInstructions.indexOf(it) to (it as FiveRegisterInstruction).registerD
}
val (indexRight, rectangleRightRegister) = drawRectangleInstructions[0]
val (indexLeft, rectangleLeftRegister) = drawRectangleInstructions[3]
// order of operation is important here due to the code above which has to be improved
// 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"
)
seekbarMethod.addInstruction(
indexRight + 1,
"invoke-static {v$rectangleRightRegister}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setSponsorBarAbsoluteRight(Landroid/graphics/Rect;)V"
)
/*
Draw segment
*/
val drawSegmentInstructionInsertIndex = (seekbarMethodInstructions.size - 1 - 2)
val (canvasInstance, centerY) = (seekbarMethodInstructions[drawSegmentInstructionInsertIndex] as FiveRegisterInstruction).let {
it.registerC to it.registerE
}
seekbarMethod.addInstruction(
drawSegmentInstructionInsertIndex - 1,
"invoke-static {v$canvasInstance, v$centerY}, Lapp/revanced/integrations/sponsorblock/PlayerController;->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
)
/*
Set video length
*/
VideoLengthFingerprint.resolve(data, seekbarSignatureResult.classDef)
val videoLengthMethodResult = VideoLengthFingerprint.result!!
val videoLengthMethod = videoLengthMethodResult.mutableMethod
val videoLengthMethodInstructions = videoLengthMethod.implementation!!.instructions
val videoLengthRegister =
(videoLengthMethodInstructions[videoLengthMethodResult.patternScanResult!!.endIndex - 2] as OneRegisterInstruction).registerA
val dummyRegisterForLong =
videoLengthRegister + 1 // this is required for long values since they are 64 bit wide
videoLengthMethod.addInstruction(
videoLengthMethodResult.patternScanResult!!.endIndex,
"invoke-static {v$videoLengthRegister, v$dummyRegisterForLong}, Lapp/revanced/integrations/sponsorblock/PlayerController;->setVideoLength(J)V"
)
/*
Voting & Shield button
*/
ShowPlayerControlsFingerprint.resolve(data, data.classes.find { it.type.endsWith("YouTubeControlsOverlay;") }!!)
val controlsMethodResult = ShowPlayerControlsFingerprint.result!!
val controlsLayoutStubResourceId =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id
val zoomOverlayResourceId =
ResourceIdMappingProviderResourcePatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id
methods@ for (method in controlsMethodResult.mutableClass.methods) {
val instructions = method.implementation?.instructions!!
instructions@ for ((index, instruction) in instructions.withIndex()) {
// search for method which inflates the controls layout view
if (instruction.opcode != Opcode.CONST) continue@instructions
when ((instruction as NarrowLiteralInstruction).wideLiteral) {
controlsLayoutStubResourceId -> {
// replace the view with the YouTubeControlsOverlay
val moveResultInstructionIndex = index + 5
val inflatedViewRegister =
(instructions[moveResultInstructionIndex] as OneRegisterInstruction).registerA
// initialize with the player overlay object
method.addInstructions(
moveResultInstructionIndex + 1, // insert right after moving the view to the register and use that register
"""
invoke-static {v$inflatedViewRegister}, Lapp/revanced/integrations/sponsorblock/ShieldButton;->initialize(Ljava/lang/Object;)V
invoke-static {v$inflatedViewRegister}, Lapp/revanced/integrations/sponsorblock/VotingButton;->initialize(Ljava/lang/Object;)V
"""
)
}
zoomOverlayResourceId -> {
val invertVisibilityMethod =
data.toMethodWalker(method).nextMethod(index - 6, true).getMethod() as MutableMethod
// change visibility of the buttons
invertVisibilityMethod.addInstructions(
0, """
invoke-static {p1}, Lapp/revanced/integrations/sponsorblock/ShieldButton;->changeVisibilityNegatedImmediate(Z)V
invoke-static {p1}, Lapp/revanced/integrations/sponsorblock/VotingButton;->changeVisibilityNegatedImmediate(Z)V
""".trimIndent()
)
}
}
}
}
// change visibility of the buttons
controlsMethodResult.mutableMethod.addInstructions(
0, """
invoke-static {p1}, Lapp/revanced/integrations/sponsorblock/ShieldButton;->changeVisibility(Z)V
invoke-static {p1}, Lapp/revanced/integrations/sponsorblock/VotingButton;->changeVisibility(Z)V
""".trimIndent()
)
// set SegmentHelperLayout.context to the player layout instance
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"
)
// append the new time to the player layout
val appendTimeFingerprintResult = AppendTimeFingerprint.result!!
val appendTimePatternScanStartIndex = appendTimeFingerprintResult.patternScanResult!!.startIndex
val targetRegister =
(appendTimeFingerprintResult.method.implementation!!.instructions.elementAt(appendTimePatternScanStartIndex + 1) as OneRegisterInstruction).registerA
appendTimeFingerprintResult.mutableMethod.addInstructions(
appendTimePatternScanStartIndex + 2, """
invoke-static {v$targetRegister}, Lapp/revanced/integrations/sponsorblock/SponsorBlockUtils;->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister
"""
)
// initialize the player controller
val initFingerprintResult = PlayerInitFingerprint.result!!
val initInstanceRegister = 0
initFingerprintResult.mutableClass.methods.first { MethodUtil.isConstructor(it) }.addInstruction(
4, // after super class invoke
"invoke-static {v$initInstanceRegister}, Lapp/revanced/integrations/sponsorblock/PlayerController;->onCreate(Ljava/lang/Object;)V"
)
// initialize the sponsorblock view
PlayerOverlaysLayoutInitFingerprint.result!!.mutableMethod.addInstruction(
6, // after inflating the view
"invoke-static {p0}, Lapp/revanced/integrations/sponsorblock/player/ui/SponsorBlockView;->initialize(Ljava/lang/Object;)V"
)
// lastly create hooks for the player controller
// get original seek method
SeekFingerprint.resolve(data, initFingerprintResult.classDef)
val seekFingerprintResultMethod = SeekFingerprint.result!!.method
// get enum type for the seek helper method
val seekSourceEnumType = seekFingerprintResultMethod.parameterTypes[1].toString()
// create helper method
val seekHelperMethod = ImmutableMethod(
seekFingerprintResultMethod.definingClass,
"seekHelper",
listOf(ImmutableMethodParameter("J", null, "time")),
"Z",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null, null,
MutableMethodImplementation(4)
).toMutable()
// insert helper method instructions
seekHelperMethod.addInstructions(
0,
"""
sget-object v0, $seekSourceEnumType->a:$seekSourceEnumType
invoke-virtual {p0, p1, p2, v0}, ${seekFingerprintResultMethod.definingClass}->${seekFingerprintResultMethod.name}(J$seekSourceEnumType)Z
move-result p1
return p1
"""
)
// add the helper method to the original class
initFingerprintResult.mutableClass.methods.add(seekHelperMethod)
// get rectangle field name
RectangleFieldInvalidatorFingerprint.resolve(data, seekbarSignatureResult.classDef)
val rectangleFieldInvalidatorInstructions =
RectangleFieldInvalidatorFingerprint.result!!.method.implementation!!.instructions
val rectangleFieldName =
((rectangleFieldInvalidatorInstructions.elementAt(rectangleFieldInvalidatorInstructions.count() - 3) as ReferenceInstruction).reference as FieldReference).name
// get the player controller class from the integrations
val playerControllerMethods =
data.proxy(data.classes.first { it.type.endsWith("PlayerController;") }).resolve().methods
// get the method which contain the "replaceMe" strings
val replaceMeMethods =
playerControllerMethods.filter { it.name == "onCreate" || it.name == "setSponsorBarRect" }
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
val register = (instruction as OneRegisterInstruction).registerA
this.replaceInstruction(
index, "const-string v$register, \"$with\""
)
}
// replace the "replaceMeWith*" strings
for (method in replaceMeMethods) {
for ((index, it) in method.implementation!!.instructions.withIndex()) {
if (it.opcode.ordinal != Opcode.CONST_STRING.ordinal) continue
when (((it as ReferenceInstruction).reference as StringReference).string) {
"replaceMeWithsetSponsorBarRect" ->
method.replaceStringInstruction(index, it, rectangleFieldName)
"replaceMeWithsetMillisecondMethod" ->
method.replaceStringInstruction(index, it, "seekHelper")
}
}
}
// TODO: isSBChannelWhitelisting implementation
return PatchResultSuccess()
}
}

View File

@@ -1,128 +0,0 @@
package app.revanced.patches.youtube.layout.sponsorblock.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.DomFileEditor
import app.revanced.patcher.data.impl.ResourceData
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import java.io.OutputStream
import java.nio.file.Files
@Name("sponsorblock-resource-patch")
@SponsorBlockCompatibility
@Dependencies([FixLocaleConfigErrorPatch::class])
@Version("0.0.1")
class SponsorBlockResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult {
val classLoader = this.javaClass.classLoader
/*
merge SponsorBlock strings to main strings
*/
val stringsResourcePath = "values/strings.xml"
val stringsResourceInputStream = classLoader.getResourceAsStream("sponsorblock/$stringsResourcePath")!!
// copy nodes from the resources node to the real resource node
"resources".copyXmlNode(
data.xmlEditor[stringsResourceInputStream, OutputStream.nullOutputStream()],
data.xmlEditor["res/$stringsResourcePath"]
).close() // close afterwards
/*
merge SponsorBlock drawables to main drawables
*/
val drawables = "drawable" to arrayOf(
"ic_sb_adjust",
"ic_sb_compare",
"ic_sb_edit",
"ic_sb_logo",
"ic_sb_publish",
"ic_sb_voting"
)
val layouts = "layout" to arrayOf(
"inline_sponsor_overlay", "new_segment", "skip_sponsor_button"
)
// collect resources
val xmlResources = arrayOf(drawables, layouts)
// write resources
xmlResources.forEach { (path, resourceNames) ->
resourceNames.forEach { name ->
val relativePath = "$path/$name.xml"
Files.copy(
classLoader.getResourceAsStream("sponsorblock/$relativePath")!!,
data["res"].resolve(relativePath).toPath()
)
}
}
/*
merge xml nodes from the host to their real xml files
*/
// collect all host resources
val hostingXmlResources = mapOf("layout" to arrayOf("youtube_controls_layout"))
// copy nodes from host resources to their real xml files
hostingXmlResources.forEach { (path, resources) ->
resources.forEach { resource ->
val hostingResourceStream = classLoader.getResourceAsStream("sponsorblock/host/$path/$resource.xml")!!
val targetXmlEditor = data.xmlEditor["res/$path/$resource.xml"]
"RelativeLayout".copyXmlNode(
data.xmlEditor[hostingResourceStream, OutputStream.nullOutputStream()],
targetXmlEditor
).also {
val children = targetXmlEditor.file.getElementsByTagName("RelativeLayout").item(0).childNodes
// Replace the startOf with the voting button view so that the button does not overlap
for (i in 1 until children.length) {
val view = children.item(i)
// Replace the attribute for a specific node only
if (!(view.hasAttributes() && view.attributes.getNamedItem("android:id").nodeValue.endsWith("live_chat_overlay_button"))) continue
// voting button id from the voting button view from the youtube_controls_layout.xml host file
val votingButtonId = "@+id/voting_button"
view.attributes.getNamedItem("android:layout_toStartOf").nodeValue = votingButtonId
break
}
}.close() // close afterwards
}
}
return PatchResultSuccess()
}
/**
* Copies the specified node of the source [DomFileEditor] to the target [DomFileEditor].
* @param source the source [DomFileEditor].
* @param target the target [DomFileEditor]-
*/
private fun String.copyXmlNode(source: DomFileEditor, target: DomFileEditor): AutoCloseable {
val hostNodes = source.file.getElementsByTagName(this).item(0).childNodes
val destinationResourceFile = target.file
val destinationNode = destinationResourceFile.getElementsByTagName(this).item(0)
for (index in 0 until hostNodes.length) {
val node = hostNodes.item(index).cloneNode(true)
destinationResourceFile.adoptNode(node)
destinationNode.appendChild(node)
}
return AutoCloseable {
source.close()
target.close()
}
}
}

View File

@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [Package(
"com.google.android.youtube", arrayOf("17.24.34", "17.24.35", "17.25.34", "17.26.35", "17.27.39") "com.google.android.youtube", arrayOf("17.24.34", "17.24.35", "17.25.34")
)] )]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)

View File

@@ -6,6 +6,7 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.extensions.removeInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultError
@@ -19,9 +20,9 @@ import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkF
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch @Patch
@Dependencies([IntegrationsPatch::class]) @Dependencies(dependencies = [IntegrationsPatch::class])
@Name("hide-watermark") @Name("hide-watermark")
@Description("Hides creator's watermarks on videos.") @Description("Hide Watermark on the page.")
@HideWatermarkCompatibility @HideWatermarkCompatibility
@Version("0.0.1") @Version("0.0.1")
class HideWatermarkPatch : BytecodePatch( class HideWatermarkPatch : BytecodePatch(

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.youtube.layout.widesearchbar.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class WideSearchbarCompatibility

View File

@@ -1,48 +0,0 @@
package app.revanced.patches.youtube.layout.widesearchbar.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.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("wide-searchbar-methodone-fingerprint")
@MatchingMethod(
"Ljkg;", "i"
)
@DirectPatternScanMethod
@WideSearchbarCompatibility
@Version("0.0.1")
/*
This finds the following method:
public final View i(akrl akrlVar, adpd adpdVar) {
}
Method we search for is located in smali now.
See:
.method public final i(Lakrl;Ladpd;)Landroid/view/View;
iget-object v0, p0, Ljkg;->a:Landroid/app/Activity;
invoke-static {v0}, Landroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater;
move-result-object v0
iget-object v1, p0, Ljkg;->g:Ljis;
const/4 v2, 0x0
invoke-interface {v1, v2}, Ljis;->h(Z)V
iget-object p1, p1, Lakrl;->f:Lahnq;
if-nez p1, :cond_12
sget-object p1, Lahnq;->a:Lahnq;
:cond_12
iget-object v1, p0, Ljkg;->x:Ltxm;
invoke-static {v1}, Lfbn;->aF(Ltxm;)Z //THIS IS WHAT WE SEARCH FOR (Method fbn.aF)
move-result v1
*/
object WideSearchbarOneFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L"), listOf(Opcode.IF_NEZ, Opcode.SGET_OBJECT, Opcode.IGET_OBJECT, Opcode.INVOKE_STATIC),
null, null
)

View File

@@ -1,47 +0,0 @@
package app.revanced.patches.youtube.layout.widesearchbar.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
@Name("wide-searchbar-methodone-parent-fingerprint")
@MatchingMethod(
"Ljkg;", "l"
)
@FuzzyPatternScanMethod(3)
@WideSearchbarCompatibility
@Version("0.0.1")
/*
* This finds the following method:
private final void l(PaneDescriptor paneDescriptor) {
Class cls = null;
ahat f = paneDescriptor != null ? paneDescriptor.f() : null;
if (paneDescriptor != null) {
cls = paneDescriptor.a;
}
ftu k = k();
if ((k == null || !k.bk()) && ((!frx.k(f) && !((Boolean) aqer.S(this.n).X(new fac(this, f, 19)).K(irx.i).aH(false)).booleanValue()) || (f != null && f.qA(ReelWatchEndpointOuterClass$ReelWatchEndpoint.reelWatchEndpoint)))) {
String j = frx.j(f);
if ((j != null && ("FEhistory".equals(j) || "FEmy_videos".equals(j) || "FEpurchases".equals(j) || j.startsWith("VL"))) || cls == this.I.E() || cls == this.G.a) {
this.F = 3;
return;
} else {
this.F = 2;
return;
}
}
this.F = 1;
}
*/
object WideSearchbarOneParentFingerprint : MethodFingerprint(
"V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("L"), null,
listOf("FEhistory", "FEmy_videos", "FEpurchases")
)

View File

@@ -1,49 +0,0 @@
package app.revanced.patches.youtube.layout.widesearchbar.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.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("wide-searchbar-methodtwo-fingerprint")
@MatchingMethod(
"Lkrf;", "h"
)
@DirectPatternScanMethod
@WideSearchbarCompatibility
@Version("0.0.1")
/*
public static jis h(Context context, txm txmVar, uag uagVar, txp txpVar) {
return fbn.aB(txmVar) ? new jhx(context, txmVar, uagVar, txpVar) : jis.d;
}
Method we search for is located in smali now.
See:
.method public static h(Landroid/content/Context;Ltxm;Luag;Ltxp;)Ljis;
invoke-static {p1}, Lfbn;->aB(Ltxm;)Z //this is the method we want to change. fbn.aB
move-result v0
if-eqz v0, :cond_c
new-instance v0, Ljhx;
invoke-direct {v0, p0, p1, p2, p3}, Ljhx;-><init>(Landroid/content/Context;Ltxm;Luag;Ltxp;)V
goto :goto_e
:cond_c
sget-object v0, Ljis;->d:Ljis;
:goto_e
return-object v0
.end method
*/
object WideSearchbarTwoFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_EQZ, Opcode.NEW_INSTANCE
),
null, null
)

View File

@@ -1,35 +0,0 @@
package app.revanced.patches.youtube.layout.widesearchbar.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import org.jf.dexlib2.AccessFlags
@Name("wide-searchbar-methodtwo-parent-fingerprint")
@MatchingMethod(
"Lkrf;", "i"
)
@FuzzyPatternScanMethod(3)
@WideSearchbarCompatibility
@Version("0.0.1")
/*
This finds following method:
public static ies i(br brVar) {
bp f = brVar.getSupportFragmentManager().f("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT");
if (f != null) {
return (kga) f;
}
return new kga();
}
*/
object WideSearchbarTwoParentFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), null,
listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT")
)

View File

@@ -1,105 +0,0 @@
package app.revanced.patches.youtube.layout.widesearchbar.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarOneFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarOneParentFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoFingerprint
import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch(include = false)
@Dependencies([IntegrationsPatch::class])
@Name("enable-wide-searchbar")
@Description("Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.")
@WideSearchbarCompatibility
@Version("0.0.1")
class WideSearchbarPatch : BytecodePatch(
listOf(
WideSearchbarOneParentFingerprint, WideSearchbarTwoParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
WideSearchbarOneFingerprint.resolve(data, WideSearchbarOneParentFingerprint.result!!.classDef)
WideSearchbarTwoFingerprint.resolve(data, WideSearchbarTwoParentFingerprint.result!!.classDef)
val resultOne = WideSearchbarOneFingerprint.result
//This should be the method aF in class fbn
val targetMethodOne =
data.toMethodWalker(resultOne!!.method).nextMethod(resultOne.patternScanResult!!.endIndex, true).getMethod() as MutableMethod
//Since both methods have the same smali code, inject instructions using a method.
addInstructions(targetMethodOne)
val resultTwo = WideSearchbarTwoFingerprint.result
//This should be the method aB in class fbn
val targetMethodTwo =
data.toMethodWalker(resultTwo!!.method).nextMethod(resultTwo.patternScanResult!!.startIndex, true).getMethod() as MutableMethod
//Since both methods have the same smali code, inject instructions using a method.
addInstructions(targetMethodTwo)
return PatchResultSuccess()
}
private fun addInstructions(method: MutableMethod) {
val index = method.implementation!!.instructions.size - 1
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
"""
)
}
//targetMethodOne: in class fbn
/*
.method public static aF(Ltxm;)Z
invoke-virtual {p0}, Ltxm;->b()Lahah;
move-result-object p0
iget-object p0, p0, Lahah;->e:Lakfd;
if-nez p0, :cond_a
sget-object p0, Lakfd;->a:Lakfd;
:cond_a
iget-boolean p0, p0, Lakfd;->V:Z
//added code here:
invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
//original code here:
return p0
.end method
*/
//targetMethodTwo: in class fbn
/*
.method public static aB(Ltxm;)Z
invoke-virtual {p0}, Ltxm;->b()Lahah;
move-result-object p0
iget-object p0, p0, Lahah;->e:Lakfd;
if-nez p0, :cond_a
sget-object p0, Lakfd;->a:Lakfd;
:cond_a
iget-boolean p0, p0, Lakfd;->y:Z
//added code here:
invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z
move-result p0
//original code here:
return p0
.end method
*/
}

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.youtube.misc.autorepeat.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.24.35", "17.25.34", "17.26.35", "17.27.39")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class AutoRepeatCompatibility

View File

@@ -1,32 +0,0 @@
package app.revanced.patches.youtube.misc.autorepeat.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.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility
import org.jf.dexlib2.AccessFlags
@Name("auto-repeat-fingerprint")
@MatchingMethod(
"Laamp;", "ae"
)
@FuzzyPatternScanMethod(2)
@AutoRepeatCompatibility
@Version("0.0.1")
//Finds method:
/*
public final void ae() {
aq(aabj.ENDED);
}
*/
object AutoRepeatFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
null,
null,
customFingerprint = { methodDef -> methodDef.implementation!!.instructions.count() == 3 && methodDef.annotations.isEmpty()}
)

View File

@@ -1,35 +0,0 @@
package app.revanced.patches.youtube.misc.autorepeat.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility
import org.jf.dexlib2.AccessFlags
@Name("auto-repeat-parent-fingerprint")
@MatchingMethod(
"Laamp;", "E"
)
@FuzzyPatternScanMethod(2)
@AutoRepeatCompatibility
@Version("0.0.1")
//This Fingerprints finds the play() method needed to be called when AutoRepeatPatch.shouldAutoRepeat() == true
/*
public final void E() {
Stuff happens
String str = "play() called when the player wasn't loaded.";
String str2 = "play() blocked because Background Playability failed";
Stuff happens again
}
*/
object AutoRepeatParentFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
null,
listOf("play() called when the player wasn't loaded.", "play() blocked because Background Playability failed"),
null
)

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