Compare commits

..

18 Commits

Author SHA1 Message Date
semantic-release-bot
920bfea952 chore(release): 2.178.0-dev.4 [skip ci]
# [2.178.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.178.0-dev.3...v2.178.0-dev.4) (2023-06-18)

### Features

* **boostforreddit:** add `change-oauth-client-id` patch ([1c95e0f](1c95e0fcad))
2023-06-18 00:21:44 +00:00
oSumAtrIX
1c95e0fcad feat(boostforreddit): add change-oauth-client-id patch 2023-06-18 02:19:08 +02:00
semantic-release-bot
7f1b70e625 chore(release): 2.178.0-dev.3 [skip ci]
# [2.178.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.178.0-dev.2...v2.178.0-dev.3) (2023-06-17)

### Bug Fixes

* **youtube/comments:** add missing filter ([#2423](https://github.com/revanced/revanced-patches/issues/2423)) ([d30797f](d30797f9b8))
2023-06-17 23:50:15 +00:00
johnconner122
d30797f9b8 fix(youtube/comments): add missing filter (#2423) 2023-06-18 01:47:31 +02:00
semantic-release-bot
d5609f65ca chore(release): 2.178.0-dev.2 [skip ci]
# [2.178.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.178.0-dev.1...v2.178.0-dev.2) (2023-06-16)

### Bug Fixes

* **googlerecorder/remove-device-restrictions:** add missing app constraint ([#2438](https://github.com/revanced/revanced-patches/issues/2438)) ([7d85d2a](7d85d2ad91))
2023-06-16 19:31:02 +00:00
LisoUseInAIKyrios
88e6ab2d07 chore: fixing build 2023-06-16 23:28:22 +04:00
johnconner122
7d85d2ad91 fix(googlerecorder/remove-device-restrictions): add missing app constraint (#2438) 2023-06-16 13:09:40 +02:00
semantic-release-bot
21adab5ef3 chore(release): 2.178.0-dev.1 [skip ci]
# [2.178.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.177.1-dev.2...v2.178.0-dev.1) (2023-06-16)

### Features

* **google-recorder:** add `remove-device-restrictions` patch ([2e7e231](2e7e231e7d))
2023-06-16 02:09:45 +00:00
oSumAtrIX
2e7e231e7d feat(google-recorder): add remove-device-restrictions patch 2023-06-16 04:06:53 +02:00
semantic-release-bot
ae67a762ff chore(release): 2.177.1-dev.2 [skip ci]
## [2.177.1-dev.2](https://github.com/revanced/revanced-patches/compare/v2.177.1-dev.1...v2.177.1-dev.2) (2023-06-14)

### Bug Fixes

* **youtube:** separate `hide-ads` to `hide-layout-components` patch ([6611882](66118829b3))
2023-06-14 01:33:36 +00:00
oSumAtrIX
66118829b3 fix(youtube): separate hide-ads to hide-layout-components patch 2023-06-14 03:30:29 +02:00
semantic-release-bot
22a18467de chore(release): 2.177.1-dev.1 [skip ci]
## [2.177.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.177.0...v2.177.1-dev.1) (2023-06-14)

### Bug Fixes

* don't include all Litho patches, when not included ([ccc369a](ccc369a2a8))
2023-06-14 00:49:42 +00:00
oSumAtrIX
ccc369a2a8 fix: don't include all Litho patches, when not included 2023-06-14 02:45:29 +02:00
semantic-release-bot
c3d898ae0d chore(release): 2.177.0 [skip ci]
# [2.177.0](https://github.com/revanced/revanced-patches/compare/v2.176.1...v2.177.0) (2023-06-12)

### Bug Fixes

* **reddit/hide-ads:** search for correct reference class descriptor ([fa49810](fa49810907))
* **syncforreddit/change-oauth-client-id:** trim whitespace from OAuth string ([#2402](https://github.com/revanced/revanced-patches/issues/2402)) ([228e8b7](228e8b7d48))
* **syncforreddit/change-oauth-client-id:** use downloads directory ([28abefe](28abefeab0))

### Features

* **syncforreddit/change-oauth-client-id:** support pro version ([7b01617](7b01617cd4))
2023-06-12 22:59:54 +00:00
oSumAtrIX
96add7b8fa chore: merge branch dev to main (#2400) 2023-06-13 00:56:40 +02:00
semantic-release-bot
2ee28e0081 chore(release): 2.177.0-dev.2 [skip ci]
# [2.177.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.177.0-dev.1...v2.177.0-dev.2) (2023-06-12)

### Bug Fixes

* **reddit/hide-ads:** search for correct reference class descriptor ([fa49810](fa49810907))
2023-06-12 22:53:44 +00:00
oSumAtrIX
fa49810907 fix(reddit/hide-ads): search for correct reference class descriptor 2023-06-13 00:51:04 +02:00
oSumAtrIX
2814328bfd chore(syncforreddit/change-oauth-client-id): revert using downloads directory 2023-06-12 23:21:40 +02:00
30 changed files with 742 additions and 467 deletions

View File

@@ -1,3 +1,66 @@
# [2.178.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.178.0-dev.3...v2.178.0-dev.4) (2023-06-18)
### Features
* **boostforreddit:** add `change-oauth-client-id` patch ([3dbc4bd](https://github.com/revanced/revanced-patches/commit/3dbc4bd49df1656893ef69c68550a2deb6a92cb7))
# [2.178.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.178.0-dev.2...v2.178.0-dev.3) (2023-06-17)
### Bug Fixes
* **youtube/comments:** add missing filter ([#2423](https://github.com/revanced/revanced-patches/issues/2423)) ([cab04b3](https://github.com/revanced/revanced-patches/commit/cab04b3a56cfc5bf00b7c6fcf6f86ab75aa5d4fd))
# [2.178.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.178.0-dev.1...v2.178.0-dev.2) (2023-06-16)
### Bug Fixes
* **googlerecorder/remove-device-restrictions:** add missing app constraint ([#2438](https://github.com/revanced/revanced-patches/issues/2438)) ([d5efe26](https://github.com/revanced/revanced-patches/commit/d5efe26f8959cde75dd3865ec3c2df4b05210e4a))
# [2.178.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.177.1-dev.2...v2.178.0-dev.1) (2023-06-16)
### Features
* **google-recorder:** add `remove-device-restrictions` patch ([ef96ed1](https://github.com/revanced/revanced-patches/commit/ef96ed124e12091dde34124eabd8be9f2bb9280c))
## [2.177.1-dev.2](https://github.com/revanced/revanced-patches/compare/v2.177.1-dev.1...v2.177.1-dev.2) (2023-06-14)
### Bug Fixes
* **youtube:** separate `hide-ads` to `hide-layout-components` patch ([7e0417f](https://github.com/revanced/revanced-patches/commit/7e0417f6728fa7b79a9d8cbcfd3ccba484a5567d))
## [2.177.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.177.0...v2.177.1-dev.1) (2023-06-14)
### Bug Fixes
* don't include all Litho patches, when not included ([fc69491](https://github.com/revanced/revanced-patches/commit/fc69491dfe4b119d46dd3da27b556e55fe0cecfb))
# [2.177.0](https://github.com/revanced/revanced-patches/compare/v2.176.1...v2.177.0) (2023-06-12)
### Bug Fixes
* **reddit/hide-ads:** search for correct reference class descriptor ([ad2a858](https://github.com/revanced/revanced-patches/commit/ad2a8585b2a5ecbc5eb92dd23b0ab124aa8a2541))
* **syncforreddit/change-oauth-client-id:** trim whitespace from OAuth string ([#2402](https://github.com/revanced/revanced-patches/issues/2402)) ([2afea71](https://github.com/revanced/revanced-patches/commit/2afea71557cfe4eb64d7c7ebf5a07dfd24a11824))
* **syncforreddit/change-oauth-client-id:** use downloads directory ([9b5af77](https://github.com/revanced/revanced-patches/commit/9b5af77a229a22466cfe8ed41a21d081beeae960))
### Features
* **syncforreddit/change-oauth-client-id:** support pro version ([d34288b](https://github.com/revanced/revanced-patches/commit/d34288b6e8c7f5bb944622a3c741fcc693868033))
# [2.177.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.177.0-dev.1...v2.177.0-dev.2) (2023-06-12)
### Bug Fixes
* **reddit/hide-ads:** search for correct reference class descriptor ([ad2a858](https://github.com/revanced/revanced-patches/commit/ad2a8585b2a5ecbc5eb92dd23b0ab124aa8a2541))
# [2.177.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.176.2-dev.2...v2.177.0-dev.1) (2023-06-12)

View File

@@ -25,7 +25,6 @@ The official ReVanced Patches.
| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 18.19.35 |
| `hide-ads` | Removes general ads. | 18.19.35 |
| `hide-album-cards` | Hides the album cards below the artist description. | 18.19.35 |
| `hide-artist-card` | Hides the artist card below the searchbar. | 18.19.35 |
| `hide-autoplay-button` | Hides the autoplay button in the video player. | 18.19.35 |
| `hide-breaking-news-shelf` | Hides the breaking news shelf on the homepage tab. | 18.19.35 |
| `hide-captions-button` | Hides the captions button on video player. | 18.19.35 |
@@ -36,6 +35,7 @@ The official ReVanced Patches.
| `hide-filter-bar` | Hides the filter bar in video feeds. | 18.19.35 |
| `hide-floating-microphone-button` | Hides the floating microphone button which appears in search. | 18.19.35 |
| `hide-info-cards` | Hides info cards in videos. | 18.19.35 |
| `hide-layout-components` | Hides general layout components. | 18.19.35 |
| `hide-load-more-button` | Hides the button under videos that loads similar videos. | 18.19.35 |
| `hide-player-buttons` | Adds the option to hide video player previous and next buttons. | 18.19.35 |
| `hide-player-overlay` | Hides the dark background overlay from the player when player controls are visible. | all |
@@ -205,6 +205,14 @@ The official ReVanced Patches.
| `spoof-signature` | Spoofs the signature of the app. | all |
</details>
### [📦 `com.rubenmayayo.reddit`](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID in Boost for Reddit. | all |
</details>
### [📦 `com.laurencedawson.reddit_sync.pro`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.pro)
<details>
@@ -293,6 +301,14 @@ The official ReVanced Patches.
| `remove-debugging-detection` | Removes the USB and wireless debugging checks. | all |
</details>
### [📦 `com.google.android.apps.recorder`](https://play.google.com/store/apps/details?id=com.google.android.apps.recorder)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `remove-device-restrictions` | Removes restrictions from using the app on any device. | all |
</details>
### [📦 `com.dci.dev.androidtwelvewidgets`](https://play.google.com/store/apps/details?id=com.dci.dev.androidtwelvewidgets)
<details>
@@ -325,6 +341,30 @@ The official ReVanced Patches.
| `unlock-prime` | Unlocks Nova Prime and all functions of the app. | all |
</details>
### [📦 `tv.trakt.trakt`](https://play.google.com/store/apps/details?id=tv.trakt.trakt)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | all |
</details>
### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | 4.6377 |
</details>
### [📦 `com.ithebk.expensemanager`](https://play.google.com/store/apps/details?id=com.ithebk.expensemanager)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | all |
</details>
### [📦 `com.vsco.cam`](https://play.google.com/store/apps/details?id=com.vsco.cam)
<details>
@@ -341,22 +381,6 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks all pro features. | all |
</details>
### [📦 `com.candylink.openvpn`](https://play.google.com/store/apps/details?id=com.candylink.openvpn)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks premium features. | all |
</details>
### [📦 `com.ithebk.expensemanager`](https://play.google.com/store/apps/details?id=com.ithebk.expensemanager)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | all |
</details>
### [📦 `ginlemon.iconpackstudio`](https://play.google.com/store/apps/details?id=ginlemon.iconpackstudio)
<details>
@@ -365,22 +389,6 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks all pro features. | all |
</details>
### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | 4.6377 |
</details>
### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks all pro features. | all |
</details>
### [📦 `org.totschnig.myexpenses`](https://play.google.com/store/apps/details?id=org.totschnig.myexpenses)
<details>
@@ -389,14 +397,6 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks all professional features. | 3.4.9 |
</details>
### [📦 `tv.trakt.trakt`](https://play.google.com/store/apps/details?id=tv.trakt.trakt)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | all |
</details>
### [📦 `com.wakdev.apps.nfctools.se`](https://play.google.com/store/apps/details?id=com.wakdev.apps.nfctools.se)
<details>
@@ -405,6 +405,22 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks all pro features. | all |
</details>
### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks all pro features. | all |
</details>
### [📦 `com.candylink.openvpn`](https://play.google.com/store/apps/details?id=com.candylink.openvpn)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks premium features. | all |
</details>
### [📦 `com.ticktick.task`](https://play.google.com/store/apps/details?id=com.ticktick.task)
<details>

View File

@@ -3,9 +3,7 @@ package android.os;
import java.io.File;
public final class Environment {
public static String DIRECTORY_DOWNLOADS = "Download";
public static File getExternalStoragePublicDirectory(final String type) {
public static File getExternalStorageDirectory() {
throw new UnsupportedOperationException("Stub");
}
}

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official
version = 2.177.0-dev.1
version = 2.178.0-dev.4

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
package app.revanced.patches.googlerecorder.restrictions.fingereprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object OnApplicationCreateFingerprint : MethodFingerprint(
strings = listOf("com.google.android.feature.PIXEL_2017_EXPERIENCE"),
customFingerprint = custom@{ methodDef, classDef ->
if (methodDef.name != "onCreate") return@custom false
classDef.type.endsWith("RecorderApplication;")
}
)

View File

@@ -0,0 +1,45 @@
package app.revanced.patches.googlerecorder.restrictions.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.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.googlerecorder.restrictions.fingereprints.OnApplicationCreateFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@Name("remove-device-restrictions")
@Description("Removes restrictions from using the app on any device.")
@Compatibility([Package("com.google.android.apps.recorder")])
@Version("0.0.1")
class RemoveDeviceRestrictions : BytecodePatch(
listOf(OnApplicationCreateFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
OnApplicationCreateFingerprint.result?.let {
val featureStringIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply {
// Remove check for device restrictions.
removeInstructions(featureStringIndex - 2, 5)
val featureAvailableRegister = getInstruction<OneRegisterInstruction>(featureStringIndex).registerA
// Override "isPixelDevice()" to return true.
addInstruction(featureStringIndex, "const/4 v$featureAvailableRegister, 0x1")
}
} ?: return OnApplicationCreateFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -73,7 +73,7 @@ class HideAdsPatch : BytecodePatch(
val reference = (it as ReferenceInstruction).reference as MethodReference
reference.name == "add" && reference.definingClass == "Lava/util/ArrayList;"
reference.name == "add" && reference.definingClass == "Ljava/util/ArrayList;"
}
result.mutableMethod.removeInstruction(index)

View File

@@ -0,0 +1,57 @@
package app.revanced.patches.reddit.customclients
import android.os.Environment
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.patch.*
import app.revanced.patches.reddit.customclients.boostforreddit.api.patch.ChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.syncforreddit.api.patch.ChangeOAuthClientIdPatch.Companion.clientId
import java.io.File
abstract class AbstractChangeOAuthClientIdPatch(
private val redirectUri: String,
private val fingerprint: MethodFingerprint,
) : BytecodePatch(listOf(fingerprint)) {
override fun execute(context: BytecodeContext): PatchResult {
if (ChangeOAuthClientIdPatch.clientId == null) {
// Test if on Android
try {
Class.forName("android.os.Environment")
} catch (e: ClassNotFoundException) {
return PatchResultError("No client ID provided")
}
File(Environment.getExternalStorageDirectory(), "reddit_client_id_revanced.txt").also {
if (it.exists()) return@also
val error = """
In order to use this patch, you need to provide a client ID.
You can do this by creating a file at ${it.absolutePath} with the client ID as its content.
Alternatively, you can provide the client ID using patch options.
You can get your client ID from https://www.reddit.com/prefs/apps.
The application type has to be "installed app" and the redirect URI has to be set to "$redirectUri"
""".trimIndent()
return PatchResultError(error)
}.let { clientId = it.readText().trim() }
}
return fingerprint.patch(context)
}
abstract fun MethodFingerprint.patch(context: BytecodeContext): PatchResult
companion object Options {
open class ChangeOAuthClientIdOptionsContainer : OptionsContainer() {
var clientId by option(
PatchOption.StringOption(
"client-id",
null,
"OAuth client ID",
"The Reddit OAuth client ID."
)
)
}
}
}

View File

@@ -0,0 +1,11 @@
package app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object GetClientIdFingerprint : MethodFingerprint(
customFingerprint = custom@{ methodDef, classDef ->
if (!classDef.type.endsWith("Credentials;")) return@custom false
methodDef.name == "getClientId"
}
)

View File

@@ -0,0 +1,36 @@
package app.revanced.patches.reddit.customclients.boostforreddit.api.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.*
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.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.Patch
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint
@Patch
@Name("change-oauth-client-id")
@Description("Changes the OAuth client ID in Boost for Reddit.")
@Compatibility([Package("com.rubenmayayo.reddit")])
@Version("0.0.1")
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"http://rubenmayayo.com",
GetClientIdFingerprint
) {
override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult {
result?.mutableMethod?.addInstructions(
0,
"""
const-string v0, "$clientId"
return-object v0
"""
) ?: return toErrorResult()
return PatchResultSuccess()
}
companion object : Options.ChangeOAuthClientIdOptionsContainer()
}

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.syncforreddit.ads.fingerprints
package app.revanced.patches.reddit.customclients.syncforreddit.ads.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.syncforreddit.ads.patch
package app.revanced.patches.reddit.customclients.syncforreddit.ads.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.*
@@ -9,8 +9,8 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.syncforreddit.ads.fingerprints.IsAdsEnabledFingerprint
import app.revanced.patches.syncforreddit.detection.piracy.patch.DisablePiracyDetectionPatch
import app.revanced.patches.reddit.customclients.syncforreddit.ads.fingerprints.IsAdsEnabledFingerprint
import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.patch.DisablePiracyDetectionPatch
@Patch
@Name("disable-ads")

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.syncforreddit.api.fingerprints
package app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.syncforreddit.api.fingerprints
package app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint

View File

@@ -0,0 +1,68 @@
package app.revanced.patches.reddit.customclients.syncforreddit.api.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.*
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetBearerTokenFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.StringReference
import java.util.*
@Patch
@Name("change-oauth-client-id")
@Description("Changes the OAuth client ID.")
@Compatibility([Package("com.laurencedawson.reddit_sync"), Package("com.laurencedawson.reddit_sync.pro")])
@Version("0.0.1")
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"http://redditsync/auth",
GetAuthorizationStringFingerprint,
) {
override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult {
result?.also { result ->
GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
addInstructions(
0,
"""
const-string v0, "Basic $auth"
return-object v0
"""
)
} ?: return GetBearerTokenFingerprint.toErrorResult()
}?.let {
val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply {
val authorizationStringInstruction = getInstruction<ReferenceInstruction>(occurrenceIndex)
val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
val reference = authorizationStringInstruction.reference as StringReference
val newAuthorizationUrl = reference.string.replace(
"client_id=.*?&".toRegex(),
"client_id=${clientId!!}&"
)
replaceInstruction(
occurrenceIndex,
"const-string v$targetRegister, \"$newAuthorizationUrl\""
)
}
} ?: return toErrorResult()
return PatchResultSuccess()
}
companion object : Options.ChangeOAuthClientIdOptionsContainer()
}

View File

@@ -1,4 +1,4 @@
package app.revanced.patches.syncforreddit.detection.piracy.patch
package app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description

View File

@@ -1,104 +0,0 @@
package app.revanced.patches.syncforreddit.api.patch
import android.os.Environment
import app.revanced.patcher.annotation.*
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint
import app.revanced.patches.syncforreddit.api.fingerprints.GetBearerTokenFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.StringReference
import java.io.File
import java.util.*
@Patch
@Name("change-oauth-client-id")
@Description("Changes the OAuth client ID.")
@Compatibility(
[
Package("com.laurencedawson.reddit_sync"),
Package("com.laurencedawson.reddit_sync.pro")
]
)
@Version("0.0.1")
class ChangeOAuthClientIdPatch : BytecodePatch(
listOf(GetAuthorizationStringFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
if (clientId == null) {
// Test if on Android
try {
Class.forName("android.os.Environment")
} catch (e: ClassNotFoundException) {
return PatchResultError("No client ID provided")
}
File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
"reddit_client_id_revanced.txt"
).also {
if (it.exists()) return@also
val error = """
In order to use this patch, you need to provide a client ID.
You can do this by creating a file at ${it.absolutePath} with the client ID as its content.
Alternatively, you can provide the client ID using patch options.
You can get your client ID from https://www.reddit.com/prefs/apps.
The application type has to be "installed app" and the redirect URI has to be set to "http://redditsync/auth"
""".trimIndent()
return PatchResultError(error)
}.let { clientId = it.readText().trim() }
}
GetAuthorizationStringFingerprint.result?.also { result ->
GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
addInstructions(
0,
"""
const-string v0, "Basic $auth"
return-object v0
"""
)
} ?: return PatchResultError("Could not find required method to patch.")
}?.let {
val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply {
val authorizationStringInstruction = getInstruction<ReferenceInstruction>(occurrenceIndex)
val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
val reference = authorizationStringInstruction.reference as StringReference
val newAuthorizationUrl = reference.string.replace(
"client_id=.*?&".toRegex(),
"client_id=${clientId!!}&"
)
replaceInstruction(
occurrenceIndex,
"const-string v$targetRegister, \"$newAuthorizationUrl\""
)
}
} ?: return PatchResultError("Could not find required method to patch.")
return PatchResultSuccess()
}
companion object : OptionsContainer() {
var clientId by option(
PatchOption.StringOption(
"client-id",
null,
"OAuth client ID",
"The client ID to use for OAuth."
)
)
}
}

View File

@@ -7,14 +7,15 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.*
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.ad.general.annotation.HideAdsCompatibility
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen
@DependsOn(
dependencies = [
[
LithoFilterPatch::class,
SettingsPatch::class,
ResourceMappingPatch::class
@@ -23,185 +24,7 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.P
@HideAdsCompatibility
@Version("0.0.1")
class HideAdsResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_gray_separator",
StringResource("revanced_hide_gray_separator_title", "Hide gray separator"),
StringResource("revanced_hide_gray_separator_summary_on", "Gray separators are hidden"),
StringResource("revanced_hide_gray_separator_summary_off", "Gray separators are shown")
),
SwitchPreference(
"revanced_hide_channel_guidelines",
StringResource("revanced_hide_channel_guidelines_title", "Hide channel guidelines"),
StringResource(
"revanced_hide_channel_guidelines_summary_on",
"Channel guidelines are hidden"
),
StringResource(
"revanced_hide_channel_guidelines_summary_off",
"Channel guidelines are shown"
)
),
SwitchPreference(
"revanced_hide_chapter_teaser",
StringResource(
"revanced_hide_chapter_teaser_title",
"Hide chapter teaser under videos"
),
StringResource(
"revanced_hide_chapter_teaser_summary_on",
"Chapter teasers are hidden"
),
StringResource(
"revanced_hide_chapter_teaser_summary_off",
"Chapter teasers are shown"
)
),
SwitchPreference(
"revanced_hide_merchandise_banners",
StringResource("revanced_hide_merchandise_banners_title", "Hide merchandise banners"),
StringResource("revanced_hide_merchandise_banners_summary_on", "Merchandise banners are hidden"),
StringResource("revanced_hide_merchandise_banners_summary_off", "Merchandise banners are shown")
),
SwitchPreference(
"revanced_hide_community_posts",
StringResource("revanced_hide_community_posts_title", "Hide community posts"),
StringResource("revanced_hide_community_posts_summary_on", "Community posts are hidden"),
StringResource("revanced_hide_community_posts_summary_off", "Community posts are shown")
),
SwitchPreference(
"revanced_hide_compact_banner",
StringResource("revanced_hide_compact_banner_title", "Hide compact banners"),
StringResource("revanced_hide_compact_banner_summary_on", "Compact banners are hidden"),
StringResource("revanced_hide_compact_banner_summary_off", "Compact banners are shown")
),
SwitchPreference(
"revanced_hide_products_banner",
StringResource("revanced_hide_products_banner_title", "Hide banner to view products"),
StringResource("revanced_hide_products_banner_summary_on", "Banner is hidden"),
StringResource("revanced_hide_products_banner_summary_off", "Banner is shown")
),
SwitchPreference(
"revanced_hide_web_search_results",
StringResource("revanced_hide_web_search_results_title", "Hide web search results"),
StringResource("revanced_hide_web_search_results_summary_on", "Web search results are hidden"),
StringResource("revanced_hide_web_search_results_summary_off", "Web search results are shown")
),
SwitchPreference(
"revanced_hide_movies_section",
StringResource("revanced_hide_movies_section_title", "Hide movies section"),
StringResource("revanced_hide_movies_section_summary_on", "Movies section is hidden"),
StringResource("revanced_hide_movies_section_summary_off", "Movies section is shown")
),
SwitchPreference(
"revanced_hide_feed_survey",
StringResource("revanced_hide_feed_survey_title", "Hide feed surveys"),
StringResource("revanced_hide_feed_survey_summary_on", "Feed surveys are hidden"),
StringResource("revanced_hide_feed_survey_summary_off", "Feed surveys are shown")
),
SwitchPreference(
"revanced_hide_community_guidelines",
StringResource("revanced_hide_community_guidelines_title", "Hide community guidelines"),
StringResource(
"revanced_hide_community_guidelines_summary_on",
"Community guidelines are hidden"
),
StringResource(
"revanced_hide_community_guidelines_summary_off",
"Community guidelines are shown"
)
),
SwitchPreference(
"revanced_hide_subscribers_community_guidelines",
StringResource(
"revanced_hide_subscribers_community_guidelines_title",
"Hide subscribers community guidelines"
),
StringResource(
"revanced_hide_subscribers_community_guidelines_summary_on",
"Subscribers community guidelines are hidden"
),
StringResource(
"revanced_hide_subscribers_community_guidelines_summary_off",
"Subscribers community guidelines are shown"
)
),
SwitchPreference(
"revanced_hide_channel_member_shelf",
StringResource("revanced_hide_channel_member_shelf_title", "Hide channel member shelf"),
StringResource(
"revanced_hide_channel_member_shelf_summary_on",
"Channel member shelf is hidden"
),
StringResource(
"revanced_hide_channel_member_shelf_summary_off",
"Channel member shelf is shown"
)
),
SwitchPreference(
"revanced_hide_emergency_box",
StringResource("revanced_hide_emergency_box_title", "Hide emergency boxes"),
StringResource("revanced_hide_emergency_box_summary_on", "Emergency boxes are hidden"),
StringResource("revanced_hide_emergency_box_summary_off", "Emergency boxes are shown")
),
SwitchPreference(
"revanced_hide_info_panels",
StringResource("revanced_hide_info_panels_title", "Hide info panels"),
StringResource("revanced_hide_info_panels_summary_on", "Info panels are hidden"),
StringResource("revanced_hide_info_panels_summary_off", "Info panels are shown")
),
SwitchPreference(
"revanced_hide_medical_panels",
StringResource("revanced_hide_medical_panels_title", "Hide medical panels"),
StringResource("revanced_hide_medical_panels_summary_on", "Medical panels are hidden"),
StringResource("revanced_hide_medical_panels_summary_off", "Medical panels are shown")
),
SwitchPreference(
"revanced_hide_channel_bar",
StringResource("revanced_hide_channel_bar_title", "Hide channel bar"),
StringResource("revanced_hide_channel_bar_summary_on", "Channel bar is hidden"),
StringResource("revanced_hide_channel_bar_summary_off", "Channel bar is shown")
),
SwitchPreference(
"revanced_hide_quick_actions",
StringResource("revanced_hide_quick_actions_title", "Hide quick actions in fullscreen"),
StringResource("revanced_hide_quick_actions_summary_on", "Quick actions are hidden"),
StringResource("revanced_hide_quick_actions_summary_off", "Quick actions are shown")
),
SwitchPreference(
"revanced_hide_related_videos",
StringResource("revanced_hide_related_videos_title", "Hide related videos in quick actions"),
StringResource("revanced_hide_related_videos_summary_on", "Related videos are hidden"),
StringResource("revanced_hide_related_videos_summary_off", "Related videos are shown")
),
SwitchPreference(
"revanced_hide_image_shelf",
StringResource("revanced_hide_image_shelf", "Hide image shelf in search results"),
StringResource("revanced_hide_image_shelf_summary_on", "Image shelf is hidden"),
StringResource("revanced_hide_image_shelf_summary_off", "Image shelf is shown")
),
SwitchPreference(
"revanced_hide_audio_track_button",
StringResource("revanced_hide_audio_track_button_title", "Hide audio track button"),
StringResource("revanced_hide_audio_track_button_on", "Audio track button is hidden"),
StringResource("revanced_hide_audio_track_button_off", "Audio track button is shown")
),
SwitchPreference(
"revanced_hide_latest_posts_ads",
StringResource("revanced_hide_latest_posts_ads_title", "Hide latest posts"),
StringResource("revanced_hide_latest_posts_ads_summary_on", "Latest posts are hidden"),
StringResource("revanced_hide_latest_posts_ads_summary_off", "Latest posts are shown")
),
SwitchPreference(
"revanced_hide_mix_playlists",
StringResource("revanced_hide_mix_playlists_title", "Hide mix playlists"),
StringResource("revanced_hide_mix_playlists_summary_on", "Mix playlists are hidden"),
StringResource("revanced_hide_mix_playlists_summary_off", "Mix playlists are shown")
),
)
PreferenceScreen.ADS.addPreferences(
SwitchPreference(
"revanced_hide_general_ads",
@@ -227,38 +50,28 @@ class HideAdsResourcePatch : ResourcePatch {
StringResource("revanced_hide_self_sponsor_ads_summary_on", "Self sponsored cards are hidden"),
StringResource("revanced_hide_self_sponsor_ads_summary_off", "Self sponsored cards are shown")
),
PreferenceScreen(
"revanced_custom_filter_preference_screen",
StringResource("revanced_custom_filter_preference_screen_title", "Custom filter"),
listOf(
SwitchPreference(
"revanced_custom_filter",
StringResource(
"revanced_custom_filter_title",
"Enable custom filter"
),
StringResource(
"revanced_custom_filter_summary_on",
"Custom filter is enabled"
),
StringResource(
"revanced_custom_filter_summary_off",
"Custom filter is disabled"
)
),
// TODO: This should be a dynamic ListPreference, which does not exist yet
TextPreference(
"revanced_custom_filter_strings",
StringResource("revanced_custom_filter_strings_title", "Custom filter"),
StringResource(
"revanced_custom_filter_strings_summary",
"Filter components by their name separated by a comma"
)
)
)
SwitchPreference(
"revanced_hide_products_banner",
StringResource("revanced_hide_products_banner_title", "Hide banner to view products"),
StringResource("revanced_hide_products_banner_summary_on", "Banner is hidden"),
StringResource("revanced_hide_products_banner_summary_off", "Banner is shown")
),
SwitchPreference(
"revanced_hide_web_search_results",
StringResource("revanced_hide_web_search_results_title", "Hide web search results"),
StringResource("revanced_hide_web_search_results_summary_on", "Web search results are hidden"),
StringResource("revanced_hide_web_search_results_summary_off", "Web search results are shown")
),
SwitchPreference(
"revanced_hide_merchandise_banners",
StringResource("revanced_hide_merchandise_banners_title", "Hide merchandise banners"),
StringResource("revanced_hide_merchandise_banners_summary_on", "Merchandise banners are hidden"),
StringResource("revanced_hide_merchandise_banners_summary_off", "Merchandise banners are shown")
)
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id
return PatchResultSuccess()
@@ -266,5 +79,8 @@ class HideAdsResourcePatch : ResourcePatch {
internal companion object {
var adAttributionId: Long = -1
private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/components/AdsFilter;"
}
}

View File

@@ -66,6 +66,14 @@ class HideButtonsPatch : ResourcePatch {
StringResource("revanced_hide_buttons_preference_screen_summary", "Hide or show buttons under videos")
)
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
return PatchResultSuccess()
}
private companion object {
private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/components/ButtonsFilter;"
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.youtube.layout.hide.artistcards.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))])
@Target(AnnotationTarget.CLASS)
internal annotation class HideArtistCardCompatibility

View File

@@ -1,37 +0,0 @@
package app.revanced.patches.youtube.layout.hide.artistcards.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.artistcards.annotations.HideArtistCardCompatibility
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Patch
@DependsOn([ResourceMappingPatch::class, LithoFilterPatch::class])
@Name("hide-artist-card")
@Description("Hides the artist card below the searchbar.")
@HideArtistCardCompatibility
@Version("0.0.1")
class HideArtistCardsPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_artist_cards",
StringResource("revanced_hide_artist_cards_title", "Hide artist cards"),
StringResource("revanced_hide_artist_cards_on", "Artist cards is hidden"),
StringResource("revanced_hide_artist_cards_off", "Artist cards is shown")
),
)
return PatchResultSuccess()
}
}

View File

@@ -9,21 +9,23 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.hide.comments.annotations.HideCommentsCompatibility
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Patch
@Name("comments")
@Description("Hides components related to comments.")
@HideCommentsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@DependsOn([SettingsPatch::class, LithoFilterPatch::class])
@Version("0.0.1")
class CommentsPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
PreferenceScreen(
"revanced_comments_preference_screen",
@@ -48,4 +50,8 @@ class CommentsPatch : ResourcePatch {
return PatchResultSuccess()
}
}
private companion object {
const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/CommentsFilter;"
}
}

View File

@@ -1,9 +1,9 @@
package app.revanced.patches.youtube.misc.litho.filter.annotation
package app.revanced.patches.youtube.layout.hide.general.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35"))])
@Target(AnnotationTarget.CLASS)
internal annotation class LithoFilterCompatibility
internal annotation class HideLayoutComponentsCompatibility

View File

@@ -0,0 +1,232 @@
package app.revanced.patches.youtube.layout.hide.general.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.shared.settings.preference.impl.TextPreference
import app.revanced.patches.youtube.layout.hide.general.annotations.HideLayoutComponentsCompatibility
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen
@Patch
@Name("hide-layout-components")
@Description("Hides general layout components.")
@DependsOn([LithoFilterPatch::class, SettingsPatch::class])
@HideLayoutComponentsCompatibility
@Version("0.0.1")
class HideLayoutComponentsPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_gray_separator",
StringResource("revanced_hide_gray_separator_title", "Hide gray separator"),
StringResource("revanced_hide_gray_separator_summary_on", "Gray separators are hidden"),
StringResource("revanced_hide_gray_separator_summary_off", "Gray separators are shown")
),
SwitchPreference(
"revanced_hide_channel_guidelines",
StringResource("revanced_hide_channel_guidelines_title", "Hide channel guidelines"),
StringResource(
"revanced_hide_channel_guidelines_summary_on",
"Channel guidelines are hidden"
),
StringResource(
"revanced_hide_channel_guidelines_summary_off",
"Channel guidelines are shown"
)
),
SwitchPreference(
"revanced_hide_chapter_teaser",
StringResource(
"revanced_hide_chapter_teaser_title",
"Hide chapter teaser under videos"
),
StringResource(
"revanced_hide_chapter_teaser_summary_on",
"Chapter teasers are hidden"
),
StringResource(
"revanced_hide_chapter_teaser_summary_off",
"Chapter teasers are shown"
)
),
SwitchPreference(
"revanced_hide_community_posts",
StringResource("revanced_hide_community_posts_title", "Hide community posts"),
StringResource("revanced_hide_community_posts_summary_on", "Community posts are hidden"),
StringResource("revanced_hide_community_posts_summary_off", "Community posts are shown")
),
SwitchPreference(
"revanced_hide_compact_banner",
StringResource("revanced_hide_compact_banner_title", "Hide compact banners"),
StringResource("revanced_hide_compact_banner_summary_on", "Compact banners are hidden"),
StringResource("revanced_hide_compact_banner_summary_off", "Compact banners are shown")
),
SwitchPreference(
"revanced_hide_movies_section",
StringResource("revanced_hide_movies_section_title", "Hide movies section"),
StringResource("revanced_hide_movies_section_summary_on", "Movies section is hidden"),
StringResource("revanced_hide_movies_section_summary_off", "Movies section is shown")
),
SwitchPreference(
"revanced_hide_feed_survey",
StringResource("revanced_hide_feed_survey_title", "Hide feed surveys"),
StringResource("revanced_hide_feed_survey_summary_on", "Feed surveys are hidden"),
StringResource("revanced_hide_feed_survey_summary_off", "Feed surveys are shown")
),
SwitchPreference(
"revanced_hide_community_guidelines",
StringResource("revanced_hide_community_guidelines_title", "Hide community guidelines"),
StringResource(
"revanced_hide_community_guidelines_summary_on",
"Community guidelines are hidden"
),
StringResource(
"revanced_hide_community_guidelines_summary_off",
"Community guidelines are shown"
)
),
SwitchPreference(
"revanced_hide_subscribers_community_guidelines",
StringResource(
"revanced_hide_subscribers_community_guidelines_title",
"Hide subscribers community guidelines"
),
StringResource(
"revanced_hide_subscribers_community_guidelines_summary_on",
"Subscribers community guidelines are hidden"
),
StringResource(
"revanced_hide_subscribers_community_guidelines_summary_off",
"Subscribers community guidelines are shown"
)
),
SwitchPreference(
"revanced_hide_channel_member_shelf",
StringResource("revanced_hide_channel_member_shelf_title", "Hide channel member shelf"),
StringResource(
"revanced_hide_channel_member_shelf_summary_on",
"Channel member shelf is hidden"
),
StringResource(
"revanced_hide_channel_member_shelf_summary_off",
"Channel member shelf is shown"
)
),
SwitchPreference(
"revanced_hide_emergency_box",
StringResource("revanced_hide_emergency_box_title", "Hide emergency boxes"),
StringResource("revanced_hide_emergency_box_summary_on", "Emergency boxes are hidden"),
StringResource("revanced_hide_emergency_box_summary_off", "Emergency boxes are shown")
),
SwitchPreference(
"revanced_hide_info_panels",
StringResource("revanced_hide_info_panels_title", "Hide info panels"),
StringResource("revanced_hide_info_panels_summary_on", "Info panels are hidden"),
StringResource("revanced_hide_info_panels_summary_off", "Info panels are shown")
),
SwitchPreference(
"revanced_hide_medical_panels",
StringResource("revanced_hide_medical_panels_title", "Hide medical panels"),
StringResource("revanced_hide_medical_panels_summary_on", "Medical panels are hidden"),
StringResource("revanced_hide_medical_panels_summary_off", "Medical panels are shown")
),
SwitchPreference(
"revanced_hide_channel_bar",
StringResource("revanced_hide_channel_bar_title", "Hide channel bar"),
StringResource("revanced_hide_channel_bar_summary_on", "Channel bar is hidden"),
StringResource("revanced_hide_channel_bar_summary_off", "Channel bar is shown")
),
SwitchPreference(
"revanced_hide_quick_actions",
StringResource("revanced_hide_quick_actions_title", "Hide quick actions in fullscreen"),
StringResource("revanced_hide_quick_actions_summary_on", "Quick actions are hidden"),
StringResource("revanced_hide_quick_actions_summary_off", "Quick actions are shown")
),
SwitchPreference(
"revanced_hide_related_videos",
StringResource("revanced_hide_related_videos_title", "Hide related videos in quick actions"),
StringResource("revanced_hide_related_videos_summary_on", "Related videos are hidden"),
StringResource("revanced_hide_related_videos_summary_off", "Related videos are shown")
),
SwitchPreference(
"revanced_hide_image_shelf",
StringResource("revanced_hide_image_shelf", "Hide image shelf in search results"),
StringResource("revanced_hide_image_shelf_summary_on", "Image shelf is hidden"),
StringResource("revanced_hide_image_shelf_summary_off", "Image shelf is shown")
),
SwitchPreference(
"revanced_hide_audio_track_button",
StringResource("revanced_hide_audio_track_button_title", "Hide audio track button"),
StringResource("revanced_hide_audio_track_button_on", "Audio track button is hidden"),
StringResource("revanced_hide_audio_track_button_off", "Audio track button is shown")
),
SwitchPreference(
"revanced_hide_latest_posts_ads",
StringResource("revanced_hide_latest_posts_ads_title", "Hide latest posts"),
StringResource("revanced_hide_latest_posts_ads_summary_on", "Latest posts are hidden"),
StringResource("revanced_hide_latest_posts_ads_summary_off", "Latest posts are shown")
),
SwitchPreference(
"revanced_hide_mix_playlists",
StringResource("revanced_hide_mix_playlists_title", "Hide mix playlists"),
StringResource("revanced_hide_mix_playlists_summary_on", "Mix playlists are hidden"),
StringResource("revanced_hide_mix_playlists_summary_off", "Mix playlists are shown")
),
SwitchPreference(
"revanced_hide_artist_cards",
StringResource("revanced_hide_artist_cards_title", "Hide artist cards"),
StringResource("revanced_hide_artist_cards_on", "Artist cards is hidden"),
StringResource("revanced_hide_artist_cards_off", "Artist cards is shown")
),
app.revanced.patches.shared.settings.preference.impl.PreferenceScreen(
"revanced_custom_filter_preference_screen",
StringResource("revanced_custom_filter_preference_screen_title", "Custom filter"),
listOf(
SwitchPreference(
"revanced_custom_filter",
StringResource(
"revanced_custom_filter_title",
"Enable custom filter"
),
StringResource(
"revanced_custom_filter_summary_on",
"Custom filter is enabled"
),
StringResource(
"revanced_custom_filter_summary_off",
"Custom filter is disabled"
)
),
// TODO: This should be a dynamic ListPreference, which does not exist yet
TextPreference(
"revanced_custom_filter_strings",
StringResource("revanced_custom_filter_strings_title", "Custom filter"),
StringResource(
"revanced_custom_filter_strings_summary",
"Filter components by their name separated by a comma"
)
)
)
)
)
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
return PatchResultSuccess()
}
internal companion object {
private const val FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/patches/components/LayoutComponentsFilter;"
}
}

View File

@@ -49,6 +49,8 @@ class HideShortsComponentsPatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
// region Hide the Shorts shelf.
ReelConstructorFingerprint.result?.let {
@@ -59,7 +61,7 @@ class HideShortsComponentsPatch : BytecodePatch(
injectHideViewCall(
insertIndex,
viewRegister,
CLASS_DESCRIPTOR,
FILTER_CLASS_DESCRIPTOR,
"hideShortsShelf"
)
}
@@ -89,7 +91,7 @@ class HideShortsComponentsPatch : BytecodePatch(
val viewRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
addInstruction(
checkCastIndex + 1,
"sput-object v$viewRegister, $CLASS_DESCRIPTOR->pivotBar:" +
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;"
)
}
@@ -102,7 +104,7 @@ class HideShortsComponentsPatch : BytecodePatch(
throw RenderBottomNavigationBarFingerprint.toErrorResult()
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
addInstruction(0, "invoke-static { }, $CLASS_DESCRIPTOR->hideNavigationBar()V")
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
}
} ?: return RenderBottomNavigationBarParentFingerprint.toErrorResult()
@@ -115,7 +117,7 @@ class HideShortsComponentsPatch : BytecodePatch(
addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, $CLASS_DESCRIPTOR->" +
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;"
)
}
@@ -127,7 +129,7 @@ class HideShortsComponentsPatch : BytecodePatch(
}
private companion object {
private const val CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/ShortsFilter;"
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/ShortsFilter;"
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
@@ -139,7 +141,7 @@ class HideShortsComponentsPatch : BytecodePatch(
val setIdIndex = referencedIndex + 1
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC
method.injectHideViewCall(setIdIndex, viewRegister, CLASS_DESCRIPTOR, methodName)
method.injectHideViewCall(setIdIndex, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName)
}
}
}

View File

@@ -42,7 +42,7 @@ import org.jf.dexlib2.iface.reference.StringReference
@Patch
@DependsOn(
dependencies = [
[
IntegrationsPatch::class,
VideoIdPatch::class,
// Required to skip segments on time.

View File

@@ -0,0 +1,11 @@
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object LithoFilterFingerprint : MethodFingerprint(
customFingerprint = custom@{ method, classDef ->
if (method.name != "<clinit>") return@custom false
classDef.type.endsWith("LithoFilterPatch;")
}
)

View File

@@ -4,8 +4,11 @@ import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
@@ -14,30 +17,28 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ComponentContextParserFingerprint
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.EmptyComponentBuilderFingerprint
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ProtobufBufferFingerprint
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ReadComponentIdentifierFingerprint
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.*
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import java.io.Closeable
@DependsOn([IntegrationsPatch::class])
@Description("Hooks the method which parses the bytes into a ComponentContext to filter components.")
@LithoFilterCompatibility
@Version("0.0.1")
class LithoFilterPatch : BytecodePatch(
listOf(ComponentContextParserFingerprint)
) {
listOf(ComponentContextParserFingerprint, LithoFilterFingerprint)
), Closeable {
override fun execute(context: BytecodeContext): PatchResult {
ComponentContextParserFingerprint.result?.also {
arrayOf(
EmptyComponentBuilderFingerprint, ReadComponentIdentifierFingerprint, ProtobufBufferFingerprint
EmptyComponentBuilderFingerprint,
ReadComponentIdentifierFingerprint,
ProtobufBufferFingerprint
).forEach { fingerprint ->
if (!fingerprint.resolve(context, it.mutableMethod, it.mutableClass))
return fingerprint.toErrorResult()
if (fingerprint.resolve(context, it.mutableMethod, it.mutableClass)) return@forEach
return fingerprint.toErrorResult()
}
}?.let { result ->
val builderMethodIndex = EmptyComponentBuilderFingerprint.patternScanEndIndex
@@ -45,16 +46,28 @@ class LithoFilterPatch : BytecodePatch(
result.mutableMethod.apply {
val insertHookIndex = result.scanResult.patternScanResult!!.endIndex
val builderMethodDescriptor = getInstruction(builderMethodIndex).descriptor
val emptyComponentFieldDescriptor = getInstruction(emptyComponentFieldIndex).descriptor
// Register is overwritten right after it is used in this patch, therefore free to clobber.
val free = getInstruction<TwoRegisterInstruction>(insertHookIndex - 1).registerA
val free2 = getInstruction<OneRegisterInstruction>(insertHookIndex).registerA
// region Get free registers that this patch uses
// Registers are overwritten right after they are used in this patch, therefore free to clobber.
val freeRegistersInstruction = getInstruction<FiveRegisterInstruction>(insertHookIndex - 2)
// Later used to store the protobuf buffer object.
val free1 = getInstruction<OneRegisterInstruction>(insertHookIndex).registerA
// Later used to store the identifier of the component.
// This register currently holds a reference to the StringBuilder object
// that is required before clobbering.
val free2 = freeRegistersInstruction.registerC
@Suppress("UnnecessaryVariable")
// The register, this patch clobbers, is previously used for the StringBuilder,
// later on a new StringBuilder is instantiated on it.
val stringBuilderRegister = free
val stringBuilderRegister = free2
// endregion
// region Get references that this patch needs
val builderMethodDescriptor = getInstruction(builderMethodIndex).descriptor
val emptyComponentFieldDescriptor = getInstruction(emptyComponentFieldIndex).descriptor
val identifierRegister =
getInstruction<OneRegisterInstruction>(ReadComponentIdentifierFingerprint.patternScanEndIndex).registerA
@@ -69,57 +82,87 @@ class LithoFilterPatch : BytecodePatch(
getInstruction(ProtobufBufferFingerprint.patternScanEndIndex - 1).descriptor
val protobufBufferFieldDescriptor = "$protobufBufferRefTypeDescriptor->b:Ljava/nio/ByteBuffer;"
// endregion
// region Patch the method
// Insert the instructions that are responsible
// to return an EmptyComponent instead of the original component if the filter method returns false.
addInstructionsWithLabels(
insertHookIndex, // right after setting the component.pathBuilder field.
insertHookIndex,
"""
# Get the protobuf buffer object.
move-object/from16 v$free2, p$protobufParameterNumber
iget-object v$free2, v$free2, $protobufBufferRefTypeRefFieldDescriptor
check-cast v$free2, $protobufBufferRefTypeDescriptor
move-object/from16 v$free1, p$protobufParameterNumber
iget-object v$free1, v$free1, $protobufBufferRefTypeRefFieldDescriptor
check-cast v$free1, $protobufBufferRefTypeDescriptor
# Register "free" now holds the protobuf buffer object
iget-object v$free2, v$free2, $protobufBufferFieldDescriptor
iget-object v$free1, v$free1, $protobufBufferFieldDescriptor
# Invoke the filter method.
invoke-static { v$stringBuilderRegister, v$identifierRegister, v$free2 }, $FILTER_METHOD_DESCRIPTOR
move-result v$free
invoke-static { v$stringBuilderRegister, v$identifierRegister, v$free1 }, $FILTER_METHOD_DESCRIPTOR
move-result v$free1
if-eqz v$free, :not_an_ad
# If the filter method returned true, then return a replacement empty component.
move-object/from16 v$free, p1
invoke-static {v$free}, $builderMethodDescriptor
move-result-object v$free
iget-object v$free, v$free, $emptyComponentFieldDescriptor
return-object v$free
if-eqz v$free1, :unfiltered
move-object/from16 v$free2, p1
invoke-static {v$free2}, $builderMethodDescriptor
move-result-object v$free2
iget-object v$free2, v$free2, $emptyComponentFieldDescriptor
return-object v$free2
""",
ExternalLabel("not_an_ad", getInstruction(insertHookIndex))
// Used to jump over the instruction which block the component from being created.
ExternalLabel("unfiltered", getInstruction(insertHookIndex))
)
// endregion
}
} ?: return ComponentContextParserFingerprint.toErrorResult()
LithoFilterFingerprint.result?.mutableMethod?.apply {
removeInstructions(2, 4) // Remove dummy filter.
addFilter = { classDescriptor ->
addInstructions(
2,
"""
new-instance v1, $classDescriptor
invoke-direct {v1}, $classDescriptor-><init>()V
const/4 v2, ${filterCount++}
aput-object v1, v0, v2
"""
)
}
} ?: return LithoFilterFingerprint.toErrorResult()
return PatchResultSuccess()
}
private companion object {
override fun close() = LithoFilterFingerprint.result!!
.mutableMethod.replaceInstruction(0, "const/4 v0, $filterCount")
companion object {
private val MethodFingerprint.patternScanResult
get() = result!!.scanResult.patternScanResult!!
val MethodFingerprint.patternScanEndIndex
private val MethodFingerprint.patternScanEndIndex
get() = patternScanResult.endIndex
val MethodFingerprint.patternScanStartIndex
private val MethodFingerprint.patternScanStartIndex
get() = patternScanResult.startIndex
val Instruction.descriptor
private val Instruction.descriptor
get() = (this as ReferenceInstruction).reference.toString()
const val FILTER_METHOD_DESCRIPTOR =
private const val FILTER_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/patches/components/LithoFilterPatch;" +
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
internal lateinit var addFilter: (String) -> Unit
private set
private var filterCount = 0
}
}