Compare commits

...

20 Commits

Author SHA1 Message Date
semantic-release-bot
9ab3bd0313 chore(release): 2.107.0 [skip ci]
# [2.107.0](https://github.com/revanced/revanced-patches/compare/v2.106.1...v2.107.0) (2022-11-13)

### Features

* **ticktick:** `unlock-themes` patch ([#1028](https://github.com/revanced/revanced-patches/issues/1028)) ([a7eda35](0f10888aa3))
* **twitch/show-deleted-messages:** `show-deleted-messages` patch ([#1030](https://github.com/revanced/revanced-patches/issues/1030)) ([2612f55](63c0e5dc84))
2022-11-13 01:24:46 +00:00
Jonathan
0f10888aa3 feat(ticktick): unlock-themes patch (#1028) 2022-11-13 02:22:40 +01:00
Tim Schneeberger
63c0e5dc84 feat(twitch/show-deleted-messages): show-deleted-messages patch (#1030)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-11-13 02:21:40 +01:00
semantic-release-bot
41bc0222b9 chore(release): 2.106.1 [skip ci]
## [2.106.1](https://github.com/revanced/revanced-patches/compare/v2.106.0...v2.106.1) (2022-11-11)

### Bug Fixes

* **youtube/custom-branding:** use high resolution icons ([#1018](https://github.com/revanced/revanced-patches/issues/1018)) ([2f626a3](71e4cc964b))
2022-11-11 10:56:27 +00:00
KAZI MMT
71e4cc964b fix(youtube/custom-branding): use high resolution icons (#1018) 2022-11-11 11:54:05 +01:00
semantic-release-bot
afc9886ebd chore(release): 2.106.0 [skip ci]
# [2.106.0](https://github.com/revanced/revanced-patches/compare/v2.105.0...v2.106.0) (2022-11-09)

### Features

* **youtube:** `open-links-directly` patch ([#999](https://github.com/revanced/revanced-patches/issues/999)) ([2e06b8d](de06d96ea0))
2022-11-09 20:43:55 +00:00
johnconner122
de06d96ea0 feat(youtube): open-links-directly patch (#999)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-11-09 21:42:07 +01:00
semantic-release-bot
1139f77cb9 chore(release): 2.105.0 [skip ci]
# [2.105.0](https://github.com/revanced/revanced-patches/compare/v2.104.2...v2.105.0) (2022-11-09)

### Features

* **nyx:** `unlock-pro` patch ([#1004](https://github.com/revanced/revanced-patches/issues/1004)) ([f72fd91](5a801b1562))
2022-11-09 12:48:57 +00:00
Jonathan
5a801b1562 feat(nyx): unlock-pro patch (#1004) 2022-11-09 13:46:55 +01:00
OxrxL
7f301090b9 refactor(youtube/general-ads-patch): squash extension classes (#1006) 2022-11-09 06:21:56 +01:00
OxrxL
28a687c605 refactor(youtube/general-ads-patch): remove unused code (#1005) 2022-11-09 01:20:13 +01:00
OxrxL
9b74a08ae1 refactor(youtube/general-ads-patch): removed redundant code (#1003) 2022-11-08 18:10:04 +01:00
semantic-release-bot
1177c41373 chore(release): 2.104.2 [skip ci]
## [2.104.2](https://github.com/revanced/revanced-patches/compare/v2.104.1...v2.104.2) (2022-11-08)

### Bug Fixes

* **youtube/hide-endscreen-cards:** restore functionality ([#993](https://github.com/revanced/revanced-patches/issues/993)) ([38eceb7](be4de62c8f))
2022-11-08 17:05:54 +00:00
OxrxL
be4de62c8f fix(youtube/hide-endscreen-cards): restore functionality (#993)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-11-08 18:04:16 +01:00
semantic-release-bot
528156aec9 chore(release): 2.104.1 [skip ci]
## [2.104.1](https://github.com/revanced/revanced-patches/compare/v2.104.0...v2.104.1) (2022-11-07)

### Bug Fixes

* **youtube/general-ads:** incorrect description for info panels ([bd5c64d](fa147bd6cc))
* **youtube/hide-info-cards:** remove initial popup of info-cards ([#992](https://github.com/revanced/revanced-patches/issues/992)) ([47fdda8](e377ecf208))
2022-11-07 23:13:02 +00:00
OxrxL
e377ecf208 fix(youtube/hide-info-cards): remove initial popup of info-cards (#992)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-11-08 00:11:12 +01:00
oSumAtrIX
fa147bd6cc fix(youtube/general-ads): incorrect description for info panels 2022-11-08 00:09:28 +01:00
OxrxL
88211e28ca refactor(youtube/general-ads-patch): remove unnecessary patches (#994) 2022-11-07 13:55:31 +01:00
semantic-release-bot
a4e3a97937 chore(release): 2.104.0 [skip ci]
# [2.104.0](https://github.com/revanced/revanced-patches/compare/v2.103.0...v2.104.0) (2022-11-06)

### Features

* **hexeditor:** `disable-ads` patch ([#973](https://github.com/revanced/revanced-patches/issues/973)) ([1866e1d](02bd807a27))
2022-11-06 12:00:48 +00:00
johnconner122
02bd807a27 feat(hexeditor): disable-ads patch (#973)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-11-06 12:58:43 +01:00
61 changed files with 953 additions and 264 deletions

View File

@@ -1,3 +1,54 @@
# [2.107.0](https://github.com/revanced/revanced-patches/compare/v2.106.1...v2.107.0) (2022-11-13)
### Features
* **ticktick:** `unlock-themes` patch ([#1028](https://github.com/revanced/revanced-patches/issues/1028)) ([7f1fedc](https://github.com/revanced/revanced-patches/commit/7f1fedcddd4330a5f884b813a20f2f8e84e2c9da))
* **twitch/show-deleted-messages:** `show-deleted-messages` patch ([#1030](https://github.com/revanced/revanced-patches/issues/1030)) ([7e6b453](https://github.com/revanced/revanced-patches/commit/7e6b4534013a03ddc7eb11a1f911fa0564372118))
## [2.106.1](https://github.com/revanced/revanced-patches/compare/v2.106.0...v2.106.1) (2022-11-11)
### Bug Fixes
* **youtube/custom-branding:** use high resolution icons ([#1018](https://github.com/revanced/revanced-patches/issues/1018)) ([1c9d1ac](https://github.com/revanced/revanced-patches/commit/1c9d1acf2b7aff4cd52d17009ff01246f74d2214))
# [2.106.0](https://github.com/revanced/revanced-patches/compare/v2.105.0...v2.106.0) (2022-11-09)
### Features
* **youtube:** `open-links-directly` patch ([#999](https://github.com/revanced/revanced-patches/issues/999)) ([bf85f62](https://github.com/revanced/revanced-patches/commit/bf85f62f30242f91bdaf53b44ae6a9a2b3b6e1b4))
# [2.105.0](https://github.com/revanced/revanced-patches/compare/v2.104.2...v2.105.0) (2022-11-09)
### Features
* **nyx:** `unlock-pro` patch ([#1004](https://github.com/revanced/revanced-patches/issues/1004)) ([9dd8239](https://github.com/revanced/revanced-patches/commit/9dd82391f3f97247224e09e0143b2272a3d47053))
## [2.104.2](https://github.com/revanced/revanced-patches/compare/v2.104.1...v2.104.2) (2022-11-08)
### Bug Fixes
* **youtube/hide-endscreen-cards:** restore functionality ([#993](https://github.com/revanced/revanced-patches/issues/993)) ([eb1bae2](https://github.com/revanced/revanced-patches/commit/eb1bae2c55e65ad29030dce6746a18662dd0fe25))
## [2.104.1](https://github.com/revanced/revanced-patches/compare/v2.104.0...v2.104.1) (2022-11-07)
### Bug Fixes
* **youtube/general-ads:** incorrect description for info panels ([77b029e](https://github.com/revanced/revanced-patches/commit/77b029e82e481a13516b1c8a888c42817507cdea))
* **youtube/hide-info-cards:** remove initial popup of info-cards ([#992](https://github.com/revanced/revanced-patches/issues/992)) ([19f3f03](https://github.com/revanced/revanced-patches/commit/19f3f038585c313a969adf3d4095a60ab4c83ede))
# [2.104.0](https://github.com/revanced/revanced-patches/compare/v2.103.0...v2.104.0) (2022-11-06)
### Features
* **hexeditor:** `disable-ads` patch ([#973](https://github.com/revanced/revanced-patches/issues/973)) ([a48e5fd](https://github.com/revanced/revanced-patches/commit/a48e5fd50dcf9ee061ffd5c5ed0b997067f40652))
# [2.103.0](https://github.com/revanced/revanced-patches/compare/v2.102.1...v2.103.0) (2022-11-05)

View File

@@ -50,6 +50,14 @@ The official Patch bundle provided by ReVanced and the community.
| `promo-code-unlock` | Disables the validation of promo code. Any code will work to unlock all features. | all |
</details>
### 📦 `com.myprog.hexedit`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `disable-ads` | Disables ads in HexEditor. | all |
</details>
### 📦 `com.spotify.music`
<details>
@@ -73,6 +81,7 @@ The official Patch bundle provided by ReVanced and the community.
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 17.43.36 |
| `hide-create-button` | Hides the create button in the navigation bar. | 17.43.36 |
| `disable-startup-shorts-player` | Disables playing YouTube Shorts when launching YouTube. | 17.43.36 |
| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 17.43.36 |
| `hide-cast-button` | Hides the cast button in the video player. | all |
| `sponsorblock` | Integrate SponsorBlock. | 17.43.36 |
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 17.43.36 |
@@ -88,17 +97,18 @@ The official Patch bundle provided by ReVanced and the community.
| `hide-email-address` | Hides the email address in the account switcher. | 17.43.36 |
| `tablet-mini-player` | Enables the tablet mini player layout. | 17.43.36 |
| `hide-watermark` | Hides creator's watermarks on videos. | 17.43.36 |
| `hide-info-cards` | Hides info-cards in videos. | 17.43.36 |
| `hide-my-mix` | Hides mix playlists. | 17.43.36 |
| `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all |
| `premium-heading` | Shows premium branding on the home screen. | all |
| `old-quality-layout` | Enables the original quality flyout menu. | 17.43.36 |
| `general-ads` | Removes general ads. | 17.43.36 |
| `video-ads` | Removes ads in the video player. | 17.43.36 |
| `hide-infocard-suggestions` | Hides infocards in videos. | 17.43.36 |
| `swipe-controls` | Adds volume and brightness swipe controls. | 17.43.36 |
| `downloads` | Enables downloading music and videos from YouTube. | 17.43.36 |
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 17.43.36 |
| `settings` | Adds settings for ReVanced to YouTube. | all |
| `open-links-directly` | Bypasses redirect links and allows opening links directly. | 17.43.36 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 17.43.36 |
| `custom-video-buffer` | Lets you change the buffers of videos. | 17.43.36 |
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
@@ -118,6 +128,22 @@ The official Patch bundle provided by ReVanced and the community.
| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all |
</details>
### 📦 `com.ticktick.task`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-themes` | Unlocks all themes. | all |
</details>
### 📦 `tv.twitch.android.app`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | all |
</details>
### 📦 `com.garzotto.pflotsh.ecmwf_a`
<details>
@@ -152,6 +178,14 @@ The official Patch bundle provided by ReVanced and the community.
| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | all |
</details>
### 📦 `com.awedea.nyx`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks all pro features. | all |
</details>
## 📝 JSON Format

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official
version = 2.103.0
version = 2.107.0

File diff suppressed because one or more lines are too long

View File

@@ -18,17 +18,6 @@ import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
import org.w3c.dom.Node
import java.nio.file.Files
// TODO: this method does not make sense here
internal fun MutableMethodImplementation.injectHideCall(
index: Int,
register: Int
) {
this.addInstruction(
index,
"invoke-static { v$register }, Lapp/revanced/integrations/patches/HideHomeAdsPatch;->HideHomeAds(Landroid/view/View;)V".toInstruction()
)
}
/**
* traverse the class hierarchy starting from the given root class
*

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.hexeditor.ad.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[
Package("com.myprog.hexedit")
]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HexEditorAdsCompatibility

View File

@@ -0,0 +1,15 @@
package app.revanced.patches.hexeditor.ad.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility
@Name("ads-fingerprint-primary")
@HexEditorAdsCompatibility
@Version("0.0.1")
object PrimaryAdsFingerprint : MethodFingerprint(
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("PreferencesHelper;") && methodDef.name == "isAdsDisabled"
}
)

View File

@@ -0,0 +1,39 @@
package app.revanced.patches.hexeditor.ad.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.extensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility
import app.revanced.patches.hexeditor.ad.fingerprints.PrimaryAdsFingerprint
@Patch
@Name("disable-ads")
@Description("Disables ads in HexEditor.")
@HexEditorAdsCompatibility
@Version("0.0.1")
class HexEditorAdsPatch : BytecodePatch(
listOf(
PrimaryAdsFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val method = PrimaryAdsFingerprint.result!!.mutableMethod
method.replaceInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.nyx.misc.pro.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.awedea.nyx")])
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class UnlockProCompatibility

View File

@@ -0,0 +1,15 @@
package app.revanced.patches.nyx.misc.pro.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.nyx.misc.pro.annotations.UnlockProCompatibility
@Name("check-pro-fingerprint")
@UnlockProCompatibility
@Version("0.0.1")
object CheckProFingerprint : MethodFingerprint(
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("BillingManager;") && methodDef.name == "isProVersion"
}
)

View File

@@ -0,0 +1,38 @@
package app.revanced.patches.nyx.misc.pro.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.nyx.misc.pro.annotations.UnlockProCompatibility
import app.revanced.patches.nyx.misc.pro.fingerprints.CheckProFingerprint
@Patch
@Name("unlock-pro")
@Description("Unlocks all pro features.")
@UnlockProCompatibility
@Version("0.0.1")
class UnlockProPatch : BytecodePatch(
listOf(
CheckProFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val method = CheckProFingerprint.result!!.mutableMethod
method.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.ticktick.misc.themeunlock.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.ticktick.task")])
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class UnlockThemesCompatibility

View File

@@ -0,0 +1,15 @@
package app.revanced.patches.ticktick.misc.themeunlock.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
@Name("check-locked-theme-fingerprint")
@UnlockThemesCompatibility
@Version("0.0.1")
object CheckLockedThemesFingerprint : MethodFingerprint(
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("Theme;") && methodDef.name == "isLockedTheme"
}
)

View File

@@ -0,0 +1,15 @@
package app.revanced.patches.ticktick.misc.themeunlock.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
@Name("set-theme-fingerprint")
@UnlockThemesCompatibility
@Version("0.0.1")
object SetThemeFingerprint : MethodFingerprint(
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("ThemePreviewActivity;") && methodDef.name == "lambda\$updateUserBtn\$1"
}
)

View File

@@ -0,0 +1,43 @@
package app.revanced.patches.ticktick.misc.themeunlock.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.removeInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.ticktick.misc.themeunlock.annotations.UnlockThemesCompatibility
import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.CheckLockedThemesFingerprint
import app.revanced.patches.ticktick.misc.themeunlock.fingerprints.SetThemeFingerprint
@Patch
@Name("unlock-themes")
@Description("Unlocks all themes.")
@UnlockThemesCompatibility
@Version("0.0.1")
class UnlockProPatch : BytecodePatch(
listOf(
CheckLockedThemesFingerprint,
SetThemeFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val lockedThemesMethod = CheckLockedThemesFingerprint.result!!.mutableMethod
lockedThemesMethod.addInstructions(
0,
"""
const/4 v0, 0x0
return v0
"""
)
val setThemeMethod = SetThemeFingerprint.result!!.mutableMethod
setThemeMethod.removeInstructions(0, 9)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,10 @@
package app.revanced.patches.twitch.chat.antidelete.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("tv.twitch.android.app")])
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ShowDeletedMessagesCompatibility

View File

@@ -0,0 +1,19 @@
package app.revanced.patches.twitch.chat.antidelete.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
import org.jf.dexlib2.AccessFlags
@Name("deleted-msg-span-ctor-fingerprint")
@ShowDeletedMessagesCompatibility
@Version("0.0.1")
object DeletedMessageClickableSpanCtorFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("DeletedMessageClickableSpan;")
}
)

View File

@@ -0,0 +1,16 @@
package app.revanced.patches.twitch.chat.antidelete.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
@Name("has-mod-access-fingerprint")
@ShowDeletedMessagesCompatibility
@Version("0.0.1")
object SetHasModAccessFingerprint : MethodFingerprint(
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("DeletedMessageClickableSpan;") && methodDef.name == "setHasModAccess"
}
)

View File

@@ -0,0 +1,45 @@
package app.revanced.patches.twitch.chat.antidelete.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.*
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility
import app.revanced.patches.twitch.chat.antidelete.fingerprints.*
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.instruction.BuilderInstruction10x
@Patch
@Name("show-deleted-messages")
@Description("Shows deleted chat messages behind a clickable spoiler.")
@ShowDeletedMessagesCompatibility
@Version("0.0.1")
class ShowDeletedMessagesPatch : BytecodePatch(
listOf(
SetHasModAccessFingerprint,
DeletedMessageClickableSpanCtorFingerprint,
)
) {
override fun execute(context: BytecodeContext): PatchResult {
// Force set hasModAccess member to true in constructor
with(DeletedMessageClickableSpanCtorFingerprint.result!!.mutableMethod) {
addInstructions(
implementation!!.instructions.lastIndex, /* place in front of return-void */
"""
const/4 v0, 1
iput-boolean v0, p0, $definingClass->hasModAccess:Z
"""
)
}
// Disable setHasModAccess setter
with(SetHasModAccessFingerprint.result!!.mutableMethod.implementation!!) {
addInstruction(0, BuilderInstruction10x(Opcode.RETURN_VOID))
}
return PatchResultSuccess()
}
}

View File

@@ -1,45 +0,0 @@
package app.revanced.patches.youtube.ad.general.bytecode.extensions
import app.revanced.patcher.extensions.softCompareTo
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.iface.reference.Reference
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
internal object MethodExtensions {
internal fun MutableClass.findMutableMethodOf(
method: Method
) = this.methods.first {
it.softCompareTo(
ImmutableMethodReference(
method.definingClass, method.name, method.parameters, method.returnType
)
)
}
internal inline fun <reified T : Reference> Instruction.toDescriptor(): String {
val reference = (this as ReferenceInstruction).reference
return when (T::class) {
MethodReference::class -> {
val methodReference = reference as MethodReference
"${methodReference.definingClass}->${methodReference.name}(${
methodReference.parameterTypes.joinToString(
""
) { it }
})${methodReference.returnType}"
}
FieldReference::class -> {
val fieldReference = reference as FieldReference
"${fieldReference.definingClass}->${fieldReference.name}:${fieldReference.type}"
}
else -> throw PatchResultError("Unsupported reference type")
}
}
}

View File

@@ -1,12 +1,12 @@
package app.revanced.patches.youtube.ad.general.bytecode.patch
import app.revanced.extensions.injectHideCall
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.extensions.softCompareTo
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
@@ -18,9 +18,8 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patcher.util.smali.toInstruction
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.findMutableMethodOf
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.toDescriptor
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralResourceAdsPatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
@@ -28,15 +27,18 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.builder.instruction.BuilderInstruction10x
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.formats.*
import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.iface.reference.Reference
import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
@Patch
@DependsOn([ResourceMappingResourcePatch::class, IntegrationsPatch::class, SettingsPatch::class, GeneralResourceAdsPatch::class])
@@ -52,19 +54,12 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
private val resourceIds = arrayOf(
"ad_attribution",
"reel_multiple_items_shelf",
"info_cards_drawer_header",
"endscreen_element_layout_video",
"endscreen_element_layout_circle",
"endscreen_element_layout_icon",
"promoted_video_item_land",
"promoted_video_item_full_bleed",
).map { name ->
ResourceMappingResourcePatch.resourceMappings.single { it.name == name }.id
}
private val stringReferences = arrayOf(
"Claiming to use more elements than provided",
"loadVideo() called on LocalDirector in wrong state",
"LoggingProperties are not in proto format"
)
@@ -144,8 +139,8 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
"revanced_adremover_info_panel",
StringResource("revanced_adremover_info_panel_enabled_title", "Remove info panels"),
true,
StringResource("revanced_adremover_info_panel_enabled_summary_on", "Merchandise banners are hidden"),
StringResource("revanced_adremover_info_panel_enabled_summary_off", "Merchandise banners are shown")
StringResource("revanced_adremover_info_panel_enabled_summary_on", "Info panels are hidden"),
StringResource("revanced_adremover_info_panel_enabled_summary_off", "Info panels are shown")
),
SwitchPreference(
"revanced_adremover_medical_panel",
@@ -214,7 +209,6 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
// insert hide call to hide the view corresponding to the resource
val viewRegister = (invokeInstruction as Instruction35c).registerC
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
}
resourceIds[1] -> { // reel ads
@@ -231,61 +225,6 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
val viewRegister = (iPutInstruction as Instruction22c).registerA
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
}
resourceIds[2] -> { // info cards ads
// and is followed by an instruction with the mnemonic INVOKE_VIRTUAL
val removeIndex = index - 1
val invokeInstruction = instructions.elementAt(removeIndex)
if (invokeInstruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
// create proxied method, make sure to not re-resolve() the current class
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
if (mutableMethod == null) mutableMethod =
mutableClass!!.findMutableMethodOf(method)
//ToDo: Add Settings toggle for whatever this is
mutableMethod!!.implementation!!.removeInstruction(removeIndex)
}
resourceIds[3], resourceIds[4], resourceIds[5] -> { // end screen ads
// and is followed by an instruction with the mnemonic IPUT_OBJECT
val insertIndex = index + 7
val invokeInstruction = instructions.elementAt(insertIndex)
if (invokeInstruction.opcode != Opcode.IPUT_OBJECT) return@forEachIndexed
// create proxied method, make sure to not re-resolve() the current class
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
if (mutableMethod == null) mutableMethod =
mutableClass!!.findMutableMethodOf(method)
// TODO: dynamically get registers
mutableMethod!!.addInstructions(
insertIndex, """
const/16 v1, 0x8
invoke-virtual {v0,v1}, Landroid/widget/FrameLayout;->setVisibility(I)V
"""
)
}
resourceIds[6] -> {
// and is followed by an instruction with the mnemonic INVOKE_DIRECT
val insertIndex = index + 3
val invokeInstruction = instructions.elementAt(insertIndex)
if (invokeInstruction.opcode != Opcode.INVOKE_DIRECT) return@forEachIndexed
// create proxied method, make sure to not re-resolve() the current class
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
if (mutableMethod == null) mutableMethod =
mutableClass!!.findMutableMethodOf(method)
// insert hide call to hide the view corresponding to the resource
val viewRegister = (invokeInstruction as Instruction35c).registerE
mutableMethod!!.implementation!!.injectHideCall(insertIndex, viewRegister)
}
resourceIds[7] -> {
// TODO, go to class, hide the inflated view
}
}
}
@@ -308,11 +247,7 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
)
}
stringReferences[1] -> {
// TODO: migrate video ads patch to here if necessary
}
stringReferences[2] -> { // Litho ads
stringReferences[1] -> { // Litho ads
val proxy = context.proxy(classDef)
val proxiedClass = proxy.mutableClass
@@ -380,4 +315,45 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
instruction.opcode == Opcode.CONST && (instruction as Instruction31i).narrowLiteral == lithoConstant
} ?: false
}
}
private fun MutableClass.findMutableMethodOf(
method: Method
) = this.methods.first {
it.softCompareTo(
ImmutableMethodReference(
method.definingClass, method.name, method.parameters, method.returnType
)
)
}
private inline fun <reified T : Reference> Instruction.toDescriptor(): String {
val reference = (this as ReferenceInstruction).reference
return when (T::class) {
MethodReference::class -> {
val methodReference = reference as MethodReference
"${methodReference.definingClass}->${methodReference.name}(${
methodReference.parameterTypes.joinToString(
""
) { it }
})${methodReference.returnType}"
}
FieldReference::class -> {
val fieldReference = reference as FieldReference
"${fieldReference.definingClass}->${fieldReference.name}:${fieldReference.type}"
}
else -> throw PatchResultError("Unsupported reference type")
}
}
private fun MutableMethodImplementation.injectHideCall(
index: Int,
register: Int
) {
this.addInstruction(
index,
"invoke-static { v$register }, Lapp/revanced/integrations/patches/HideHomeAdsPatch;->HideHomeAds(Landroid/view/View;)V".toInstruction()
)
}
}

View File

@@ -1,20 +0,0 @@
package app.revanced.patches.youtube.ad.general.bytecode.utils
import app.revanced.patcher.extensions.or
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.iface.MethodImplementation
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodParameter
internal object MethodUtils {
internal fun createMutableMethod(
definingClass: String, name: String, returnType: String, parameter: String, implementation: MethodImplementation
) = ImmutableMethod(
definingClass, name, listOf(
ImmutableMethodParameter(
parameter, null, null
)
), returnType, AccessFlags.PRIVATE or AccessFlags.STATIC, null, null, implementation
).toMutable()
}

View File

@@ -1,19 +0,0 @@
package app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("hide-infocard-suggestions-fingerprint")
@FuzzyPatternScanMethod(2)
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
object HideInfocardSuggestionsFingerprint : MethodFingerprint(
"Ljava/lang/Boolean;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
strings = listOf("vibrator")
)

View File

@@ -1,19 +0,0 @@
package app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("hide-infocard-suggestions-parent-fingerprint")
@FuzzyPatternScanMethod(2)
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
object HideInfocardSuggestionsParentFingerprint : MethodFingerprint(
"Ljava/lang/String;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
strings = listOf("player_overlay_info_card_teaser"),
)

View File

@@ -1,67 +0,0 @@
package app.revanced.patches.youtube.ad.infocardsuggestions.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsFingerprint
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
@Patch
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("hide-infocard-suggestions")
@Description("Hides infocards in videos.")
@HideInfocardSuggestionsCompatibility
@Version("0.0.1")
class HideInfocardSuggestionsPatch : BytecodePatch(
listOf(
HideInfocardSuggestionsParentFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference(
"revanced_info_cards_enabled",
StringResource("revanced_info_cards_enabled_title", "Show info-cards"),
false,
StringResource("revanced_info_cards_enabled_summary_on", "Info-cards are shown"),
StringResource("revanced_info_cards_enabled_summary_off", "Info-cards are hidden")
)
)
val parentResult = HideInfocardSuggestionsParentFingerprint.result
?: return PatchResultError("Parent fingerprint not resolved!")
HideInfocardSuggestionsFingerprint.resolve(context, parentResult.classDef)
val result = HideInfocardSuggestionsFingerprint.result
?: return PatchResultError("Required parent method could not be found.")
val method = result.mutableMethod
val implementation = method.implementation
?: return PatchResultError("Implementation not found.")
val index = implementation.instructions.indexOfFirst { ((it as? BuilderInstruction35c)?.reference.toString() == "Landroid/view/View;->setVisibility(I)V") }
method.replaceInstruction(index, """
invoke-static {p1}, Lapp/revanced/integrations/patches/HideInfoCardSuggestionsPatch;->hideInfoCardSuggestions(Landroid/view/View;)V
""")
return PatchResultSuccess()
}
}

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.youtube.ad.infocardsuggestions.annotations
package app.revanced.patches.youtube.layout.hideendscreencards.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@@ -10,4 +10,4 @@ import app.revanced.patcher.annotation.Package
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HideInfocardSuggestionsCompatibility
internal annotation class HideEndscreenCardsCompatibility

View File

@@ -0,0 +1,28 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("layout-circle-fingerprint")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
object LayoutCircleFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutCircle
} == true
}
)

View File

@@ -0,0 +1,28 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("layout-icon-fingerprint")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
object LayoutIconFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST_4,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutIcon
} == true
}
)

View File

@@ -0,0 +1,28 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("layout-video-fingerprint")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
object LayoutVideoFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutVideo
} == true
}
)

View File

@@ -0,0 +1,57 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.fingerprint.Fingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutCircleFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutIconFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutVideoFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.formats.Instruction21c
@Patch
@DependsOn([IntegrationsPatch::class, HideEndscreenCardsResourcePatch::class])
@Name("hide-endscreen-cards")
@Description("Hides the suggested video cards at the end of a video in fullscreen.")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
class HideEndscreenCardsPatch : BytecodePatch(
listOf(
LayoutCircleFingerprint,
LayoutIconFingerprint,
LayoutVideoFingerprint,
)
) {
override fun execute(context: BytecodeContext): PatchResult {
fun MethodFingerprint.injectHideCall() {
val layoutResult = result!!
val layoutMethod = layoutResult.mutableMethod
val checkCastIndex = layoutResult.scanResult.patternScanResult!!.endIndex
val viewRegister = (layoutMethod.instruction(checkCastIndex) as Instruction21c).registerA
layoutMethod.addInstruction(
checkCastIndex + 1,
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideEndscreenCardsPatch;->hideEndscreen(Landroid/view/View;)V"
)
}
listOf(LayoutCircleFingerprint, LayoutIconFingerprint, LayoutVideoFingerprint).forEach(MethodFingerprint::injectHideCall)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,48 @@
package app.revanced.patches.youtube.layout.hideendscreencards.resource.patch
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@Name("hide-endscreen-cards-resource-patch")
@HideEndscreenCardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
@Version("0.0.1")
class HideEndscreenCardsResourcePatch : ResourcePatch {
internal companion object {
var layoutCircle: Long = -1
var layoutIcon: Long = -1
var layoutVideo: Long = -1
}
override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_endscreen_cards",
StringResource("revanced_hide_endscreen_cards_title", "Hide end-screen cards"),
true,
StringResource("revanced_hide_endscreen_cards_summary_on", "End-screen cards are hidden"),
StringResource("revanced_hide_endscreen_cards_summary_off", "End-screen cards are shown")
),
)
fun findEndscreenResourceId(name: String) = ResourceMappingResourcePatch.resourceMappings.single {
it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id
layoutCircle = findEndscreenResourceId("circle")
layoutIcon = findEndscreenResourceId("icon")
layoutVideo = findEndscreenResourceId("video")
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.hideinfocards.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HideInfocardsCompatibility

View File

@@ -0,0 +1,17 @@
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("infocards-incognito-fingerprint")
@HideInfocardsCompatibility
@Version("0.0.1")
object InfocardsIncognitoFingerprint : MethodFingerprint(
"Ljava/lang/Boolean;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
strings = listOf("vibrator")
)

View File

@@ -0,0 +1,17 @@
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
import org.jf.dexlib2.AccessFlags
@Name("infocards-incognito-parent-fingerprint")
@HideInfocardsCompatibility
@Version("0.0.1")
object InfocardsIncognitoParentFingerprint : MethodFingerprint(
"Ljava/lang/String;",
AccessFlags.PUBLIC or AccessFlags.FINAL,
strings = listOf("player_overlay_info_card_teaser"),
)

View File

@@ -0,0 +1,25 @@
package app.revanced.patches.youtube.layout.hideinfocards.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
import app.revanced.patches.youtube.layout.hideinfocards.resource.patch.HideInfocardsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("infocards-method-call-fingerprint")
@HideInfocardsCompatibility
@Version("0.0.1")
object InfocardsMethodCallFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
(instruction as? WideLiteralInstruction)?.wideLiteral == HideInfocardsResourcePatch.drawerResourceId
} == true
}
)

View File

@@ -0,0 +1,71 @@
package app.revanced.patches.youtube.layout.hideinfocards.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsIncognitoFingerprint
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsMethodCallFingerprint
import app.revanced.patches.youtube.layout.hideinfocards.fingerprints.InfocardsIncognitoParentFingerprint
import app.revanced.patches.youtube.layout.hideinfocards.resource.patch.HideInfocardsResourcePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
@Patch
@DependsOn([IntegrationsPatch::class, HideInfocardsResourcePatch::class])
@Name("hide-info-cards")
@Description("Hides info-cards in videos.")
@HideInfocardsCompatibility
@Version("0.0.1")
class HideInfocardsPatch : BytecodePatch(
listOf(
InfocardsIncognitoParentFingerprint,
InfocardsMethodCallFingerprint,
)
) {
override fun execute(context: BytecodeContext): PatchResult {
with(InfocardsIncognitoFingerprint.also {
it.resolve(context, InfocardsIncognitoParentFingerprint.result!!.classDef)
}.result!!.mutableMethod) {
val invokeInstructionIndex = implementation!!.instructions.indexOfFirst {
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal &&
((it as? BuilderInstruction35c)?.reference.toString() ==
"Landroid/view/View;->setVisibility(I)V")
}
replaceInstruction(invokeInstructionIndex, """
invoke-static {v${(instruction(invokeInstructionIndex) as? BuilderInstruction35c)?.registerC}}, Lapp/revanced/integrations/patches/HideInfocardsPatch;->hideInfocardsIncognito(Landroid/view/View;)V
"""
)
}
with(InfocardsMethodCallFingerprint.result!!) {
val hideInfocardsCallMethod = mutableMethod
val invokeInterfaceIndex = scanResult.patternScanResult!!.endIndex
val toggleRegister = hideInfocardsCallMethod.implementation!!.registerCount - 1
hideInfocardsCallMethod.addInstructions(
invokeInterfaceIndex, """
invoke-static {}, Lapp/revanced/integrations/patches/HideInfocardsPatch;->hideInfocardsMethodCall()Z
move-result v$toggleRegister
if-nez v$toggleRegister, :hide_info_cards
""", listOf(ExternalLabel("hide_info_cards", hideInfocardsCallMethod.instruction(invokeInterfaceIndex + 1)))
)
}
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,40 @@
package app.revanced.patches.youtube.layout.hideinfocards.resource.patch
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.hideinfocards.annotations.HideInfocardsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
@HideInfocardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
@Version("0.0.1")
class HideInfocardsResourcePatch : ResourcePatch {
internal companion object {
var drawerResourceId: Long = -1
}
override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_infocards",
StringResource("revanced_hide_infocards_title", "Hide info-cards"),
true,
StringResource("revanced_hide_infocards_summary_on", "Info-cards are hidden"),
StringResource("revanced_hide_infocards_summary_off", "Info-cards are shown")
)
)
drawerResourceId = ResourceMappingResourcePatch.resourceMappings.single {
it.type == "id" && it.name == "info_cards_drawer_header"
}.id
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.misc.openlinksdirectly.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.34.36", "17.36.39", "17.38.36", "17.39.35" , "17.40.41", "17.42.35", "17.43.36")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class OpenLinksDirectlyCompatibility

View File

@@ -0,0 +1,23 @@
package app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.openlinksdirectly.annotations.OpenLinksDirectlyCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("open-links-directly-primary-fingerprint")
@OpenLinksDirectlyCompatibility
@Version("0.0.1")
object OpenLinksDirectlyFingerprintPrimary : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
Opcode.CHECK_CAST,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST,
Opcode.SGET
)
)

View File

@@ -0,0 +1,28 @@
package app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.openlinksdirectly.annotations.OpenLinksDirectlyCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("open-links-directly-secondary-fingerprint")
@OpenLinksDirectlyCompatibility
@Version("0.0.1")
object OpenLinksDirectlyFingerprintSecondary : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.RETURN_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.CONST_STRING
),
strings = listOf("Uri must have an absolute scheme")
)

View File

@@ -0,0 +1,72 @@
package app.revanced.patches.youtube.misc.openlinksdirectly.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.openlinksdirectly.annotations.OpenLinksDirectlyCompatibility
import app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints.OpenLinksDirectlyFingerprintPrimary
import app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints.OpenLinksDirectlyFingerprintSecondary
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.formats.Instruction11x
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("open-links-directly")
@Description("Bypasses redirect links and allows opening links directly.")
@OpenLinksDirectlyCompatibility
@Version("0.0.1")
class OpenLinksDirectlyPatch : BytecodePatch(
listOf(
OpenLinksDirectlyFingerprintPrimary, OpenLinksDirectlyFingerprintSecondary
)
) {
override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_uri_redirect",
StringResource("revanced_uri_redirect_title", "Open links directly"),
true,
StringResource("revanced_uri_redirect_summary_on", "Enabled"),
StringResource("revanced_uri_redirect_summary_off", "Disabled")
)
)
OpenLinksDirectlyFingerprintPrimary.hookUriParser(true)
OpenLinksDirectlyFingerprintSecondary.hookUriParser(false)
return PatchResultSuccess()
}
}
fun MethodFingerprint.hookUriParser(isPrimaryFingerprint: Boolean) {
fun getTargetRegister(instruction: Instruction): Int {
if (isPrimaryFingerprint) return (instruction as Instruction35c).registerC
return (instruction as Instruction11x).registerA
}
with(this.result!!) {
val startIndex = scanResult.patternScanResult!!.startIndex
val instruction = method.implementation!!.instructions.elementAt(startIndex + 1)
val insertIndex = if (isPrimaryFingerprint) 1 else 2
val targetRegister = getTargetRegister(instruction)
mutableMethod.addInstructions(
startIndex + insertIndex, """
invoke-static {v$targetRegister}, Lapp/revanced/integrations/patches/OpenLinksDirectlyPatch;->parseRedirectUri(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister
"""
)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 B

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB