Compare commits

...

49 Commits

Author SHA1 Message Date
semantic-release-bot
1023936a26 chore(release): 2.36.2 [skip ci]
## [2.36.2](https://github.com/revanced/revanced-patches/compare/v2.36.1...v2.36.2) (2022-08-14)

### Bug Fixes

* disable cast modules in YouTube Music ([#337](https://github.com/revanced/revanced-patches/issues/337)) ([98e5dbc](98e5dbcc73))
2022-08-14 21:15:11 +00:00
Canny
98e5dbcc73 fix: disable cast modules in YouTube Music (#337) 2022-08-14 23:13:16 +02:00
semantic-release-bot
353806828b chore(release): 2.36.1 [skip ci]
## [2.36.1](https://github.com/revanced/revanced-patches/compare/v2.36.0...v2.36.1) (2022-08-14)

### Bug Fixes

* add missing switch for tablet mini-player ([1ad69e3](1ad69e350c))
2022-08-14 20:36:40 +00:00
oSumAtrIX
1ad69e350c fix: add missing switch for tablet mini-player 2022-08-14 22:34:44 +02:00
semantic-release-bot
42c562cff7 chore(release): 2.36.0 [skip ci]
# [2.36.0](https://github.com/revanced/revanced-patches/compare/v2.35.0...v2.36.0) (2022-08-14)

### Features

* `swipe-controls` override volume button behaviour ([#285](https://github.com/revanced/revanced-patches/issues/285)) ([155121f](155121f891))
2022-08-14 20:22:07 +00:00
Chris
155121f891 feat: swipe-controls override volume button behaviour (#285) 2022-08-14 22:19:54 +02:00
semantic-release-bot
c684a1c846 chore(release): 2.35.0 [skip ci]
# [2.35.0](https://github.com/revanced/revanced-patches/compare/v2.34.0...v2.35.0) (2022-08-14)

### Features

* `tiktok-ads` patch ([#335](https://github.com/revanced/revanced-patches/issues/335)) ([49ddc0a](49ddc0a2ed))
2022-08-14 20:18:06 +00:00
oSumAtrIX
49ddc0a2ed feat: tiktok-ads patch (#335) 2022-08-14 22:16:25 +02:00
semantic-release-bot
221b61acc7 chore(release): 2.34.0 [skip ci]
# [2.34.0](https://github.com/revanced/revanced-patches/compare/v2.33.2...v2.34.0) (2022-08-14)

### Features

* `tablet-mini-player` patch ([aab39cb](aab39cbe93))
2022-08-14 15:35:33 +00:00
oSumAtrIX
c133d495c3 build: bump patcher dependency version 2022-08-14 17:33:13 +02:00
oSumAtrIX
aab39cbe93 feat: tablet-mini-player patch 2022-08-14 17:32:32 +02:00
semantic-release-bot
bdab92faf2 chore(release): 2.33.2 [skip ci]
## [2.33.2](https://github.com/revanced/revanced-patches/compare/v2.33.1...v2.33.2) (2022-08-07)
2022-08-07 20:42:34 +00:00
oSumAtrIX
50acd3d3b5 refactor: remove unused parameter 2022-08-07 22:40:07 +02:00
oSumAtrIX
49a369a340 refactor: un-shadow variable name 2022-08-07 22:39:53 +02:00
oSumAtrIX
be8620bf91 build: bump patcher dependency version 2022-08-07 22:36:02 +02:00
semantic-release-bot
32ed4c9f04 chore(release): 2.33.1 [skip ci]
## [2.33.1](https://github.com/revanced/revanced-patches/compare/v2.33.0...v2.33.1) (2022-08-07)

### Bug Fixes

* spoof `X-Android-Cert` of Firebase `authToken` api request ([#315](https://github.com/revanced/revanced-patches/issues/315)) ([9c44497](9c44497d40))
2022-08-07 10:44:47 +00:00
Itroublve
9c44497d40 fix: spoof X-Android-Cert of Firebase authToken api request (#315) 2022-08-07 12:42:39 +02:00
semantic-release-bot
8e604139e3 chore(release): 2.33.0 [skip ci]
# [2.33.0](https://github.com/revanced/revanced-patches/compare/v2.32.1...v2.33.0) (2022-08-06)

### Features

* bump music patches to 5.17.51 ([#307](https://github.com/revanced/revanced-patches/issues/307)) ([3de3a82](3de3a82afb))
2022-08-06 23:04:00 +00:00
epicsampler
3de3a82afb feat: bump music patches to 5.17.51 (#307) 2022-08-07 01:02:08 +02:00
oSumAtrIX
d39fb7ca03 refactor: use approriate description 2022-08-05 03:48:03 +02:00
semantic-release-bot
2d995d3757 chore(release): 2.32.1 [skip ci]
## [2.32.1](https://github.com/revanced/revanced-patches/compare/v2.32.0...v2.32.1) (2022-08-04)

### Bug Fixes

* incorrect compatibilty attribute ([#296](https://github.com/revanced/revanced-patches/issues/296)) ([464c980](464c98093a))
2022-08-04 19:55:13 +00:00
Itroublve
464c98093a fix: incorrect compatibilty attribute (#296) 2022-08-04 21:53:29 +02:00
semantic-release-bot
6ac5ed441f chore(release): 2.32.0 [skip ci]
# [2.32.0](https://github.com/revanced/revanced-patches/compare/v2.31.0...v2.32.0) (2022-08-04)

### Features

* `promo-code-unlock` patch ([#292](https://github.com/revanced/revanced-patches/issues/292)) ([7925ca9](7925ca97c4))
2022-08-04 17:05:39 +00:00
Technikte
7925ca97c4 feat: promo-code-unlock patch (#292) 2022-08-04 19:03:56 +02:00
semantic-release-bot
0c5f117d5d chore(release): 2.31.0 [skip ci]
# [2.31.0](https://github.com/revanced/revanced-patches/compare/v2.30.1...v2.31.0) (2022-08-03)

### Features

* remove `force-vp9-codec` patch ([#287](https://github.com/revanced/revanced-patches/issues/287)) ([6ab475c](6ab475c284))
2022-08-03 18:30:49 +00:00
epicsampler
6ab475c284 feat: remove force-vp9-codec patch (#287) 2022-08-03 20:28:39 +02:00
semantic-release-bot
75ac69455b chore(release): 2.30.1 [skip ci]
## [2.30.1](https://github.com/revanced/revanced-patches/compare/v2.30.0...v2.30.1) (2022-08-03)

### Bug Fixes

* migrate to new patcher api ([e42043b](e42043b939))
2022-08-03 01:56:55 +00:00
oSumAtrIX
e42043b939 fix: migrate to new patcher api 2022-08-03 03:53:35 +02:00
semantic-release-bot
5237c3a1a6 chore(release): 2.30.0 [skip ci]
# [2.30.0](https://github.com/revanced/revanced-patches/compare/v2.29.0...v2.30.0) (2022-08-03)

### Bug Fixes

* incorrect fingerprint version [skip ci] ([a9abab9](a9abab97d7))
* rollback to `Dependencies` annotation ([f82aae9](f82aae930b))

### Features

* set the correct theme of the settings screen ([7d6f205](7d6f205fd9))
2022-08-03 01:11:48 +00:00
oSumAtrIX
7d6f205fd9 feat: set the correct theme of the settings screen 2022-08-03 03:09:52 +02:00
oSumAtrIX
f82aae930b fix: rollback to Dependencies annotation 2022-08-03 03:09:39 +02:00
oSumAtrIX
83b11c92af refactor: remove unused annotation [skip ci] 2022-08-03 02:23:27 +02:00
oSumAtrIX
a9abab97d7 fix: incorrect fingerprint version [skip ci] 2022-08-03 02:01:56 +02:00
semantic-release-bot
a70da4f6c4 chore(release): 2.29.0 [skip ci]
# [2.29.0](https://github.com/revanced/revanced-patches/compare/v2.28.2...v2.29.0) (2022-08-02)

### Features

* add "Application Icon Path" option to branding ([e53b490](e53b490edf))
* add "Application Name" option to branding and move renaming to CustomBrandingPatch.kt ([19cc4a3](19cc4a3e91))
2022-08-02 21:51:01 +00:00
Sculas
e53b490edf feat: add "Application Icon Path" option to branding 2022-08-02 23:48:51 +02:00
Sculas
bfe995f635 build: update patcher lib to 3.3.0 2022-08-02 23:40:13 +02:00
Sculas
19cc4a3e91 feat: add "Application Name" option to branding and move renaming to CustomBrandingPatch.kt 2022-08-02 21:28:22 +02:00
Sculas
16f6486258 build: update patcher lib to 3.0.0 2022-08-02 21:15:43 +02:00
Sculas
47360ea3b7 refactor: migrate CustomBrandingPatch.kt to DependsOn 2022-08-02 20:24:19 +02:00
Sculas
5c5b3d562d refactor: migrate MicroGResourcePatch.kt to DependsOn 2022-08-02 20:22:57 +02:00
Sculas
a62316a8c8 refactor: cleanup MicroGResourcePatch.kt 2022-08-02 20:21:14 +02:00
semantic-release-bot
14f7d514d2 chore(release): 2.28.2 [skip ci]
## [2.28.2](https://github.com/revanced/revanced-patches/compare/v2.28.1...v2.28.2) (2022-08-02)

### Bug Fixes

* remove requirement for solution [skip ci] ([#271](https://github.com/revanced/revanced-patches/issues/271)) ([9ae3d05](9ae3d0546c))
2022-08-02 01:16:42 +00:00
oSumAtrIX
78d901338f build: bump patcher dependency version 2022-08-02 03:14:28 +02:00
Robert
9ae3d0546c fix: remove requirement for solution [skip ci] (#271) 2022-08-01 13:07:47 +02:00
oSumAtrIX
3076a16d14 refactor: use ResourceUtils.copyXmlNode 2022-08-01 04:13:51 +02:00
semantic-release-bot
f8e1f2fe18 chore(release): 2.28.1 [skip ci]
## [2.28.1](https://github.com/revanced/revanced-patches/compare/v2.28.0...v2.28.1) (2022-07-31)

### Bug Fixes

* add missing permission to reboot app ([#260](https://github.com/revanced/revanced-patches/issues/260)) ([a9611f3](a9611f304e))
2022-07-31 18:43:15 +00:00
Joey Peter
a9611f304e fix: add missing permission to reboot app (#260) 2022-07-31 20:41:35 +02:00
semantic-release-bot
7c0e183df5 chore(release): 2.28.0 [skip ci]
# [2.28.0](https://github.com/revanced/revanced-patches/compare/v2.27.0...v2.28.0) (2022-07-31)

### Features

* add `custom-video-buffer` patch ([15e1ced](15e1ced2c9))
2022-07-31 10:36:58 +00:00
Joey Peter
15e1ced2c9 feat: add custom-video-buffer patch 2022-07-31 12:34:49 +02:00
88 changed files with 1250 additions and 492 deletions

View File

@@ -52,10 +52,10 @@ body:
label: Solution
description: If applicable, add a possible solution.
validations:
required: true
required: false
- type: textarea
attributes:
label: Additional context
description: Add additional context here.
validations:
required: false
required: false

View File

@@ -1,3 +1,124 @@
## [2.36.2](https://github.com/revanced/revanced-patches/compare/v2.36.1...v2.36.2) (2022-08-14)
### Bug Fixes
* disable cast modules in YouTube Music ([#337](https://github.com/revanced/revanced-patches/issues/337)) ([86eaba8](https://github.com/revanced/revanced-patches/commit/86eaba8248100987f46540a224956099bcf9da2c))
## [2.36.1](https://github.com/revanced/revanced-patches/compare/v2.36.0...v2.36.1) (2022-08-14)
### Bug Fixes
* add missing switch for tablet mini-player ([b824d35](https://github.com/revanced/revanced-patches/commit/b824d35960df9e99c2a2d248356c3c9342cfe130))
# [2.36.0](https://github.com/revanced/revanced-patches/compare/v2.35.0...v2.36.0) (2022-08-14)
### Features
* `swipe-controls` override volume button behaviour ([#285](https://github.com/revanced/revanced-patches/issues/285)) ([69465f3](https://github.com/revanced/revanced-patches/commit/69465f3a9934973a2449605a248a462510e10ff6))
# [2.35.0](https://github.com/revanced/revanced-patches/compare/v2.34.0...v2.35.0) (2022-08-14)
### Features
* `tiktok-ads` patch ([#335](https://github.com/revanced/revanced-patches/issues/335)) ([81bef57](https://github.com/revanced/revanced-patches/commit/81bef57742bfaefcdfe02fd290cca6923341149a))
# [2.34.0](https://github.com/revanced/revanced-patches/compare/v2.33.2...v2.34.0) (2022-08-14)
### Features
* `tablet-mini-player` patch ([dae41f1](https://github.com/revanced/revanced-patches/commit/dae41f1c59d26d00b1ba821dbe1521e68226f47c))
## [2.33.2](https://github.com/revanced/revanced-patches/compare/v2.33.1...v2.33.2) (2022-08-07)
## [2.33.1](https://github.com/revanced/revanced-patches/compare/v2.33.0...v2.33.1) (2022-08-07)
### Bug Fixes
* spoof `X-Android-Cert` of Firebase `authToken` api request ([#315](https://github.com/revanced/revanced-patches/issues/315)) ([c81d61f](https://github.com/revanced/revanced-patches/commit/c81d61f685449590473fa5205e7709f81872a9b9))
# [2.33.0](https://github.com/revanced/revanced-patches/compare/v2.32.1...v2.33.0) (2022-08-06)
### Features
* bump music patches to 5.17.51 ([#307](https://github.com/revanced/revanced-patches/issues/307)) ([c303589](https://github.com/revanced/revanced-patches/commit/c303589bd8d1956ce2e3c4c285d45a648b5db30f))
## [2.32.1](https://github.com/revanced/revanced-patches/compare/v2.32.0...v2.32.1) (2022-08-04)
### Bug Fixes
* incorrect compatibilty attribute ([#296](https://github.com/revanced/revanced-patches/issues/296)) ([0ab3e97](https://github.com/revanced/revanced-patches/commit/0ab3e9724157c628555964273c6b65f9f48f9664))
# [2.32.0](https://github.com/revanced/revanced-patches/compare/v2.31.0...v2.32.0) (2022-08-04)
### Features
* `promo-code-unlock` patch ([#292](https://github.com/revanced/revanced-patches/issues/292)) ([d5df2e6](https://github.com/revanced/revanced-patches/commit/d5df2e68f47cbb3d374b8ce24769872959014051))
# [2.31.0](https://github.com/revanced/revanced-patches/compare/v2.30.1...v2.31.0) (2022-08-03)
### Features
* remove `force-vp9-codec` patch ([#287](https://github.com/revanced/revanced-patches/issues/287)) ([e428978](https://github.com/revanced/revanced-patches/commit/e42897801b20e7439969954753e2c15c85eb41b5))
## [2.30.1](https://github.com/revanced/revanced-patches/compare/v2.30.0...v2.30.1) (2022-08-03)
### Bug Fixes
* migrate to new patcher api ([f43446e](https://github.com/revanced/revanced-patches/commit/f43446ed189e583302fcd899f5eb7517f2a77144))
# [2.30.0](https://github.com/revanced/revanced-patches/compare/v2.29.0...v2.30.0) (2022-08-03)
### Bug Fixes
* incorrect fingerprint version [skip ci] ([f8c62ae](https://github.com/revanced/revanced-patches/commit/f8c62ae16b088ff6d0e96a4ef62dc707cd83beb9))
* rollback to `Dependencies` annotation ([36a2ae8](https://github.com/revanced/revanced-patches/commit/36a2ae886c63f1d22bb1cca9e7110af6c3f6f2d3))
### Features
* set the correct theme of the settings screen ([70d850c](https://github.com/revanced/revanced-patches/commit/70d850cf295d306b0de9419efe6a4bbf3857d3a0))
# [2.29.0](https://github.com/revanced/revanced-patches/compare/v2.28.2...v2.29.0) (2022-08-02)
### Features
* add "Application Icon Path" option to branding ([1748d1e](https://github.com/revanced/revanced-patches/commit/1748d1e5badf61213d793ff7ae1d090ea2ea82f0))
* add "Application Name" option to branding and move renaming to CustomBrandingPatch.kt ([8dafe05](https://github.com/revanced/revanced-patches/commit/8dafe05b2c5e2b0291d46b02717d910721673712))
## [2.28.2](https://github.com/revanced/revanced-patches/compare/v2.28.1...v2.28.2) (2022-08-02)
### Bug Fixes
* remove requirement for solution [skip ci] ([#271](https://github.com/revanced/revanced-patches/issues/271)) ([553fad3](https://github.com/revanced/revanced-patches/commit/553fad3fe1bb79bdf34e9f91c0e1cbfda78e1054))
## [2.28.1](https://github.com/revanced/revanced-patches/compare/v2.28.0...v2.28.1) (2022-07-31)
### Bug Fixes
* add missing permission to reboot app ([#260](https://github.com/revanced/revanced-patches/issues/260)) ([6ced6df](https://github.com/revanced/revanced-patches/commit/6ced6df8ed7642dea51e1acd1c12f4de4874b972))
# [2.28.0](https://github.com/revanced/revanced-patches/compare/v2.27.0...v2.28.0) (2022-07-31)
### Features
* add `custom-video-buffer` patch ([9f117c7](https://github.com/revanced/revanced-patches/commit/9f117c74cdbdcf98eae97cf4c37f0baca451d695))
# [2.27.0](https://github.com/revanced/revanced-patches/compare/v2.26.0...v2.27.0) (2022-07-31)

View File

@@ -25,16 +25,32 @@ Official patches by ReVanced
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `minimized-playback-music` | Enables minimized playback on Kids music. | 5.16.51 |
| `minimized-playback-music` | Enables minimized playback on Kids music. | 5.17.51 |
| `tasteBuilder-remover` | Removes the "Tell us which artists you like" card from the home screen. | 5.16.51 |
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.16.51 |
| `hide-get-premium` | Removes all "Get Premium" evidences from the avatar menu. | 5.17.51 |
| `compact-header` | Hides the music category bar at the top of the homepage. | 5.16.51 |
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.16.51 |
| `background-play` | Enables playing music in the background. | 5.16.51 |
| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.16.51 |
| `music-video-ads` | Removes ads in the music player. | 5.16.51 |
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.16.51 |
| `exclusive-audio-playback` | Enables the option to play music without video. | 5.16.51 |
| `upgrade-button-remover` | Removes the upgrade tab from the pivot bar. | 5.17.51 |
| `background-play` | Enables playing music in the background. | 5.17.51 |
| `music-microg-support` | Allows YouTube Music ReVanced to run without root and under a different package name. | 5.17.51 |
| `music-video-ads` | Removes ads in the music player. | 5.17.51 |
| `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | 5.17.51 |
| `exclusive-audio-playback` | Enables the option to play music without video. | 5.17.51 |
</details>
### 📦 `de.dwd.warnapp`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all |
</details>
### 📦 `com.ss.android.ugc.trill`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `tiktok-ads` | Removes ads from TikTok. | all |
</details>
### 📦 `com.google.android.youtube`
@@ -51,14 +67,15 @@ Official patches by ReVanced
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 17.29.34 |
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.29.34 |
| `premium-heading` | Shows premium branding on the home screen. | all |
| `custom-branding` | Changes the YouTube launcher icon to be ReVanced's. | all |
| `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all |
| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 17.29.34 |
| `old-quality-layout` | Enables the original quality flyout menu. | 17.29.34 |
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.29.34 |
| `hide-watermark` | Hides creator's watermarks on videos. | 17.29.34 |
| `sponsorblock` | Integrate SponsorBlock. | 17.29.34 |
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.29.34 |
| `force-vp9-codec` | Forces the VP9 codec for videos. | 17.29.34 |
| `tablet-mini-player` | Enables the tablet mini player layout. | 17.29.34 |
| `custom-video-buffer` | Lets you change the buffers of videos. | 17.29.34 |
| `always-autorepeat` | Always repeats the playing video again. | 17.29.34 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG | 17.29.34 |
| `settings` | Adds settings for ReVanced to YouTube. | all |

View File

@@ -22,7 +22,7 @@ repositories {
dependencies {
implementation(kotlin("stdlib"))
implementation("app.revanced:revanced-patcher:2.4.0")
implementation("app.revanced:revanced-patcher:3.3.3")
implementation("app.revanced:multidexlib2:2.5.2.r2")
}

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official
version = 2.27.0
version = 2.36.2

View File

@@ -1,8 +1,10 @@
package app.revanced.extensions
import app.revanced.patcher.data.impl.BytecodeData
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.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.toInstruction
import org.jf.dexlib2.AccessFlags
@@ -14,7 +16,6 @@ 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 java.io.OutputStream
import java.nio.file.Files
// TODO: this method does not make sense here
@@ -28,6 +29,30 @@ internal fun MutableMethodImplementation.injectHideCall(
)
}
/**
* traverse the class hierarchy starting from the given root class
*
* @param targetClass the class to start traversing the class hierarchy from
* @param callback function that is called for every class in the hierarchy
*/
fun BytecodeData.traverseClassHierarchy(targetClass: MutableClass, callback: MutableClass.() -> Unit) {
callback(targetClass)
this.findClass(targetClass.superclass ?: return)?.resolve()?.let {
traverseClassHierarchy(it, callback)
}
}
/**
* apply a transform to all methods of the class
*
* @param transform the transformation function. original method goes in, transformed method goes out
*/
fun MutableClass.transformMethods(transform: MutableMethod.() -> MutableMethod) {
val transformedMethods = methods.map { it.transform() }
methods.clear()
methods.addAll(transformedMethods)
}
/**
* 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
*
@@ -146,7 +171,7 @@ fun ResourceData.injectStrings(
// open source strings.xml
val sourceInputStream = classLoader.getResourceAsStream("$patchDirectoryPath/$relativePath")
?: throw PatchResultError("failed to open '$patchDirectoryPath/$relativePath'")
xmlEditor[sourceInputStream, OutputStream.nullOutputStream()].use { sourceStringsXml ->
xmlEditor[sourceInputStream].use { sourceStringsXml ->
val strings = sourceStringsXml.file.getElementsByTagName("resources").item(0).childNodes
// open target strings.xml

View File

@@ -5,7 +5,7 @@ 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.patch.Patch
import app.revanced.patcher.util.patch.implementation.JarPatchBundle
import app.revanced.patcher.util.patch.impl.JarPatchBundle
import java.io.File
object Generator {

View File

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

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class CodecsUnlockCompatibility

View File

@@ -12,17 +12,14 @@ import org.jf.dexlib2.Opcode
@Name("codec-lock-fingerprint")
@MatchingMethod(
"Labwj;",
"Lacfr;",
"a",
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@CodecsUnlockCompatibility
@Version("0.0.1")
object CodecsLockFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, null, listOf(
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
@@ -37,5 +34,6 @@ object CodecsLockFingerprint : MethodFingerprint(
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_DIRECT,
Opcode.RETURN_OBJECT
)
)
),
listOf("eac3_supported")
)

View File

@@ -13,6 +13,7 @@ import app.revanced.patcher.util.smali.toInstruction
import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility
import app.revanced.patches.music.audio.codecs.fingerprints.AllCodecsReferenceFingerprint
import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprint
import org.jf.dexlib2.Opcode
@Patch
@Name("codecs-unlock")
@@ -25,19 +26,29 @@ class CodecsUnlockPatch : BytecodePatch(
)
) {
override fun execute(data: BytecodeData): PatchResult {
var result = CodecsLockFingerprint.result!!
val codecsLockResult = CodecsLockFingerprint.result!!
val implementation = result.mutableMethod.implementation!!
val implementation = codecsLockResult.mutableMethod.implementation!!
val instructionIndex = result.patternScanResult!!.startIndex
val scanResultStartIndex = codecsLockResult.patternScanResult!!.startIndex
val instructionIndex = scanResultStartIndex +
if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) {
// for 5.16.xx and lower
-3
} else {
// since 5.17.xx
-2
}
result = AllCodecsReferenceFingerprint.result!!
val codecMethod =
data.toMethodWalker(result.method).nextMethod(result.patternScanResult!!.startIndex).getMethod()
val allCodecsResult = AllCodecsReferenceFingerprint.result!!
val allCodecsMethod =
data.toMethodWalker(allCodecsResult.method)
.nextMethod(allCodecsResult.patternScanResult!!.startIndex)
.getMethod()
implementation.replaceInstruction(
instructionIndex,
"invoke-static {}, ${codecMethod.definingClass}->${codecMethod.name}()Ljava/util/Set;".toInstruction()
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction()
)
return PatchResultSuccess()

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ExclusiveAudioCompatibility

View File

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

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HideGetPremiumCompatibility

View File

@@ -3,6 +3,11 @@ package app.revanced.patches.music.layout.tastebuilder.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
/**
* -- Note 2022-08-05 --
* Since 5.17.xx the tastebuilder component is dismissible, so this patch is less useful
* also it is partly litho now
*/
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
@@ -11,4 +16,3 @@ import app.revanced.patcher.annotation.Package
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class RemoveTasteBuilderCompatibility

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class RemoveUpgradeButtonCompatibility

View File

@@ -5,9 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class MusicMicroGPatchCompatibility
internal annotation class MusicMicroGPatchCompatibility

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.misc.microg.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
@Name("cast-context-fetch-fingerprint")
@MatchingMethod(
"Lvvz;", "a"
)
@DirectPatternScanMethod
@MicroGPatchCompatibility
@Version("0.0.1")
object CastContextFetchFingerprint : MethodFingerprint(
null, null, null, null,
listOf("Error fetching CastContext.")
)

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.misc.microg.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
@Name("cast-module-fingerprint")
@MatchingMethod(
"Llqh;", "c"
)
@DirectPatternScanMethod
@MicroGPatchCompatibility
@Version("0.0.1")
object CastDynamiteModuleFingerprint : MethodFingerprint(
null, null, null, null,
listOf("com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl")
)

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.misc.microg.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
@Name("cast-context-fetch-fingerprint")
@MatchingMethod(
"Lmcf;", "c"
)
@DirectPatternScanMethod
@MicroGPatchCompatibility
@Version("0.0.1")
object CastDynamiteModuleV2Fingerprint : MethodFingerprint(
null, null, null, null,
listOf("Failed to load module via V2: ")
)

View File

@@ -7,7 +7,7 @@ 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.patch.annotations.Dependencies
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
@@ -27,7 +27,7 @@ import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableStringReference
@Patch
@Dependencies([MusicMicroGResourcePatch::class])
@DependsOn([MusicMicroGResourcePatch::class])
@Name("music-microg-support")
@Description("Allows YouTube Music ReVanced to run without root and under a different package name.")
@MusicMicroGPatchCompatibility
@@ -36,6 +36,9 @@ class MusicMicroGBytecodePatch : BytecodePatch(
listOf(
ServiceCheckFingerprint,
GooglePlayUtilityFingerprint,
CastDynamiteModuleFingerprint,
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
PrimeFingerprint,
)
) {
@@ -122,9 +125,17 @@ class MusicMicroGBytecodePatch : BytecodePatch(
listOf(
ServiceCheckFingerprint,
GooglePlayUtilityFingerprint,
CastDynamiteModuleFingerprint,
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
).forEach { fingerprint ->
val result = fingerprint.result!!
val stringInstructions = when (result.method.returnType.first()) {
'L' -> """
const/4 v0, 0x0
return-object v0
"""
'V' -> "return-void"
'I' -> """
const/4 v0, 0x0

View File

@@ -5,10 +5,9 @@ import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51")
"com.google.android.apps.youtube.music", arrayOf("5.14.53", "5.16.51", "5.17.51")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class BackgroundPlayCompatibility

View File

@@ -0,0 +1,14 @@
package app.revanced.patches.tiktok.ad.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[
Package("com.ss.android.ugc.trill", arrayOf()),
Package("com.zhiliaoapp.musically", arrayOf())
]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class TiktokAdsCompatibility

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.tiktok.ad.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.ad.annotations.TiktokAdsCompatibility
@Name("feed-item-clone-fingerprint")
@MatchingMethod(
"Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;",
"clone",
)
@TiktokAdsCompatibility
@Version("0.0.1")
object FeedItemListCloneFingerprint : MethodFingerprint(
null, null, null, null,null, { methodDef ->
methodDef.definingClass.endsWith("/FeedItemList;") && methodDef.name == "clone"
}
)

View File

@@ -0,0 +1,48 @@
package app.revanced.patches.tiktok.ad.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.tiktok.ad.annotations.TiktokAdsCompatibility
import app.revanced.patches.tiktok.ad.fingerprints.FeedItemListCloneFingerprint
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.reference.FieldReference
@Patch
@Name("tiktok-ads")
@Description("Removes ads from TikTok.")
@TiktokAdsCompatibility
@Version("0.0.1")
class TiktokAdsPatch : BytecodePatch(
listOf(FeedItemListCloneFingerprint)
) {
override fun execute(data: BytecodeData): PatchResult {
val method = FeedItemListCloneFingerprint.result!!.mutableMethod
// iterate all instructions in the clone method
for ((index, instruction) in method.implementation!!.instructions.withIndex()) {
// conditions for the instruction we need
if (instruction.opcode.ordinal != Opcode.IPUT_OBJECT.ordinal) continue
val clonePreloadAdsFieldInstruction = (instruction as? ReferenceInstruction)
if ((clonePreloadAdsFieldInstruction?.reference as? FieldReference)?.name != "preloadAds") continue
// set null instead of the field "preloadAds"
val overrideRegister = (clonePreloadAdsFieldInstruction as TwoRegisterInstruction).registerA
method.addInstruction(
index,
"const/4 v$overrideRegister, 0x0"
)
return PatchResultSuccess()
}
return PatchResultError("Could not find required instruction.")
}
}

View File

@@ -1,13 +1,13 @@
package app.revanced.patches.youtube.misc.forcevp9.annotations
package app.revanced.patches.warnwetter.misc.firebasegetcert.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.26.35", "17.27.39", "17.28.34", "17.29.34")
"de.dwd.warnapp", arrayOf()
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ForceVP9Compatibility
internal annotation class FirebaseGetCertPatchCompatibility

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.warnwetter.misc.firebasegetcert.annotations.FirebaseGetCertPatchCompatibility
@Name("messaging-app-certificate-fingerprint")
@MatchingMethod(
"Lcom/google/firebase/installations/remote/c;", "f"
)
@FirebaseGetCertPatchCompatibility
@Version("0.0.1")
object GetMessagingCertFingerprint : MethodFingerprint(
"Ljava/lang/String;",
null,
null,
null,
listOf(
"ContentValues",
"Could not get fingerprint hash for package: ",
"No such package: "
)
)

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.warnwetter.misc.firebasegetcert.annotations.FirebaseGetCertPatchCompatibility
@Name("registration-app-certificate-fingerprint")
@MatchingMethod(
"Lcom/google/firebase/remoteconfig/internal/ConfigFetchHttpClient;", "f"
)
@FirebaseGetCertPatchCompatibility
@Version("0.0.1")
object GetReqistrationCertFingerprint : MethodFingerprint(
"Ljava/lang/String;",
null,
null,
null,
listOf(
"FirebaseRemoteConfig",
"Could not get fingerprint hash for package: ",
"No such package: "
)
)

View File

@@ -0,0 +1,45 @@
package app.revanced.patches.warnwetter.misc.firebasegetcert.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.PatchResultSuccess
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.warnwetter.misc.firebasegetcert.fingerprints.*
import app.revanced.patches.warnwetter.misc.firebasegetcert.annotations.FirebaseGetCertPatchCompatibility
@Name("spoof-cert-patch")
@Description("Spoofs the X-Android-Cert header.")
@FirebaseGetCertPatchCompatibility
@Version("0.0.1")
class FirebaseGetCertPatch : BytecodePatch(
listOf(
GetReqistrationCertFingerprint,
GetMessagingCertFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val spoofedInstruction =
"""
const-string v0, "0799DDF0414D3B3475E88743C91C0676793ED450"
return-object v0
"""
val registrationCertMethod = GetReqistrationCertFingerprint.result!!.mutableMethod
val messagingCertMethod = GetMessagingCertFingerprint.result!!.mutableMethod
registrationCertMethod.addInstructions(
0,
spoofedInstruction
)
messagingCertMethod.addInstructions(
0,
spoofedInstruction
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.warnwetter.misc.promocode.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"de.dwd.warnapp", arrayOf()
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class PromoCodeUnlockCompatibility

View File

@@ -0,0 +1,24 @@
package app.revanced.patches.warnwetter.misc.promocode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.warnwetter.misc.promocode.annotations.PromoCodeUnlockCompatibility
@Name("promo-code-unlock-fingerprint")
@MatchingMethod(
"Lde/dwd/warnapp/model/PromoTokenVerification;", "isValid"
)
@PromoCodeUnlockCompatibility
@Version("0.0.1")
object PromoCodeUnlockFingerprint : MethodFingerprint(
null,
null,
null,
null,
null,
{ methodDef ->
methodDef.definingClass.endsWith("PromoTokenVerification;") && methodDef.name == "isValid"
}
)

View File

@@ -0,0 +1,47 @@
package app.revanced.patches.warnwetter.misc.promocode.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.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.warnwetter.misc.firebasegetcert.patch.FirebaseGetCertPatch
import app.revanced.patches.warnwetter.misc.promocode.annotations.PromoCodeUnlockCompatibility
import app.revanced.patches.warnwetter.misc.promocode.fingerprints.PromoCodeUnlockFingerprint
@DependsOn(
[
FirebaseGetCertPatch::class
]
)
@Patch
@Name("promo-code-unlock")
@Description("Disables the validation of promo code. Any code will work to unlock all features.")
@PromoCodeUnlockCompatibility
@Version("0.0.1")
class PromoCodeUnlockPatch : BytecodePatch(
listOf(
PromoCodeUnlockFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val method = PromoCodeUnlockFingerprint.result!!.mutableMethod
method.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -9,7 +9,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
@@ -38,7 +38,7 @@ import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
@Patch
@Dependencies([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class])
@DependsOn([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class])
@Name("general-ads")
@Description("Removes general ads.")
@GeneralAdsCompatibility
@@ -174,7 +174,6 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
}
Opcode.CONST_STRING -> {
when (((instruction as Instruction21c).reference as StringReference).string) {
stringReferences[0] -> {
val stringInstruction = instructions.elementAt(3)
@@ -200,23 +199,23 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
stringReferences[2] -> { // Litho ads
// create proxied method.
val proxy = data.proxy(classDef)
val mutableClass = proxy.resolve()
val proxiedClass = proxy.resolve()
// add getIsEmpty method
mutableClass.addGetIsEmptyMethod()
proxiedClass.addGetIsEmptyMethod()
// get required method to patch and get references from
val lithoMethod = getLithoMethod(mutableClass)
val lithoMethod = getLithoMethod(proxiedClass)
?: return PatchResultError("Could not find required litho method to patch.")
val lithoMethodImplementation = lithoMethod.implementation!!
// create and add getTemplateName method
val getTemplateMethod =
mutableClass.createGetTemplateNameMethod(lithoMethodImplementation)
mutableClass.addMethod(getTemplateMethod)
proxiedClass.createGetTemplateNameMethod(lithoMethodImplementation)
proxiedClass.addMethod(getTemplateMethod)
val lithoInstructions = lithoMethodImplementation.instructions
val thisType = mutableClass.type
val thisType = proxiedClass.type
val templateNameParameterType = getTemplateMethod.parameterTypes.first()
// get reference descriptors

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
@@ -19,7 +19,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("hide-infocard-suggestions")
@Description("Hides infocards in videos.")
@HideInfocardSuggestionsCompatibility

View File

@@ -8,7 +8,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsFingerprin
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("video-ads")
@Description("Removes ads in the video player.")
@VideoAdsCompatibility

View File

@@ -8,7 +8,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility
@@ -22,7 +22,7 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction11n
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("seekbar-tapping")
@Description("Enables tap-to-seek on the seekbar of the video player.")
@SeekbarTappingCompatibility

View File

@@ -0,0 +1,21 @@
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("swipe-controls-host-activity-fingerprint")
@MatchingMethod(
"Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;", "<init>"
)
@DirectPatternScanMethod
@SwipeControlsCompatibility
@Version("0.0.1")
object SwipeControlsHostActivityFingerprint : MethodFingerprint(
null, null, null, null, null, { methodDef ->
methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;" && methodDef.name == "<init>"
}
)

View File

@@ -7,15 +7,15 @@ 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")
@Name("watch-while-activity-fingerprint")
@MatchingMethod(
"LWatchWhileActivity;", "onCreate"
"LWatchWhileActivity;", "<init>"
)
@DirectPatternScanMethod
@SwipeControlsCompatibility
@Version("0.0.1")
object WatchWhileOnStartFingerprint : MethodFingerprint(
object WatchWhileActivityFingerprint : MethodFingerprint(
null, null, null, null, null, { methodDef ->
methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "onStart"
methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "<init>"
}
)
)

View File

@@ -1,45 +1,69 @@
package app.revanced.patches.youtube.interaction.swipecontrols.patch.bytecode
import app.revanced.extensions.transformMethods
import app.revanced.extensions.traverseClassHierarchy
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
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.fingerprints.SwipeControlsHostActivityFingerprint
import app.revanced.patches.youtube.interaction.swipecontrols.fingerprints.WatchWhileActivityFingerprint
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
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.immutable.ImmutableMethod
@Patch
@Name("swipe-controls")
@Description("Adds volume and brightness swipe controls.")
@SwipeControlsCompatibility
@Version("0.0.2")
@Dependencies(
@Version("0.0.3")
@DependsOn(
[
IntegrationsPatch::class,
PlayerTypeHookPatch::class,
PlayerOverlaysHookPatch::class,
SwipeControlsResourcePatch::class
]
)
class SwipeControlsBytecodePatch : BytecodePatch(
listOf(
WatchWhileOnStartFingerprint
WatchWhileActivityFingerprint,
SwipeControlsHostActivityFingerprint
)
) {
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"
)
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
val targetClass = WatchWhileActivityFingerprint.result!!.mutableClass
// inject the wrapper class from integrations into the class hierarchy of WatchWhileActivity
wrapperClass.setSuperClass(targetClass.superclass)
targetClass.setSuperClass(wrapperClass.type)
// ensure all classes and methods in the hierarchy are non-final, so we can override them in integrations
data.traverseClassHierarchy(targetClass) {
accessFlags = accessFlags and AccessFlags.FINAL.value.inv()
transformMethods {
ImmutableMethod(
definingClass,
name,
parameters,
returnType,
accessFlags and AccessFlags.FINAL.value.inv(),
annotations,
hiddenApiRestrictions,
implementation
).toMutable()
}
}
return PatchResultSuccess()
}
}
}

View File

@@ -6,7 +6,7 @@ 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.annotations.Dependencies
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility
@@ -15,7 +15,7 @@ import org.w3c.dom.Element
import java.io.File
@Patch
@Dependencies([FixLocaleConfigErrorPatch::class])
@DependsOn([FixLocaleConfigErrorPatch::class])
@Name("amoled")
@Description("Enables pure black theme.")
@AmoledCompatibility

View File

@@ -8,7 +8,7 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -21,7 +21,7 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch
@Dependencies([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class])
@DependsOn([ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class])
@Name("hide-autoplay-button")
@Description("Hides the autoplay button in the video player.")
@AutoplayButtonCompatibility

View File

@@ -7,7 +7,7 @@ import app.revanced.patcher.data.impl.ResourceData
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility
@@ -17,7 +17,7 @@ import java.nio.file.StandardCopyOption
import kotlin.io.path.exists
@Patch
@Dependencies([FixLocaleConfigErrorPatch::class])
@DependsOn([FixLocaleConfigErrorPatch::class])
@Name("premium-heading")
@Description("Shows premium branding on the home screen.")
@PremiumHeadingCompatibility

View File

@@ -4,20 +4,21 @@ import app.revanced.patcher.annotation.Description
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.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Dependencies
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.nio.file.Files
@Patch
@Dependencies([FixLocaleConfigErrorPatch::class])
@DependsOn([FixLocaleConfigErrorPatch::class])
@Name("custom-branding")
@Description("Changes the YouTube launcher icon to be ReVanced's.")
@Description("Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).")
@CustomBrandingCompatibility
@Version("0.0.1")
class CustomBrandingPatch : ResourcePatch() {
@@ -25,6 +26,7 @@ class CustomBrandingPatch : ResourcePatch() {
val resDirectory = data["res"]
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
// Icon branding
val iconNames = arrayOf(
"adaptiveproduct_youtube_background_color_108",
"adaptiveproduct_youtube_foreground_color_108",
@@ -40,15 +42,59 @@ class CustomBrandingPatch : ResourcePatch() {
"mdpi" to 48
).forEach { (iconDirectory, size) ->
iconNames.forEach iconLoop@{ iconName ->
val iconFile = this.javaClass.classLoader.getResourceAsStream("branding/$size/$iconName.png")
val iconFile = getIconStream("branding/$size/$iconName.png")
?: return PatchResultError("The icon $iconName can not be found.")
Files.write(
resDirectory.resolve("mipmap-$iconDirectory").resolve("$iconName.png").toPath(), iconFile.readAllBytes()
resDirectory.resolve("mipmap-$iconDirectory").resolve("$iconName.png").toPath(),
iconFile.readAllBytes()
)
}
}
// Name branding
val appName: String by options[keyAppName]
val manifest = data["AndroidManifest.xml"]
manifest.writeText(
manifest.readText()
.replace(
"android:label=\"@string/application_name",
"android:label=\"$appName"
)
)
return PatchResultSuccess()
}
override val options = PatchOptions(
PatchOption.StringOption(
key = keyAppName,
default = "YouTube ReVanced",
title = "Application Name",
description = "The name of the application it will show on your home screen.",
required = true
),
PatchOption.StringOption(
key = keyAppIconPath,
default = null,
title = "Application Icon Path",
description = "A path to the icon of the application."
)
)
private fun getIconStream(iconPath: String): InputStream? {
val appIconPath: String? by options[keyAppIconPath]
if (appIconPath == null) {
return this.javaClass.classLoader.getResourceAsStream(iconPath)
}
val file = File(appIconPath!!).resolve(iconPath)
if (!file.exists()) return null
return FileInputStream(file)
}
private companion object {
private const val keyAppName = "appName"
private const val keyAppIconPath = "appIconPath"
}
}

View File

@@ -5,7 +5,7 @@ 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.annotations.Dependencies
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
@@ -14,7 +14,7 @@ import app.revanced.patches.youtube.layout.castbutton.annotations.CastButtonComp
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("hide-cast-button")
@Description("Hides the cast button in the video player.")
@CastButtonCompatibility

View File

@@ -8,7 +8,7 @@ import app.revanced.patcher.extensions.addInstruction
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.createbutton.annotations.CreateButtonCompatibility
@@ -22,7 +22,7 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.reference.MethodReference
@Patch
@Dependencies([IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class])
@DependsOn([IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class])
@Name("disable-create-button")
@Description("Hides the create button in the navigation bar.")
@CreateButtonCompatibility

View File

@@ -10,7 +10,7 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.fullscreenpanels.annotations.FullscreenPanelsCompatibility
@@ -20,7 +20,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch
@Name("disable-fullscreen-panels")
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Description("Disables video description and comments panel in fullscreen view.")
@FullscreenPanelsCompatibility
@Version("0.0.1")

View File

@@ -8,7 +8,7 @@ import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.extensions.addInstructions
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -24,7 +24,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
@Patch
@Name("minimized-playback")
@Description("Enables minimized and background playback.")
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@MinimizedPlaybackCompatibility
@Version("0.0.1")
class MinimizedPlaybackPatch : BytecodePatch(

View File

@@ -7,7 +7,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
@@ -16,7 +16,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("old-quality-layout")
@Description("Enables the original quality flyout menu.")
@OldQualityLayoutCompatibility

View File

@@ -8,7 +8,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
@@ -20,7 +20,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.videoid.patch.VideoIdPatch
@Patch
@Dependencies([IntegrationsPatch::class, VideoIdPatch::class])
@DependsOn([IntegrationsPatch::class, VideoIdPatch::class])
@Name("return-youtube-dislike")
@Description("Shows the dislike count of videos using the Return YouTube Dislike API.")
@ReturnYouTubeDislikeCompatibility

View File

@@ -7,7 +7,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("hide-shorts-button")
@Description("Hides the shorts button on the navigation bar.")
@ShortsButtonCompatibility

View File

@@ -13,7 +13,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -37,7 +37,7 @@ import org.jf.dexlib2.immutable.ImmutableMethodParameter
import org.jf.dexlib2.util.MethodUtil
@Patch
@Dependencies(
@DependsOn(
dependencies = [IntegrationsPatch::class, ResourceIdMappingProviderResourcePatch::class, SponsorBlockResourcePatch::class, VideoIdPatch::class]
)
@Name("sponsorblock")

View File

@@ -2,20 +2,19 @@ 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.annotations.DependsOn
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 app.revanced.util.resources.ResourceUtils.copyXmlNode
import java.nio.file.Files
@Name("sponsorblock-resource-patch")
@SponsorBlockCompatibility
@Dependencies([FixLocaleConfigErrorPatch::class])
@DependsOn([FixLocaleConfigErrorPatch::class])
@Version("0.0.1")
class SponsorBlockResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult {
@@ -29,7 +28,7 @@ class SponsorBlockResourcePatch : ResourcePatch() {
// copy nodes from the resources node to the real resource node
"resources".copyXmlNode(
data.xmlEditor[stringsResourceInputStream, OutputStream.nullOutputStream()],
data.xmlEditor[stringsResourceInputStream],
data.xmlEditor["res/$stringsResourcePath"]
).close() // close afterwards
@@ -78,7 +77,7 @@ class SponsorBlockResourcePatch : ResourcePatch() {
val targetXmlEditor = data.xmlEditor["res/$path/$resource.xml"]
"RelativeLayout".copyXmlNode(
data.xmlEditor[hostingResourceStream, OutputStream.nullOutputStream()],
data.xmlEditor[hostingResourceStream],
targetXmlEditor
).also {
val children = targetXmlEditor.file.getElementsByTagName("RelativeLayout").item(0).childNodes
@@ -102,27 +101,4 @@ class SponsorBlockResourcePatch : ResourcePatch() {
}
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

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

View File

@@ -0,0 +1,41 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-dimensions-calculator-fingerprint")
@MatchingMethod(
"Lkkr;", "pM"
)
@FuzzyPatternScanMethod(2) // TODO: Find a good threshold value
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L"),
listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.MUL_FLOAT,
Opcode.INVOKE_INTERFACE,
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.INVOKE_DIRECT,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.FLOAT_TO_DOUBLE,
Opcode.CONST_WIDE_HIGH16,
Opcode.CMPL_DOUBLE,
)
)

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-override-fingerprint")
@MatchingMethod(
"Lkkr;", "j"
)
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerOverrideFingerprint : MethodFingerprint(
"Z", AccessFlags.STATIC or AccessFlags.PUBLIC ,null,
listOf(Opcode.RETURN), // anchor to insert the instruction
)

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-override-no-context-fingerprint")
@MatchingMethod(
"Lkkr;", "k"
)
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint(
"Z", AccessFlags.FINAL or AccessFlags.PRIVATE ,null,
listOf(Opcode.RETURN), // anchor to insert the instruction
)

View File

@@ -0,0 +1,37 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("mini-player-response-model-size-check-fingerprint")
@MatchingMethod(
"Lenv;", "a"
)
@TabletMiniPlayerCompatibility
@Version("0.0.1")
object MiniPlayerResponseModelSizeCheckFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L", "L"),
listOf(
Opcode.OR_INT_LIT8,
Opcode.IPUT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.RETURN_OBJECT,
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST,
Opcode.CHECK_CAST,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
),
null
)

View File

@@ -0,0 +1,92 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.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.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.DependsOn
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.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@DependsOn([IntegrationsPatch::class])
@Name("tablet-mini-player")
@Description("Enables the tablet mini player layout.")
@TabletMiniPlayerCompatibility
@Version("0.0.1")
class TabletMiniPlayerPatch : BytecodePatch(
listOf(
MiniPlayerDimensionsCalculatorFingerprint,
MiniPlayerResponseModelSizeCheckFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
// first resolve the fingerprints via the parent fingerprint
val miniPlayerClass = MiniPlayerDimensionsCalculatorFingerprint.result!!.classDef
/*
* no context parameter method
*/
MiniPlayerOverrideNoContextFingerprint.resolve(data, miniPlayerClass)
val (method, _, parameterRegister) = MiniPlayerOverrideNoContextFingerprint.addProxyCall()
// - 1 means to insert before the return instruction
val secondInsertIndex = method.implementation!!.instructions.size - 1
method.insertOverride(secondInsertIndex, parameterRegister /** same register used to return **/)
/*
* method with context parameter
*/
MiniPlayerOverrideFingerprint.resolve(data, miniPlayerClass)
val (_, _, _) = MiniPlayerOverrideFingerprint.addProxyCall()
/*
* size check return value override
*/
val (_, _, _) = MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall()
return PatchResultSuccess()
}
// helper methods
private companion object {
fun MethodFingerprint.addProxyCall(): Triple<MutableMethod, Int, Int> {
val (method, scanIndex, parameterRegister) = this.unwrap()
method.insertOverride(scanIndex, parameterRegister)
return Triple(method, scanIndex, parameterRegister)
}
fun MutableMethod.insertOverride(index: Int, overrideRegister: Int) {
this.addInstructions(
index,
"""
invoke-static {v$overrideRegister}, Lapp/revanced/integrations/patches/TabletMiniPlayerOverridePatch;->getTabletMiniPlayerOverride(Z)Z
move-result v$overrideRegister
"""
)
}
fun MethodFingerprint.unwrap(): Triple<MutableMethod, Int, Int> {
val result = this.result!!
val scanIndex = result.patternScanResult!!.endIndex
val method = result.mutableMethod
val instructions = method.implementation!!.instructions
val parameterRegister = (instructions[scanIndex] as OneRegisterInstruction).registerA
return Triple(method, scanIndex, parameterRegister)
}
}
}

View File

@@ -10,7 +10,7 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
@@ -19,7 +19,7 @@ import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkF
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("hide-watermark")
@Description("Hides creator's watermarks on videos.")
@HideWatermarkCompatibility

View File

@@ -9,7 +9,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@@ -21,7 +21,7 @@ import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([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

View File

@@ -10,7 +10,7 @@ import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.reso
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.autorepeat.annotations.AutoRepeatCompatibility
@@ -19,7 +19,7 @@ import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParen
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@Patch
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@Name("always-autorepeat")
@Description("Always repeats the playing video again.")
@AutoRepeatCompatibility

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.extensions.replaceInstruction
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
@@ -25,7 +25,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
@Patch
@Name("custom-playback-speed")
@Description("Adds more video playback speed options.")
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
@CustomPlaybackSpeedCompatibility
@Version("0.0.1")
class CustomPlaybackSpeedPatch : BytecodePatch(

View File

@@ -1,48 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("force-vp9-codec-fingerprint")
@MatchingMethod(
"Lpzs;", "aI"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ForceVP9CodecFingerprint : MethodFingerprint(
"Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "I"), listOf(
Opcode.SGET, Opcode.IF_NEZ, Opcode.INVOKE_STATIC
), null, null
)
/*
public static boolean aI(Context context, int i) {
if (b == 0) {
aH(context);
}
return b >= i; // Override to: return Lapp/revanced/integrations/patches/ForceCodecPatch->shouldForceVP9()
}
.method public static aI(Landroid/content/Context;I)Z
sget v0, Lpzs;->b:I
if-nez v0, :cond_7
invoke-static {p0}, Lpzs;->aH(Landroid/content/Context;)V
:cond_7
//remove after here, and inject only our code
sget p0, Lpzs;->b:I
if-lt p0, p1, :cond_d
const/4 p0, 0x1
return p0
:cond_d
const/4 p0, 0x0
return p0
.end method
*/

View File

@@ -1,73 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("force-vp9-codec-fingerprint-two")
@MatchingMethod(
"Lpzs;", "aO"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ForceVP9CodecFingerprintTwo : MethodFingerprint(
"Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("I"), listOf(
Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT_OBJECT, Opcode.CONST_4
), null, null
)
/*
public static boolean aO(int i) {
Pair aG = aG();
return (aG == null ? 0 : Math.min(((Integer) aG.first).intValue(), ((Integer) aG.second).intValue())) >= i;
//replace line with: return Lapp/revanced/integrations/patches/ForceCodecPatch/shouldForceVP9();
}
becomes:
public static boolean aO(int i) {
return Lapp/revanced/integrations/patches/ForceCodecPatch/shouldForceVP9();
}
.method public static aO(I)Z
invoke-static {}, Lpzs;->aG()Landroid/util/Pair;
move-result-object v0
const/4 v1, 0x0
if-nez v0, :cond_9
const/4 v0, 0x0
goto :goto_1d
:cond_9
iget-object v2, v0, Landroid/util/Pair;->first:Ljava/lang/Object;
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
iget-object v0, v0, Landroid/util/Pair;->second:Ljava/lang/Object;
check-cast v0, Ljava/lang/Integer;
invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
move-result v0
invoke-static {v2, v0}, Ljava/lang/Math;->min(II)I
move-result v0
:goto_1d
if-lt v0, p0, :cond_21
const/4 p0, 0x1
return p0
:cond_21
return v1
.end method
becomes:
.method public static aO(I)Z
invoke-static {}, Lapp/revanced/integrations/patches/ForceCodecPatch;->shouldForceVP9()Z
move-result v0
return v0
.end method
*/

View File

@@ -1,24 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
@Name("force-vp9-codec-parent-fingerprint")
@MatchingMethod(
"Lqaa;", "U"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ForceVP9ParentFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf(), null,
listOf(
"sys.display-size", "x"
)
)

View File

@@ -1,30 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
@Name("replace-device-info-parent-fingerprint")
@MatchingMethod(
"Lvjb;", "e"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ReplaceDeviceInfoFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), null,
null,
customFingerprint = { methodDef ->
methodDef.implementation!!.instructions.any {
((it as? ReferenceInstruction)?.reference as? FieldReference)?.definingClass.equals("Landroid/os/Build;")
&& ((it as? ReferenceInstruction)?.reference as? FieldReference)?.name.equals("MANUFACTURER")
}
}
)

View File

@@ -1,24 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.misc.forcevp9.annotations.ForceVP9Compatibility
import org.jf.dexlib2.AccessFlags
@Name("replace-device-info-parent-fingerprint")
@MatchingMethod(
"Lvjb;", "b"
)
@DirectPatternScanMethod
@ForceVP9Compatibility
@Version("0.0.1")
object ReplaceDeviceInfoParentFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), null,
listOf(
"Failed to read the client side experiments map from the disk"
)
)

View File

@@ -1,87 +0,0 @@
package app.revanced.patches.youtube.misc.forcevp9.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.extensions.removeInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
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.misc.forcevp9.annotations.ForceVP9Compatibility
import app.revanced.patches.youtube.misc.forcevp9.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
@Patch
@Dependencies([IntegrationsPatch::class])
@Name("force-vp9-codec")
@Description("Forces the VP9 codec for videos.")
@ForceVP9Compatibility
@Version("0.0.1")
class ForceVP9CodecPatch : BytecodePatch(
listOf(
ForceVP9ParentFingerprint, ReplaceDeviceInfoParentFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
val classDef = ForceVP9ParentFingerprint.result!!.classDef
ForceVP9CodecFingerprint.resolve(data, classDef)
ForceVP9CodecFingerprintTwo.resolve(data, classDef)
replaceInstructions(ForceVP9CodecFingerprint.result!!)
replaceInstructions(ForceVP9CodecFingerprintTwo.result!!)
ReplaceDeviceInfoFingerprint.resolve(data, ReplaceDeviceInfoParentFingerprint.result!!.classDef)
var method = ReplaceDeviceInfoFingerprint.result!!.mutableMethod
replaceDeviceInfos("Manufacturer", method)
replaceDeviceInfos("Model", method)
return PatchResultSuccess()
}
private fun replaceInstructions(result: MethodFingerprintResult) {
val method = result.mutableMethod
method.removeInstructions(0, method.implementation!!.instructions.size - 1)
method.addInstructions(
0, """
invoke-static {}, Lapp/revanced/integrations/patches/ForceCodecPatch;->shouldForceVP9()Z
move-result v0
return v0
"""
)
}
private fun replaceDeviceInfos(name: String, method: MutableMethod) {
var impl = method.implementation!!
//find target instruction for Build.name.uppercase() and replace that with our method
impl.instructions.filter {
((it as? ReferenceInstruction)?.reference as? FieldReference)?.let { field ->
//sget-object v1, Landroid/os/Build;->MANUFACTURER:Ljava/lang/String;
//sget-object v1, Landroid/os/Build;->MODEL:Ljava/lang/String;
field.definingClass == "Landroid/os/Build;" && field.name == name.uppercase()
} == true
}.forEach { instruction ->
val index = method.implementation!!.instructions.indexOf(instruction)
val register = (instruction as OneRegisterInstruction).registerA
// inject the call to
method.removeInstruction(index)
method.addInstructions(
index, """
invoke-static {}, Lapp/revanced/integrations/patches/ForceCodecPatch;->get$name()Ljava/lang/String;
move-result-object v$register
"""
)
}
}
}

View File

@@ -8,7 +8,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.hdrbrightness.annotations.HDRBrightnessCompatibility
@@ -23,7 +23,7 @@ import org.jf.dexlib2.iface.reference.FieldReference
@Description("Makes the brightness of HDR videos follow the system default.")
@HDRBrightnessCompatibility
@Version("0.0.2")
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
class HDRBrightnessPatch : BytecodePatch(
listOf(
HDRBrightnessFingerprintXXZ

View File

@@ -9,7 +9,7 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.replaceInstruction
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
@@ -28,7 +28,7 @@ import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableStringReference
@Patch
@Dependencies(
@DependsOn(
[
MicroGResourcePatch::class,
HideCastButtonPatch::class,

View File

@@ -6,17 +6,16 @@ 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.annotations.Dependencies
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
import app.revanced.patches.youtube.misc.microg.shared.Constants.BASE_MICROG_PACKAGE_NAME
import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_APP_NAME
import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_PACKAGE_NAME
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
@Name("microg-resource-patch")
@Dependencies([FixLocaleConfigErrorPatch::class, SettingsResourcePatch::class])
@DependsOn([FixLocaleConfigErrorPatch::class, SettingsResourcePatch::class])
@Description("Resource patch to allow YouTube ReVanced to run without root and under a different package name.")
@MicroGPatchCompatibility
@Version("0.0.1")
@@ -34,32 +33,32 @@ class MicroGResourcePatch : ResourcePatch() {
it.file.firstChild.appendChild(settingsElement)
}
val settings_fragment = data.get("res/xml/settings_fragment.xml")
val text = settings_fragment.readText()
settings_fragment.writeText(
text.replace("android:targetPackage=\"com.google.android.youtube", "android:targetPackage=\"$REVANCED_PACKAGE_NAME")
val settingsFragment = data["res/xml/settings_fragment.xml"]
settingsFragment.writeText(
settingsFragment.readText().replace(
"android:targetPackage=\"com.google.android.youtube",
"android:targetPackage=\"$REVANCED_PACKAGE_NAME"
)
)
val manifest = data.get("AndroidManifest.xml").readText()
data.get("AndroidManifest.xml").writeText(
manifest.replace(
"package=\"com.google.android.youtube", "package=\"$REVANCED_PACKAGE_NAME"
).replace(
"android:label=\"@string/application_name", "android:label=\"$REVANCED_APP_NAME"
).replace(
"android:authorities=\"com.google.android.youtube", "android:authorities=\"$REVANCED_PACKAGE_NAME"
).replace(
"com.google.android.youtube.permission.C2D_MESSAGE", "$REVANCED_PACKAGE_NAME.permission.C2D_MESSAGE"
).replace( // TODO: might not be needed
"com.google.android.youtube.lifecycle-trojan", "$REVANCED_PACKAGE_NAME.lifecycle-trojan"
).replace( // TODO: might not be needed
"com.google.android.youtube.photopicker_images", "$REVANCED_PACKAGE_NAME.photopicker_images"
).replace(
"com.google.android.c2dm", "$BASE_MICROG_PACKAGE_NAME.android.c2dm"
).replace(
"</queries>", "<package android:name=\"$BASE_MICROG_PACKAGE_NAME.android.gms\"/></queries>"
)
val manifest = data["AndroidManifest.xml"]
manifest.writeText(
manifest.readText()
.replace(
"package=\"com.google.android.youtube", "package=\"$REVANCED_PACKAGE_NAME"
).replace(
"android:authorities=\"com.google.android.youtube", "android:authorities=\"$REVANCED_PACKAGE_NAME"
).replace(
"com.google.android.youtube.permission.C2D_MESSAGE", "$REVANCED_PACKAGE_NAME.permission.C2D_MESSAGE"
).replace( // might not be needed
"com.google.android.youtube.lifecycle-trojan", "$REVANCED_PACKAGE_NAME.lifecycle-trojan"
).replace( // might not be needed
"com.google.android.youtube.photopicker_images", "$REVANCED_PACKAGE_NAME.photopicker_images"
).replace(
"com.google.android.c2dm", "$BASE_MICROG_PACKAGE_NAME.android.c2dm"
).replace(
"</queries>", "<package android:name=\"$BASE_MICROG_PACKAGE_NAME.android.gms\"/></queries>"
)
)
return PatchResultSuccess()

View File

@@ -3,5 +3,4 @@ package app.revanced.patches.youtube.misc.microg.shared
object Constants {
internal const val BASE_MICROG_PACKAGE_NAME = "com.mgoogle"
internal const val REVANCED_PACKAGE_NAME = "app.revanced.android.youtube"
internal const val REVANCED_APP_NAME = "YouTube ReVanced"
}

View File

@@ -7,7 +7,7 @@ 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.DependsOn
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playeroverlay.annotation.PlayerOverlaysHookCompatibility
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.misc.playeroverlay.fingerprint.PlayerOverlay
@Description("Hook for adding custom overlays to the video player.")
@PlayerOverlaysHookCompatibility
@Version("0.0.1")
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
class PlayerOverlaysHookPatch : BytecodePatch(
listOf(
PlayerOverlaysOnFinishInflateFingerprint

View File

@@ -7,7 +7,7 @@ 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.DependsOn
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.annotation.PlayerTypeHookCompatibility
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.misc.playertype.fingerprint.UpdatePlayerType
@Description("Hook to get the current player type of WatchWhileActivity")
@PlayerTypeHookCompatibility
@Version("0.0.1")
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
class PlayerTypeHookPatch : BytecodePatch(
listOf(
UpdatePlayerTypeFingerprint

View File

@@ -9,7 +9,7 @@ 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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@@ -22,7 +22,7 @@ import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
@Patch
@Dependencies([IntegrationsPatch::class, VideoIdPatch::class])
@DependsOn([IntegrationsPatch::class, VideoIdPatch::class])
@Name("remember-video-quality")
@Description("Adds the ability to remember the video quality you chose in the video quality flyout.")
@DefaultVideoQualityCompatibility

View File

@@ -2,7 +2,6 @@ package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
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
@@ -13,9 +12,8 @@ import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.Retu
@MatchingMethod(
"Lcom/google/android/libraries/social/licenses/LicenseActivity;", "onCreate"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
@Version("0.0.1")
object LicenseActivityFingerprint : MethodFingerprint(
null,
null,

View File

@@ -13,9 +13,8 @@ import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.Retu
@MatchingMethod(
"Lapp/revanced/integrations/settingsmenu/ReVancedSettingActivity;", "initializeSettings"
)
@FuzzyPatternScanMethod(2)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.2")
@Version("0.0.1")
object ReVancedSettingsActivityFingerprint : MethodFingerprint(
null,
null,

View File

@@ -0,0 +1,29 @@
package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
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 app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("theme-setter-fingerprint")
@MatchingMethod(
"Lfyq;", "a"
)
@ReturnYouTubeDislikeCompatibility
@Version("0.0.1")
object ThemeSetterFingerprint : MethodFingerprint(
"L",
null,
null,
listOf(Opcode.RETURN_OBJECT),
null,
{ methodDef ->
methodDef.implementation?.instructions?.any {
it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == SettingsPatch.appearanceStringId
} == true
}
)

View File

@@ -8,27 +8,37 @@ import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.addInstructions
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.smali.toInstruction
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.LicenseActivityFingerprint
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ReVancedSettingsActivityFingerprint
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterFingerprint
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
@Patch
@Dependencies([IntegrationsPatch::class, SettingsResourcePatch::class])
@DependsOn(
[
IntegrationsPatch::class,
SettingsResourcePatch::class,
ResourceIdMappingProviderResourcePatch::class
]
)
@Name("settings")
@Description("Adds settings for ReVanced to YouTube.")
@SettingsCompatibility
@Version("0.0.1")
class SettingsPatch : BytecodePatch(
listOf(LicenseActivityFingerprint, ReVancedSettingsActivityFingerprint)
listOf(LicenseActivityFingerprint, ReVancedSettingsActivityFingerprint, ThemeSetterFingerprint)
) {
override fun execute(data: BytecodeData): PatchResult {
val licenseActivityResult = LicenseActivityFingerprint.result!!
val settingsResult = ReVancedSettingsActivityFingerprint.result!!
val themeSetterResult = ThemeSetterFingerprint.result!!
val licenseActivityClass = licenseActivityResult.mutableClass
val settingsClass = settingsResult.mutableClass
@@ -37,7 +47,25 @@ class SettingsPatch : BytecodePatch(
val setThemeMethodName = "setTheme"
val initializeSettings = settingsResult.mutableMethod
// First add the setTheme call to the onCreate method to not affect the offsets.
val setThemeInstruction =
"invoke-static {v0}, Lapp/revanced/integrations/utils/ThemeHelper;->setTheme(Ljava/lang/Object;)V".toInstruction(
themeSetterResult.mutableMethod
)
// add instructions to set the theme of the settings activity
themeSetterResult.mutableMethod.implementation!!.let {
it.addInstruction(
themeSetterResult.patternScanResult!!.startIndex,
setThemeInstruction
)
it.addInstruction(
it.instructions.size - 1, // add before return
setThemeInstruction
)
}
// add the setTheme call to the onCreate method to not affect the offsets.
onCreate.addInstructions(
1,
"""
@@ -46,11 +74,18 @@ class SettingsPatch : BytecodePatch(
"""
)
// Add the initializeSettings call to the onCreate method.
// add the initializeSettings call to the onCreate method.
onCreate.addInstruction(
0,
"invoke-static { p0 }, ${settingsClass.type}->$setThemeMethodName(${licenseActivityClass.type})V"
)
return PatchResultSuccess()
}
internal companion object {
val appearanceStringId = ResourceIdMappingProviderResourcePatch.resourceMappings.find {
it.type == "string" && it.name == "app_theme_appearance_dark"
}!!.id
}
}

View File

@@ -5,17 +5,18 @@ 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.annotations.Dependencies
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.impl.ResourcePatch
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility
import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources
import app.revanced.util.resources.ResourceUtils.copyXmlNode
import org.w3c.dom.Element
@Name("settings-resource-patch")
@SettingsCompatibility
@Dependencies([FixLocaleConfigErrorPatch::class])
@DependsOn([FixLocaleConfigErrorPatch::class])
@Version("0.0.1")
class SettingsResourcePatch : ResourcePatch() {
override fun execute(data: ResourceData): PatchResult {
@@ -55,6 +56,17 @@ class SettingsResourcePatch : ResourcePatch() {
data.copyResources("settings", resourceGroup)
}
data.xmlEditor["AndroidManifest.xml"].use {
val manifestNode = it
.file
.getElementsByTagName("manifest")
.item(0) as Element
val element = it.file.createElement("uses-permission")
element.setAttribute("android:name", "android.permission.SCHEDULE_EXACT_ALARM")
manifestNode.appendChild(element)
}
return PatchResultSuccess()
}
}

View File

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

View File

@@ -0,0 +1,32 @@
package app.revanced.patches.youtube.misc.videobuffer.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.misc.videobuffer.annotations.CustomVideoBufferCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
@Name("maxbuffer-fingerprint")
@MatchingMethod(
"Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;", "r"
)
@DirectPatternScanMethod
@CustomVideoBufferCompatibility
@Version("0.0.1")
object MaxBufferFingerprint : MethodFingerprint(
"I", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(),
listOf(Opcode.SGET_OBJECT, Opcode.IGET, Opcode.IF_EQZ, Opcode.RETURN),
null,
customFingerprint = { methodDef ->
methodDef.definingClass.equals("Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;")
&& methodDef.implementation!!.instructions.any {
((it as? NarrowLiteralInstruction)?.narrowLiteral == 120000)
&& methodDef.name.equals("r")
}
}
)

View File

@@ -0,0 +1,31 @@
package app.revanced.patches.youtube.misc.videobuffer.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.misc.videobuffer.annotations.CustomVideoBufferCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
@Name("playbackbuffer-fingerprint")
@MatchingMethod(
"Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;", "p"
)
@DirectPatternScanMethod
@CustomVideoBufferCompatibility
@Version("0.0.1")
object PlaybackBufferFingerprint : MethodFingerprint(
"I", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(),
listOf(Opcode.IF_LEZ, Opcode.RETURN),
null,
customFingerprint = { methodDef ->
methodDef.definingClass.equals("Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;")
&& methodDef.implementation!!.instructions.any {
((it as? NarrowLiteralInstruction)?.narrowLiteral == 1600)
}
}
)

View File

@@ -0,0 +1,31 @@
package app.revanced.patches.youtube.misc.videobuffer.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.misc.videobuffer.annotations.CustomVideoBufferCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
@Name("playbackbuffer-fingerprint")
@MatchingMethod(
"Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;", "t"
)
@DirectPatternScanMethod
@CustomVideoBufferCompatibility
@Version("0.0.1")
object ReBufferFingerprint : MethodFingerprint(
"I", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(),
listOf(Opcode.IF_LEZ, Opcode.RETURN),
null,
customFingerprint = { methodDef ->
methodDef.definingClass.equals("Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;")
&& methodDef.implementation!!.instructions.any {
((it as? NarrowLiteralInstruction)?.narrowLiteral == 5000)
}
}
)

View File

@@ -0,0 +1,73 @@
package app.revanced.patches.youtube.misc.videobuffer.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.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patches.youtube.misc.videobuffer.annotations.CustomVideoBufferCompatibility
import app.revanced.patches.youtube.misc.videobuffer.fingerprints.MaxBufferFingerprint
import app.revanced.patches.youtube.misc.videobuffer.fingerprints.PlaybackBufferFingerprint
import app.revanced.patches.youtube.misc.videobuffer.fingerprints.ReBufferFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@Name("custom-video-buffer")
@Description("Lets you change the buffers of videos.")
@CustomVideoBufferCompatibility
@Version("0.0.1")
class CustomVideoBufferPatch : BytecodePatch(
listOf(
MaxBufferFingerprint, PlaybackBufferFingerprint, ReBufferFingerprint
)
) {
override fun execute(data: BytecodeData): PatchResult {
execMaxBuffer()
execPlaybackBuffer(data)
execReBuffer(data)
return PatchResultSuccess()
}
private fun execMaxBuffer() {
val result = MaxBufferFingerprint.result!!
val method = result.mutableMethod
val index = result.patternScanResult!!.endIndex - 1
val register = (method.implementation!!.instructions.get(index) as OneRegisterInstruction).registerA
method.addInstructions(
index + 1, """
invoke-static {}, Lapp/revanced/integrations/patches/VideoBufferPatch;->getMaxBuffer()I
move-result v$register
"""
)
}
private fun execPlaybackBuffer(data: BytecodeData) {
val result = PlaybackBufferFingerprint.result!!
val method = result.mutableMethod
val index = result.patternScanResult!!.startIndex
val register = (method.implementation!!.instructions.get(index) as OneRegisterInstruction).registerA
method.addInstructions(
index + 1, """
invoke-static {}, Lapp/revanced/integrations/patches/VideoBufferPatch;->getPlaybackBuffer()I
move-result v$register
"""
)
}
private fun execReBuffer(data: BytecodeData) {
val result = ReBufferFingerprint.result!!
val method = result.mutableMethod
val index = result.patternScanResult!!.startIndex
val register = (method.implementation!!.instructions.get(index) as OneRegisterInstruction).registerA
method.addInstructions(
index + 1, """
invoke-static {}, Lapp/revanced/integrations/patches/VideoBufferPatch;->getReBuffer()I
move-result v$register
"""
)
}
}

View File

@@ -8,7 +8,7 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
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.DependsOn
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
@@ -20,7 +20,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Description("Hook to detect when the video id changes")
@VideoIdCompatibility
@Version("0.0.1")
@Dependencies([IntegrationsPatch::class])
@DependsOn([IntegrationsPatch::class])
class VideoIdPatch : BytecodePatch(
listOf(
VideoIdFingerprint

View File

@@ -2,7 +2,6 @@ package app.revanced.util.resources
import app.revanced.patcher.data.impl.DomFileEditor
import app.revanced.patcher.data.impl.ResourceData
import java.io.OutputStream
import java.nio.file.Files
internal object ResourceUtils {
@@ -44,7 +43,7 @@ internal object ResourceUtils {
// Copy nodes from the resources node to the real resource node
elementTag.copyXmlNode(
this.xmlEditor[stringsResourceInputStream, OutputStream.nullOutputStream()],
this.xmlEditor[stringsResourceInputStream],
this.xmlEditor["res/$targetResource"]
).close()
}

View File

@@ -139,7 +139,7 @@
<SwitchPreference android:title="@string/revanced_branding_watermark_title" android:key="revanced_branding_watermark_enabled" android:defaultValue="false" android:summaryOn="@string/revanced_branding_watermark_summary_on" android:summaryOff="@string/revanced_branding_watermark_summary_off" />
<SwitchPreference android:title="@string/revanced_cast_button_title" android:key="revanced_cast_button_enabled" android:defaultValue="false" android:summaryOn="@string/revanced_cast_button_summary_on" android:summaryOff="@string/revanced_cast_button_summary_off" />
<SwitchPreference android:title="@string/revanced_autoplay_button_title" android:key="revanced_autoplay_button_enabled" android:defaultValue="false" android:summaryOn="@string/revanced_autoplay_button_summary_on" android:summaryOff="@string/revanced_autoplay_button_summary_off" />
<!--<SwitchPreference android:title="@string/revanced_tablet_miniplayer_title" android:key="revanced_tablet_miniplayer" android:defaultValue="false" android:summaryOn="@string/revanced_tablet_miniplayer_summary_on" android:summaryOff="@string/revanced_tablet_miniplayer_summary_off" />-->
<SwitchPreference android:title="@string/revanced_tablet_miniplayer_title" android:key="revanced_tablet_miniplayer" android:defaultValue="false" android:summaryOn="@string/revanced_tablet_miniplayer_summary_on" android:summaryOff="@string/revanced_tablet_miniplayer_summary_off" />
<SwitchPreference android:title="@string/revanced_create_button_title" android:key="revanced_create_button_enabled" android:defaultValue="false" android:summaryOn="@string/revanced_create_button_summary_on" android:summaryOff="@string/revanced_create_button_summary_off" />
<SwitchPreference android:title="@string/revanced_new_actionbar_title" android:key="revanced_new_actionbar" android:defaultValue="false" android:summaryOn="@string/revanced_new_actionbar_summary_on" android:summaryOff="@string/revanced_new_actionbar_summary_off" />
<SwitchPreference android:title="@string/revanced_shorts_button_title" android:key="revanced_shorts_button_enabled" android:defaultValue="false" android:summaryOn="@string/revanced_shorts_button_summary_on" android:summaryOff="@string/revanced_shorts_button_summary_off" />