mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-22 18:23:59 +00:00
Compare commits
12 Commits
v4.4.0-dev
...
v4.4.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c87f8a376d | ||
|
|
cb4b6514db | ||
|
|
5a172c9deb | ||
|
|
a9f418a19f | ||
|
|
5b0360c067 | ||
|
|
069f26de20 | ||
|
|
46ff5b8b92 | ||
|
|
69721509bf | ||
|
|
0bd0c827a4 | ||
|
|
cbae1383ca | ||
|
|
2679fad25f | ||
|
|
08c4468ff1 |
36
CHANGELOG.md
36
CHANGELOG.md
@@ -1,3 +1,39 @@
|
|||||||
|
# [4.4.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.13...v4.4.0-dev.14) (2024-03-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Hide layout components:** Filter home/search results by keywords ([#2853](https://github.com/ReVanced/revanced-patches/issues/2853)) ([5916204](https://github.com/ReVanced/revanced-patches/commit/59162042b0a68edf7f94a3c21f838dada3c3f9c3))
|
||||||
|
|
||||||
|
# [4.4.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.12...v4.4.0-dev.13) (2024-03-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube:** Move setting to correct screen ([a16eda8](https://github.com/ReVanced/revanced-patches/commit/a16eda864515612d3a6b846082844df15eb49f56))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Hide Shorts components:** Hide like and dislike buttons ([2df0892](https://github.com/ReVanced/revanced-patches/commit/2df0892682406e67283c4aeaacebf8f222029833))
|
||||||
|
* **YouTube - Hide Shorts components:** Hide sound metadata label ([ea7d1e0](https://github.com/ReVanced/revanced-patches/commit/ea7d1e0d08cc245117ffe8ad0df3c31c5e87f739))
|
||||||
|
* **YouTube - Hide Shorts components:** Hide title and full video link label ([e7b64e1](https://github.com/ReVanced/revanced-patches/commit/e7b64e154e7fb8edd0037f5e171f4aa3ed9017f8))
|
||||||
|
|
||||||
|
# [4.4.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.11...v4.4.0-dev.12) (2024-03-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube:** Fix video playback by switching to ReVanced GmsCore vendor ([#2907](https://github.com/ReVanced/revanced-patches/issues/2907)) ([33ea122](https://github.com/ReVanced/revanced-patches/commit/33ea12228c2ae5dcadf3e7c7016d4bf6006d899a))
|
||||||
|
|
||||||
|
# [4.4.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.10...v4.4.0-dev.11) (2024-03-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Mi Fitness:** Add `Force English locale` and `Fix login` patch ([#2734](https://github.com/ReVanced/revanced-patches/issues/2734)) ([7a25791](https://github.com/ReVanced/revanced-patches/commit/7a25791d53530b1236896b2c3d6275ee7556e8b7))
|
||||||
|
* **Sync for Lemmy:** Add `Disable ads` patch ([#2872](https://github.com/ReVanced/revanced-patches/issues/2872)) ([0785819](https://github.com/ReVanced/revanced-patches/commit/0785819dd5ad487c778b5baf09004cdab3687184))
|
||||||
|
|
||||||
# [4.4.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.9...v4.4.0-dev.10) (2024-03-25)
|
# [4.4.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.9...v4.4.0-dev.10) (2024-03-25)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -284,6 +284,18 @@ public final class app/revanced/patches/messenger/inputfield/patch/DisableTyping
|
|||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/mifitness/misc/login/FixLoginPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/mifitness/misc/login/FixLoginPatch;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/moneymanager/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/moneymanager/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/moneymanager/UnlockProPatch;
|
public static final field INSTANCE Lapp/revanced/patches/moneymanager/UnlockProPatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
@@ -481,6 +493,13 @@ public final class app/revanced/patches/reddit/customclients/Constants {
|
|||||||
public static final field OAUTH_USER_AGENT Ljava/lang/String;
|
public static final field OAUTH_USER_AGENT Ljava/lang/String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public fun <init> (Ljava/util/Set;Ljava/util/Set;)V
|
||||||
|
public synthetic fun <init> (Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch {
|
public final class app/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch;
|
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch;
|
||||||
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
@@ -536,10 +555,12 @@ public final class app/revanced/patches/reddit/customclients/slide/api/SpoofClie
|
|||||||
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/reddit/customclients/syncforlemmy/ads/DisableAdsPatch : app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforlemmy/ads/DisableAdsPatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch : app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch;
|
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/reddit/customclients/syncforreddit/annoyances/startup/DisableSyncForLemmyBottomSheetPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/reddit/customclients/syncforreddit/annoyances/startup/DisableSyncForLemmyBottomSheetPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
@@ -615,6 +636,7 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes
|
|||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
||||||
protected final fun getGmsCoreVendor ()Ljava/lang/String;
|
protected final fun getGmsCoreVendor ()Ljava/lang/String;
|
||||||
|
protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
|
public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
@@ -1587,6 +1609,13 @@ public final class app/revanced/patches/youtube/misc/minimizedplayback/Minimized
|
|||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch;
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
public final fun getHookNavigationButtonCreated ()Lkotlin/jvm/functions/Function1;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch : app/revanced/patcher/patch/ResourcePatch, java/io/Closeable {
|
public final class app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch : app/revanced/patcher/patch/ResourcePatch, java/io/Closeable {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch;
|
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch;
|
||||||
public final fun addControls (Ljava/lang/String;)V
|
public final fun addControls (Ljava/lang/String;)V
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
org.gradle.caching = true
|
org.gradle.caching = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 4.4.0-dev.10
|
version = 4.4.0-dev.14
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package app.revanced.patches.mifitness.misc.locale
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.mifitness.misc.locale.fingerprints.SyncBluetoothLanguageFingerprint
|
||||||
|
import app.revanced.patches.mifitness.misc.login.FixLoginPatch
|
||||||
|
import app.revanced.util.exception
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Force English locale",
|
||||||
|
description = "Forces wearable devices to use the English locale.",
|
||||||
|
compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")],
|
||||||
|
dependencies = [FixLoginPatch::class],
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object ForceEnglishLocalePatch : BytecodePatch(
|
||||||
|
setOf(SyncBluetoothLanguageFingerprint),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
SyncBluetoothLanguageFingerprint.result?.let {
|
||||||
|
val resolvePhoneLocaleInstruction = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val registerIndexToUpdate =
|
||||||
|
getInstruction<OneRegisterInstruction>(resolvePhoneLocaleInstruction).registerA
|
||||||
|
|
||||||
|
replaceInstruction(
|
||||||
|
resolvePhoneLocaleInstruction,
|
||||||
|
"const-string v$registerIndexToUpdate, \"en_gb\"",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw SyncBluetoothLanguageFingerprint.exception
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package app.revanced.patches.mifitness.misc.locale.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
internal object SyncBluetoothLanguageFingerprint : MethodFingerprint(
|
||||||
|
customFingerprint = { methodDef, _ ->
|
||||||
|
methodDef.definingClass == "Lcom/xiaomi/fitness/devicesettings/DeviceSettingsSyncer;" &&
|
||||||
|
methodDef.name == "syncBluetoothLanguage"
|
||||||
|
},
|
||||||
|
opcodes = listOf(Opcode.MOVE_RESULT_OBJECT),
|
||||||
|
)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package app.revanced.patches.mifitness.misc.login
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.mifitness.misc.login.fingerprints.XiaomiAccountManagerConstructorFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Fix login",
|
||||||
|
description = "Fixes login for uncertified Mi Fitness app",
|
||||||
|
compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")],
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object FixLoginPatch : BytecodePatch(
|
||||||
|
setOf(XiaomiAccountManagerConstructorFingerprint),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
XiaomiAccountManagerConstructorFingerprint.result?.let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val isCertifiedIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
|
val isCertifiedRegister = getInstruction<OneRegisterInstruction>(isCertifiedIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
isCertifiedIndex,
|
||||||
|
"const/4 p$isCertifiedRegister, 0x0",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw XiaomiAccountManagerConstructorFingerprint.exception
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package app.revanced.patches.mifitness.misc.login.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
internal object XiaomiAccountManagerConstructorFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.CONSTRUCTOR,
|
||||||
|
customFingerprint = { methodDef, _ ->
|
||||||
|
methodDef.definingClass == "Lcom/xiaomi/passport/accountmanager/XiaomiAccountManager;"
|
||||||
|
},
|
||||||
|
opcodes = listOf(Opcode.IF_NEZ),
|
||||||
|
)
|
||||||
@@ -2,12 +2,12 @@ package app.revanced.patches.music.misc.gms
|
|||||||
|
|
||||||
import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME
|
import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME
|
||||||
import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
||||||
import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption
|
import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption
|
||||||
import app.revanced.patches.music.misc.gms.fingerprints.*
|
import app.revanced.patches.music.misc.gms.fingerprints.*
|
||||||
import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint
|
|
||||||
import app.revanced.patches.music.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.music.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
|
import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint
|
||||||
import app.revanced.patches.shared.fingerprints.CastContextFetchFingerprint
|
import app.revanced.patches.shared.fingerprints.CastContextFetchFingerprint
|
||||||
|
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||||
@@ -32,7 +32,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
|||||||
CastDynamiteModuleV2Fingerprint,
|
CastDynamiteModuleV2Fingerprint,
|
||||||
CastContextFetchFingerprint,
|
CastContextFetchFingerprint,
|
||||||
PrimeMethodFingerprint,
|
PrimeMethodFingerprint,
|
||||||
)
|
),
|
||||||
) {
|
) {
|
||||||
override val gmsCoreVendor by gmsCoreVendorOption
|
override val gmsCoreVendor by gmsCoreVendorGroupIdOption
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package app.revanced.patches.reddit.customclients.ads
|
||||||
|
|
||||||
|
import app.revanced.patcher.PatchClass
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patches.reddit.customclients.ads.fingerprints.IsAdsEnabledFingerprint
|
||||||
|
import app.revanced.util.returnEarly
|
||||||
|
|
||||||
|
abstract class BaseDisableAdsPatch(
|
||||||
|
dependencies: Set<PatchClass> = emptySet(),
|
||||||
|
compatiblePackages: Set<CompatiblePackage>,
|
||||||
|
) : BytecodePatch(
|
||||||
|
name = "Disable ads",
|
||||||
|
dependencies = dependencies,
|
||||||
|
compatiblePackages = compatiblePackages,
|
||||||
|
fingerprints = setOf(IsAdsEnabledFingerprint),
|
||||||
|
) {
|
||||||
|
override fun execute(context: BytecodeContext) = listOf(IsAdsEnabledFingerprint).returnEarly()
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.reddit.customclients.syncforreddit.ads.fingerprints
|
package app.revanced.patches.reddit.customclients.ads.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
@@ -7,5 +7,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
internal object IsAdsEnabledFingerprint : MethodFingerprint(
|
internal object IsAdsEnabledFingerprint : MethodFingerprint(
|
||||||
returnType = "Z",
|
returnType = "Z",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
strings = listOf("SyncIapHelper")
|
strings = listOf("SyncIapHelper"),
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package app.revanced.patches.reddit.customclients.syncforlemmy.ads
|
||||||
|
|
||||||
|
import app.revanced.patches.reddit.customclients.ads.BaseDisableAdsPatch
|
||||||
|
import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.DisablePiracyDetectionPatch
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object DisableAdsPatch : BaseDisableAdsPatch(
|
||||||
|
dependencies = setOf(DisablePiracyDetectionPatch::class),
|
||||||
|
compatiblePackages = setOf(CompatiblePackage("com.laurencedawson.reddit_sync")),
|
||||||
|
)
|
||||||
@@ -1,30 +1,8 @@
|
|||||||
package app.revanced.patches.reddit.customclients.syncforreddit.ads
|
package app.revanced.patches.reddit.customclients.syncforreddit.ads
|
||||||
|
|
||||||
import app.revanced.util.exception
|
import app.revanced.patches.reddit.customclients.ads.BaseDisableAdsPatch
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
import app.revanced.patches.reddit.customclients.syncforreddit.ads.fingerprints.IsAdsEnabledFingerprint
|
|
||||||
import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.DisablePiracyDetectionPatch
|
|
||||||
|
|
||||||
@Patch(
|
|
||||||
name = "Disable ads",
|
|
||||||
dependencies = [DisablePiracyDetectionPatch::class],
|
|
||||||
compatiblePackages = [CompatiblePackage("com.laurencedawson.reddit_sync")]
|
|
||||||
)
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object DisableAdsPatch : BytecodePatch(setOf(IsAdsEnabledFingerprint)) {
|
object DisableAdsPatch : BaseDisableAdsPatch(
|
||||||
override fun execute(context: BytecodeContext) {
|
compatiblePackages = setOf(CompatiblePackage("io.syncapps.lemmy_sync")),
|
||||||
IsAdsEnabledFingerprint.result?.mutableMethod?.apply {
|
)
|
||||||
addInstructions(
|
|
||||||
0,
|
|
||||||
"""
|
|
||||||
const/4 v0, 0x0
|
|
||||||
return v0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
} ?: throw IsAdsEnabledFingerprint.exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -53,15 +53,15 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
) : BytecodePatch(
|
) : BytecodePatch(
|
||||||
name = "GmsCore support",
|
name = "GmsCore support",
|
||||||
description = "Allows patched Google apps to run without root and under a different package name " +
|
description = "Allows patched Google apps to run without root and under a different package name " +
|
||||||
"by using GmsCore instead of Google Play Services.",
|
"by using GmsCore instead of Google Play Services.",
|
||||||
dependencies = setOf(
|
dependencies = setOf(
|
||||||
ChangePackageNamePatch::class,
|
ChangePackageNamePatch::class,
|
||||||
gmsCoreSupportResourcePatch::class,
|
gmsCoreSupportResourcePatch::class,
|
||||||
integrationsPatchDependency
|
integrationsPatchDependency,
|
||||||
) + dependencies,
|
) + dependencies,
|
||||||
compatiblePackages = compatiblePackages,
|
compatiblePackages = compatiblePackages,
|
||||||
fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints,
|
fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints,
|
||||||
requiresIntegrations = true
|
requiresIntegrations = true,
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
// Manually register all options of the resource patch so that they are visible in the patch API.
|
// Manually register all options of the resource patch so that they are visible in the patch API.
|
||||||
@@ -77,7 +77,7 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
val transformations = arrayOf(
|
val transformations = arrayOf(
|
||||||
::commonTransform,
|
::commonTransform,
|
||||||
::contentUrisTransform,
|
::contentUrisTransform,
|
||||||
packageNameTransform(fromPackageName, packageName)
|
packageNameTransform(fromPackageName, packageName),
|
||||||
)
|
)
|
||||||
context.transformStringReferences transform@{ string ->
|
context.transformStringReferences transform@{ string ->
|
||||||
transformations.forEach { transform ->
|
transformations.forEach { transform ->
|
||||||
@@ -96,7 +96,7 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
// Check the availability of GmsCore.
|
// Check the availability of GmsCore.
|
||||||
mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstruction(
|
mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstruction(
|
||||||
1, // Hack to not disturb other patches (such as the integrations patch).
|
1, // Hack to not disturb other patches (such as the integrations patch).
|
||||||
"invoke-static {}, Lapp/revanced/integrations/youtube/patches/GmsCoreSupport;->checkAvailability()V"
|
"invoke-static {}, Lapp/revanced/integrations/youtube/patches/GmsCoreSupport;->checkAvailability()V",
|
||||||
) ?: throw mainActivityOnCreateFingerprint.exception
|
) ?: throw mainActivityOnCreateFingerprint.exception
|
||||||
|
|
||||||
// Change the vendor of GmsCore in ReVanced Integrations.
|
// Change the vendor of GmsCore in ReVanced Integrations.
|
||||||
@@ -130,8 +130,8 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
BuilderInstruction21c(
|
BuilderInstruction21c(
|
||||||
Opcode.CONST_STRING,
|
Opcode.CONST_STRING,
|
||||||
instruction.registerA,
|
instruction.registerA,
|
||||||
ImmutableStringReference(transformedString)
|
ImmutableStringReference(transformedString),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,8 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
"com.google.android.gms",
|
"com.google.android.gms",
|
||||||
in PERMISSIONS,
|
in PERMISSIONS,
|
||||||
in ACTIONS,
|
in ACTIONS,
|
||||||
in AUTHORITIES -> referencedString.replace("com.google", gmsCoreVendor!!)
|
in AUTHORITIES,
|
||||||
|
-> referencedString.replace("com.google", gmsCoreVendor!!)
|
||||||
|
|
||||||
// No vendor prefix for whatever reason...
|
// No vendor prefix for whatever reason...
|
||||||
"subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds"
|
"subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds"
|
||||||
@@ -161,7 +162,7 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
if (str.startsWith(uriPrefix)) {
|
if (str.startsWith(uriPrefix)) {
|
||||||
return str.replace(
|
return str.replace(
|
||||||
uriPrefix,
|
uriPrefix,
|
||||||
"content://${authority.replace("com.google", gmsCoreVendor!!)}"
|
"content://${authority.replace("com.google", gmsCoreVendor!!)}",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,13 +175,13 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? = { string ->
|
private fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? = { string ->
|
||||||
when (string) {
|
when (string) {
|
||||||
"$fromPackageName.SuggestionsProvider",
|
"$fromPackageName.SuggestionsProvider",
|
||||||
"$fromPackageName.fileprovider" -> string.replace(fromPackageName, toPackageName)
|
"$fromPackageName.fileprovider",
|
||||||
|
-> string.replace(fromPackageName, toPackageName)
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -273,6 +274,9 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
// fido
|
// fido
|
||||||
"com.google.android.gms.fido.fido2.privileged.START",
|
"com.google.android.gms.fido.fido2.privileged.START",
|
||||||
|
|
||||||
|
// gass
|
||||||
|
"com.google.android.gms.gass.START",
|
||||||
|
|
||||||
// games
|
// games
|
||||||
"com.google.android.gms.games.service.START",
|
"com.google.android.gms.games.service.START",
|
||||||
"com.google.android.gms.games.PLAY_GAMES_UPGRADE",
|
"com.google.android.gms.games.PLAY_GAMES_UPGRADE",
|
||||||
@@ -292,8 +296,18 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
// misc
|
// misc
|
||||||
"com.google.android.gms.gmscompliance.service.START",
|
"com.google.android.gms.gmscompliance.service.START",
|
||||||
"com.google.android.gms.oss.licenses.service.START",
|
"com.google.android.gms.oss.licenses.service.START",
|
||||||
|
"com.google.android.gms.tapandpay.service.BIND",
|
||||||
|
"com.google.android.gms.measurement.START",
|
||||||
|
"com.google.android.gms.languageprofile.service.START",
|
||||||
|
"com.google.android.gms.clearcut.service.START",
|
||||||
|
"com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE",
|
||||||
|
|
||||||
|
// potoken
|
||||||
|
"com.google.android.gms.potokens.service.START",
|
||||||
|
|
||||||
|
// droidguard/ safetynet
|
||||||
|
"com.google.android.gms.droidguard.service.START",
|
||||||
"com.google.android.gms.safetynet.service.START",
|
"com.google.android.gms.safetynet.service.START",
|
||||||
"com.google.android.gms.tapandpay.service.BIND"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -314,9 +328,9 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
"com.google.android.gms.fonts",
|
"com.google.android.gms.fonts",
|
||||||
|
|
||||||
// phenotype
|
// phenotype
|
||||||
"com.google.android.gms.phenotype"
|
"com.google.android.gms.phenotype",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,21 +24,23 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
|||||||
private val spoofedPackageSignature: String,
|
private val spoofedPackageSignature: String,
|
||||||
dependencies: Set<PatchClass> = setOf(),
|
dependencies: Set<PatchClass> = setOf(),
|
||||||
) : ResourcePatch(dependencies = setOf(ChangePackageNamePatch::class, AddResourcesPatch::class) + dependencies) {
|
) : ResourcePatch(dependencies = setOf(ChangePackageNamePatch::class, AddResourcesPatch::class) + dependencies) {
|
||||||
internal val gmsCoreVendorOption =
|
internal val gmsCoreVendorGroupIdOption =
|
||||||
stringPatchOption(
|
stringPatchOption(
|
||||||
key = "gmsCoreVendor",
|
key = "gmsCoreVendorGroupId",
|
||||||
default = "com.mgoogle",
|
default = "app.revanced",
|
||||||
values =
|
values =
|
||||||
mapOf(
|
mapOf(
|
||||||
"Vanced" to "com.mgoogle",
|
|
||||||
"ReVanced" to "app.revanced",
|
"ReVanced" to "app.revanced",
|
||||||
),
|
),
|
||||||
title = "GmsCore Vendor",
|
title = "GmsCore vendor group ID",
|
||||||
description = "The group id of the GmsCore vendor.",
|
description = "The vendor's group ID for GmsCore.",
|
||||||
required = true,
|
required = true,
|
||||||
) { it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")) }
|
) { it!!.matches(Regex(PACKAGE_NAME_REGEX_PATTERN)) }
|
||||||
|
|
||||||
protected val gmsCoreVendor by gmsCoreVendorOption
|
protected val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption
|
||||||
|
|
||||||
|
@Deprecated("Use gmsCoreVendorGroupId instead.", ReplaceWith("gmsCoreVendorGroupId"))
|
||||||
|
protected val gmsCoreVendor by gmsCoreVendorGroupIdOption
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
AddResourcesPatch(BaseGmsCoreSupportResourcePatch::class)
|
AddResourcesPatch(BaseGmsCoreSupportResourcePatch::class)
|
||||||
@@ -70,12 +72,12 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
|||||||
|
|
||||||
// Spoof package name and signature.
|
// Spoof package name and signature.
|
||||||
applicationNode.adoptChild("meta-data") {
|
applicationNode.adoptChild("meta-data") {
|
||||||
setAttribute("android:name", "$gmsCoreVendor.android.gms.SPOOFED_PACKAGE_NAME")
|
setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_NAME")
|
||||||
setAttribute("android:value", fromPackageName)
|
setAttribute("android:value", fromPackageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
applicationNode.adoptChild("meta-data") {
|
applicationNode.adoptChild("meta-data") {
|
||||||
setAttribute("android:name", "$gmsCoreVendor.android.gms.SPOOFED_PACKAGE_SIGNATURE")
|
setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_SIGNATURE")
|
||||||
setAttribute("android:value", spoofedPackageSignature)
|
setAttribute("android:value", spoofedPackageSignature)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +85,7 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
|||||||
applicationNode.adoptChild("meta-data") {
|
applicationNode.adoptChild("meta-data") {
|
||||||
// TODO: The name of this metadata should be dynamic.
|
// TODO: The name of this metadata should be dynamic.
|
||||||
setAttribute("android:name", "app.revanced.MICROG_PACKAGE_NAME")
|
setAttribute("android:name", "app.revanced.MICROG_PACKAGE_NAME")
|
||||||
setAttribute("android:value", "$gmsCoreVendor.android.gms")
|
setAttribute("android:value", "$gmsCoreVendorGroupId.android.gms")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,11 +112,16 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
|||||||
"$packageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION",
|
"$packageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION",
|
||||||
).replace(
|
).replace(
|
||||||
"com.google.android.c2dm",
|
"com.google.android.c2dm",
|
||||||
"$gmsCoreVendor.android.c2dm",
|
"$gmsCoreVendorGroupId.android.c2dm",
|
||||||
).replace(
|
).replace(
|
||||||
"</queries>",
|
"</queries>",
|
||||||
"<package android:name=\"$gmsCoreVendor.android.gms\"/></queries>",
|
"<package android:name=\"$gmsCoreVendorGroupId.android.gms\"/></queries>",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private const val VANCED_VENDOR = "com.mgoogle"
|
||||||
|
private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
|||||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
||||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.*
|
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.ANDROID_AUTOMOTIVE_STRING
|
||||||
import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT
|
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.AddCreateButtonViewFingerprint
|
||||||
import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.injectHook
|
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
@@ -24,8 +24,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
IntegrationsPatch::class,
|
IntegrationsPatch::class,
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResolvePivotBarFingerprintsPatch::class,
|
|
||||||
AddResourcesPatch::class,
|
AddResourcesPatch::class,
|
||||||
|
NavigationBarHookPatch::class,
|
||||||
],
|
],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
@@ -47,7 +47,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.37",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -76,53 +76,7 @@ object NavigationButtonsPatch : BytecodePatch(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
// Switch create with notifications button.
|
||||||
* Resolve fingerprints
|
|
||||||
*/
|
|
||||||
|
|
||||||
val initializeButtonsResult = InitializeButtonsFingerprint.result!!
|
|
||||||
|
|
||||||
val fingerprintResults =
|
|
||||||
arrayOf(PivotBarEnumFingerprint, PivotBarButtonsViewFingerprint)
|
|
||||||
.onEach {
|
|
||||||
if (!it.resolve(
|
|
||||||
context,
|
|
||||||
initializeButtonsResult.mutableMethod,
|
|
||||||
initializeButtonsResult.mutableClass,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
throw it.exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.map { it.result!!.scanResult.patternScanResult!! }
|
|
||||||
|
|
||||||
val enumScanResult = fingerprintResults[0]
|
|
||||||
val buttonViewResult = fingerprintResults[1]
|
|
||||||
|
|
||||||
val enumHookInsertIndex = enumScanResult.startIndex + 2
|
|
||||||
val buttonHookInsertIndex = buttonViewResult.endIndex
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Inject hooks
|
|
||||||
*/
|
|
||||||
|
|
||||||
val enumHook = "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, " +
|
|
||||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->lastNavigationButton:Ljava/lang/Enum;"
|
|
||||||
val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
|
|
||||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideButton(Landroid/view/View;)V"
|
|
||||||
|
|
||||||
// Inject bottom to top to not mess up the indices
|
|
||||||
mapOf(
|
|
||||||
buttonHook to buttonHookInsertIndex,
|
|
||||||
enumHook to enumHookInsertIndex,
|
|
||||||
).forEach { (hook, insertIndex) ->
|
|
||||||
initializeButtonsResult.mutableMethod.injectHook(hook, insertIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hide create or switch it with notifications buttons.
|
|
||||||
*/
|
|
||||||
|
|
||||||
AddCreateButtonViewFingerprint.result?.let {
|
AddCreateButtonViewFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val stringIndex = it.scanResult.stringsScanResult!!.matches.find { match ->
|
val stringIndex = it.scanResult.stringsScanResult!!.matches.find { match ->
|
||||||
@@ -130,7 +84,8 @@ object NavigationButtonsPatch : BytecodePatch(
|
|||||||
}!!.index
|
}!!.index
|
||||||
|
|
||||||
val conditionalCheckIndex = stringIndex - 1
|
val conditionalCheckIndex = stringIndex - 1
|
||||||
val conditionRegister = getInstruction<OneRegisterInstruction>(conditionalCheckIndex).registerA
|
val conditionRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(conditionalCheckIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
conditionalCheckIndex,
|
conditionalCheckIndex,
|
||||||
@@ -142,26 +97,7 @@ object NavigationButtonsPatch : BytecodePatch(
|
|||||||
}
|
}
|
||||||
} ?: throw AddCreateButtonViewFingerprint.exception
|
} ?: throw AddCreateButtonViewFingerprint.exception
|
||||||
|
|
||||||
/*
|
// Hook navigation button created, in order to hide them.
|
||||||
* Resolve fingerprints
|
NavigationBarHookPatch.hookNavigationButtonCreated(INTEGRATIONS_CLASS_DESCRIPTOR)
|
||||||
*/
|
|
||||||
|
|
||||||
InitializeButtonsFingerprint.result!!.let {
|
|
||||||
if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)) {
|
|
||||||
throw PivotBarCreateButtonViewFingerprint.exception
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PivotBarCreateButtonViewFingerprint.result!!.apply {
|
|
||||||
val insertIndex = scanResult.patternScanResult!!.endIndex
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Inject hooks
|
|
||||||
*/
|
|
||||||
val hook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " +
|
|
||||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideCreateButton(Landroid/view/View;)V"
|
|
||||||
|
|
||||||
mutableMethod.injectHook(hook, insertIndex)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.layout.buttons.navigation
|
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.PatchException
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
|
||||||
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.InitializeButtonsFingerprint
|
|
||||||
import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.PivotBarConstructorFingerprint
|
|
||||||
|
|
||||||
@Patch(
|
|
||||||
description = "Resolves necessary fingerprints.",
|
|
||||||
dependencies = [ResourceMappingPatch::class]
|
|
||||||
)
|
|
||||||
internal object ResolvePivotBarFingerprintsPatch : BytecodePatch(
|
|
||||||
setOf(PivotBarConstructorFingerprint)
|
|
||||||
) {
|
|
||||||
internal var imageOnlyTabResourceId: Long = -1
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
|
||||||
// imageOnlyTabResourceId is used in InitializeButtonsFingerprint fingerprint
|
|
||||||
ResourceMappingPatch.resourceMappings.find { it.type == "layout" && it.name == "image_only_tab" }
|
|
||||||
?.let { imageOnlyTabResourceId = it.id } ?: throw PatchException("Failed to find resource")
|
|
||||||
|
|
||||||
PivotBarConstructorFingerprint.result?.let {
|
|
||||||
// Resolve InitializeButtonsFingerprint on the class of the method
|
|
||||||
// which PivotBarConstructorFingerprint resolved to
|
|
||||||
if (!InitializeButtonsFingerprint.resolve(
|
|
||||||
context,
|
|
||||||
it.classDef
|
|
||||||
)
|
|
||||||
) throw InitializeButtonsFingerprint.exception
|
|
||||||
} ?: throw PivotBarConstructorFingerprint.exception
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
internal object PivotBarButtonsViewFingerprint : MethodFingerprint(
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.INVOKE_VIRTUAL_RANGE,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT, // target reference
|
|
||||||
Opcode.GOTO,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
internal object PivotBarCreateButtonViewFingerprint : MethodFingerprint(
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.INVOKE_DIRECT_RANGE,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.INVOKE_STATIC
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
internal object PivotBarEnumFingerprint : MethodFingerprint(
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.INVOKE_STATIC,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
Opcode.IF_NEZ, // target reference
|
|
||||||
Opcode.SGET_OBJECT,
|
|
||||||
Opcode.INVOKE_VIRTUAL,
|
|
||||||
Opcode.MOVE_RESULT,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.layout.buttons.navigation.utils
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode.MOVE_RESULT_OBJECT
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
internal object InjectionUtils {
|
|
||||||
const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injects an instruction into insertIndex of the hook.
|
|
||||||
* @param hook The hook to insert.
|
|
||||||
* @param insertIndex The index to insert the instruction at.
|
|
||||||
* [MOVE_RESULT_OBJECT] has to be the previous instruction before [insertIndex].
|
|
||||||
*/
|
|
||||||
fun MutableMethod.injectHook(hook: String, insertIndex: Int) {
|
|
||||||
val injectTarget = this
|
|
||||||
|
|
||||||
// Register to pass to the hook
|
|
||||||
val registerIndex = insertIndex - 1 // MOVE_RESULT_OBJECT is always the previous instruction
|
|
||||||
val register = injectTarget.getInstruction<OneRegisterInstruction>(registerIndex).registerA
|
|
||||||
|
|
||||||
injectTarget.addInstruction(
|
|
||||||
insertIndex,
|
|
||||||
hook.replace("REGISTER_INDEX", register.toString()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,6 +12,7 @@ import app.revanced.patcher.patch.annotation.Patch
|
|||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||||
import app.revanced.patches.shared.misc.settings.preference.InputType
|
import app.revanced.patches.shared.misc.settings.preference.InputType
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
||||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
@@ -20,8 +21,10 @@ import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElemen
|
|||||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
|
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
|
||||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
|
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||||
|
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
@@ -33,6 +36,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
LithoFilterPatch::class,
|
LithoFilterPatch::class,
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
AddResourcesPatch::class,
|
AddResourcesPatch::class,
|
||||||
|
NavigationBarHookPatch::class,
|
||||||
|
PlayerTypeHookPatch::class // Used by Keyword Content filter.
|
||||||
],
|
],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
@@ -54,7 +59,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.37",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -69,6 +74,8 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
"Lapp/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter;"
|
"Lapp/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter;"
|
||||||
private const val CUSTOM_FILTER_CLASS_NAME =
|
private const val CUSTOM_FILTER_CLASS_NAME =
|
||||||
"Lapp/revanced/integrations/youtube/patches/components/CustomFilter;"
|
"Lapp/revanced/integrations/youtube/patches/components/CustomFilter;"
|
||||||
|
private const val KEYWORD_FILTER_CLASS_NAME =
|
||||||
|
"Lapp/revanced/integrations/youtube/patches/components/KeywordContentFilter;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
@@ -94,6 +101,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
SwitchPreference("revanced_hide_emergency_box"),
|
SwitchPreference("revanced_hide_emergency_box"),
|
||||||
SwitchPreference("revanced_hide_expandable_chip"),
|
SwitchPreference("revanced_hide_expandable_chip"),
|
||||||
SwitchPreference("revanced_hide_info_panels"),
|
SwitchPreference("revanced_hide_info_panels"),
|
||||||
|
SwitchPreference("revanced_hide_join_membership_button"),
|
||||||
SwitchPreference("revanced_hide_medical_panels"),
|
SwitchPreference("revanced_hide_medical_panels"),
|
||||||
SwitchPreference("revanced_hide_quick_actions"),
|
SwitchPreference("revanced_hide_quick_actions"),
|
||||||
SwitchPreference("revanced_hide_related_videos"),
|
SwitchPreference("revanced_hide_related_videos"),
|
||||||
@@ -108,7 +116,6 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
SwitchPreference("revanced_hide_feed_survey"),
|
SwitchPreference("revanced_hide_feed_survey"),
|
||||||
SwitchPreference("revanced_hide_for_you_shelf"),
|
SwitchPreference("revanced_hide_for_you_shelf"),
|
||||||
SwitchPreference("revanced_hide_image_shelf"),
|
SwitchPreference("revanced_hide_image_shelf"),
|
||||||
SwitchPreference("revanced_hide_join_membership_button"),
|
|
||||||
SwitchPreference("revanced_hide_latest_posts_ads"),
|
SwitchPreference("revanced_hide_latest_posts_ads"),
|
||||||
SwitchPreference("revanced_hide_mix_playlists"),
|
SwitchPreference("revanced_hide_mix_playlists"),
|
||||||
SwitchPreference("revanced_hide_movies_section"),
|
SwitchPreference("revanced_hide_movies_section"),
|
||||||
@@ -117,6 +124,20 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
SwitchPreference("revanced_hide_search_result_shelf_header"),
|
SwitchPreference("revanced_hide_search_result_shelf_header"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SettingsPatch.PreferenceScreen.FEED.addPreferences(
|
||||||
|
PreferenceScreen(
|
||||||
|
key = "revanced_hide_keyword_content_screen",
|
||||||
|
sorting = Sorting.UNSORTED,
|
||||||
|
preferences = setOf(
|
||||||
|
SwitchPreference("revanced_hide_keyword_content_home"),
|
||||||
|
SwitchPreference("revanced_hide_keyword_content_subscriptions"),
|
||||||
|
SwitchPreference("revanced_hide_keyword_content_search"),
|
||||||
|
TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
|
||||||
|
NonInteractivePreference("revanced_hide_keyword_content_about")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||||
SwitchPreference("revanced_hide_gray_separator"),
|
SwitchPreference("revanced_hide_gray_separator"),
|
||||||
PreferenceScreen(
|
PreferenceScreen(
|
||||||
@@ -136,19 +157,19 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
|
|
||||||
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)
|
LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR)
|
||||||
LithoFilterPatch.addFilter(DESCRIPTION_COMPONENTS_FILTER_CLASS_NAME)
|
LithoFilterPatch.addFilter(DESCRIPTION_COMPONENTS_FILTER_CLASS_NAME)
|
||||||
|
LithoFilterPatch.addFilter(KEYWORD_FILTER_CLASS_NAME)
|
||||||
LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_NAME)
|
LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_NAME)
|
||||||
|
|
||||||
// region Mix playlists
|
// region Mix playlists
|
||||||
|
|
||||||
ParseElementFromBufferFingerprint.result?.let { result ->
|
ParseElementFromBufferFingerprint.resultOrThrow().let { result ->
|
||||||
val returnEmptyComponentInstruction =
|
val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
|
||||||
result.mutableMethod.getInstructions().last { it.opcode == Opcode.INVOKE_STATIC }
|
|
||||||
|
|
||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex
|
|
||||||
val conversionContextRegister =
|
val conversionContextRegister =
|
||||||
getInstruction<TwoRegisterInstruction>(consumeByteBufferIndex - 2).registerA
|
getInstruction<TwoRegisterInstruction>(consumeByteBufferIndex - 2).registerA
|
||||||
val byteBufferRegister = getInstruction<FiveRegisterInstruction>(consumeByteBufferIndex).registerD
|
val byteBufferRegister = getInstruction<FiveRegisterInstruction>(consumeByteBufferIndex).registerD
|
||||||
|
val returnEmptyComponentInstruction = getInstructions().last { it.opcode == Opcode.INVOKE_STATIC }
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
consumeByteBufferIndex,
|
consumeByteBufferIndex,
|
||||||
@@ -160,15 +181,15 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
|
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} ?: throw ParseElementFromBufferFingerprint.exception
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Watermark (legacy code for old versions of YouTube)
|
// region Watermark (legacy code for old versions of YouTube)
|
||||||
|
|
||||||
ShowWatermarkFingerprint.also {
|
ShowWatermarkFingerprint.also {
|
||||||
it.resolve(context, PlayerOverlayFingerprint.result?.classDef ?: throw PlayerOverlayFingerprint.exception)
|
it.resolve(context, PlayerOverlayFingerprint.resultOrThrow().classDef)
|
||||||
}.result?.mutableMethod?.apply {
|
}.resultOrThrow().mutableMethod.apply {
|
||||||
val index = implementation!!.instructions.size - 5
|
val index = implementation!!.instructions.size - 5
|
||||||
|
|
||||||
removeInstruction(index)
|
removeInstruction(index)
|
||||||
@@ -179,7 +200,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
move-result p2
|
move-result p2
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
} ?: throw ShowWatermarkFingerprint.exception
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,18 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
|||||||
SwitchPreference("revanced_hide_shorts_subscribe_button"),
|
SwitchPreference("revanced_hide_shorts_subscribe_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_subscribe_button_paused"),
|
SwitchPreference("revanced_hide_shorts_subscribe_button_paused"),
|
||||||
SwitchPreference("revanced_hide_shorts_thanks_button"),
|
SwitchPreference("revanced_hide_shorts_thanks_button"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_like_button"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_dislike_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_comments_button"),
|
SwitchPreference("revanced_hide_shorts_comments_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_remix_button"),
|
SwitchPreference("revanced_hide_shorts_remix_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_share_button"),
|
SwitchPreference("revanced_hide_shorts_share_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_info_panel"),
|
SwitchPreference("revanced_hide_shorts_info_panel"),
|
||||||
SwitchPreference("revanced_hide_shorts_channel_bar"),
|
SwitchPreference("revanced_hide_shorts_channel_bar"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_video_title"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_sound_metadata_label"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_full_video_link_label"),
|
||||||
SwitchPreference("revanced_hide_shorts_sound_button"),
|
SwitchPreference("revanced_hide_shorts_sound_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_navigation_bar")
|
SwitchPreference("revanced_hide_shorts_navigation_bar"),
|
||||||
)
|
)
|
||||||
|
|
||||||
ResourceMappingPatch.resourceMappings.find {
|
ResourceMappingPatch.resourceMappings.find {
|
||||||
@@ -42,4 +47,4 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
|||||||
it.type == "dimen" && it.name == "reel_player_right_cell_button_height"
|
it.type == "dimen" && it.name == "reel_player_right_cell_button_height"
|
||||||
}.id
|
}.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Client spoof",
|
name = "Client spoof",
|
||||||
description = "Adds options to spoof the client to allow video playback.",
|
description = "Spoofs the client to allow video playback.",
|
||||||
dependencies = [SpoofSignaturePatch::class],
|
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage("com.google.android.youtube"),
|
CompatiblePackage("com.google.android.youtube"),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -13,21 +13,11 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
|||||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
|
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ParamsMapPutFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplGeneralFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplLiveStreamFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplRecommendedLevelFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ScrubbedPreviewLayoutFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderRecommendedLevelFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderSpecFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererSpecFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailParentFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
|
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
|
||||||
import app.revanced.util.*
|
import app.revanced.util.exception
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
@@ -43,6 +33,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
|||||||
AddResourcesPatch::class,
|
AddResourcesPatch::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@Deprecated("This patch will be removed in the future.")
|
||||||
object SpoofSignaturePatch : BytecodePatch(
|
object SpoofSignaturePatch : BytecodePatch(
|
||||||
setOf(
|
setOf(
|
||||||
PlayerResponseModelImplGeneralFingerprint,
|
PlayerResponseModelImplGeneralFingerprint,
|
||||||
|
|||||||
@@ -6,12 +6,11 @@ import app.revanced.patches.youtube.layout.buttons.cast.HideCastButtonPatch
|
|||||||
import app.revanced.patches.youtube.misc.fix.playback.ClientSpoofPatch
|
import app.revanced.patches.youtube.misc.fix.playback.ClientSpoofPatch
|
||||||
import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME
|
import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME
|
||||||
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
||||||
import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption
|
import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption
|
||||||
import app.revanced.patches.youtube.misc.gms.fingerprints.*
|
import app.revanced.patches.youtube.misc.gms.fingerprints.*
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.shared.fingerprints.HomeActivityFingerprint
|
import app.revanced.patches.youtube.shared.fingerprints.HomeActivityFingerprint
|
||||||
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||||
fromPackageName = YOUTUBE_PACKAGE_NAME,
|
fromPackageName = YOUTUBE_PACKAGE_NAME,
|
||||||
@@ -22,18 +21,19 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
|||||||
GooglePlayUtilityFingerprint,
|
GooglePlayUtilityFingerprint,
|
||||||
CastDynamiteModuleFingerprint,
|
CastDynamiteModuleFingerprint,
|
||||||
CastDynamiteModuleV2Fingerprint,
|
CastDynamiteModuleV2Fingerprint,
|
||||||
CastContextFetchFingerprint
|
CastContextFetchFingerprint,
|
||||||
),
|
),
|
||||||
mainActivityOnCreateFingerprint = HomeActivityFingerprint,
|
mainActivityOnCreateFingerprint = HomeActivityFingerprint,
|
||||||
integrationsPatchDependency = IntegrationsPatch::class,
|
integrationsPatchDependency = IntegrationsPatch::class,
|
||||||
dependencies = setOf(
|
dependencies = setOf(
|
||||||
HideCastButtonPatch::class,
|
HideCastButtonPatch::class,
|
||||||
ClientSpoofPatch::class
|
ClientSpoofPatch::class,
|
||||||
),
|
),
|
||||||
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
||||||
compatiblePackages = setOf(
|
compatiblePackages = setOf(
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube", setOf(
|
"com.google.android.youtube",
|
||||||
|
setOf(
|
||||||
"18.48.39",
|
"18.48.39",
|
||||||
"18.49.37",
|
"18.49.37",
|
||||||
"19.01.34",
|
"19.01.34",
|
||||||
@@ -44,9 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.37",
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
fingerprints = setOf(
|
fingerprints = setOf(
|
||||||
ServiceCheckFingerprint,
|
ServiceCheckFingerprint,
|
||||||
@@ -55,7 +55,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
|||||||
CastDynamiteModuleV2Fingerprint,
|
CastDynamiteModuleV2Fingerprint,
|
||||||
CastContextFetchFingerprint,
|
CastContextFetchFingerprint,
|
||||||
PrimeMethodFingerprint,
|
PrimeMethodFingerprint,
|
||||||
)
|
),
|
||||||
) {
|
) {
|
||||||
override val gmsCoreVendor by gmsCoreVendorOption
|
override val gmsCoreVendor by gmsCoreVendorGroupIdOption
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,11 @@ import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_
|
|||||||
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
|
||||||
|
|
||||||
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
|
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
|
||||||
fromPackageName = YOUTUBE_PACKAGE_NAME,
|
fromPackageName = YOUTUBE_PACKAGE_NAME,
|
||||||
toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME,
|
toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME,
|
||||||
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600",
|
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600",
|
||||||
dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class)
|
dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
@@ -22,9 +21,9 @@ object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
|
|||||||
IntentPreference(
|
IntentPreference(
|
||||||
"microg_settings",
|
"microg_settings",
|
||||||
intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") {
|
intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") {
|
||||||
"$gmsCoreVendor.android.gms"
|
"$gmsCoreVendorGroupId.android.gms"
|
||||||
}
|
},
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
super.execute(context)
|
super.execute(context)
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.navigation
|
||||||
|
|
||||||
|
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.getInstructions
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.navigation.fingerprints.*
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
description = "Hooks the active navigation or search bar.",
|
||||||
|
dependencies = [
|
||||||
|
IntegrationsPatch::class,
|
||||||
|
NavigationBarHookResourcePatch::class,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
object NavigationBarHookPatch : BytecodePatch(
|
||||||
|
setOf(
|
||||||
|
PivotBarConstructorFingerprint,
|
||||||
|
NavigationEnumFingerprint,
|
||||||
|
PivotBarButtonsCreateDrawableViewFingerprint,
|
||||||
|
PivotBarButtonsCreateResourceViewFingerprint,
|
||||||
|
NavigationBarHookCallbackFingerprint,
|
||||||
|
ActionBarSearchResultsFingerprint,
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
internal const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/youtube/shared/NavigationBar;"
|
||||||
|
|
||||||
|
internal const val INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/integrations/youtube/shared/NavigationBar\$NavigationButton;"
|
||||||
|
|
||||||
|
override fun execute(context: BytecodeContext) {
|
||||||
|
fun MutableMethod.addHook(hook: Hook, insertPredicate: Instruction.() -> Boolean) {
|
||||||
|
val filtered = getInstructions().filter(insertPredicate)
|
||||||
|
if (filtered.isEmpty()) throw PatchException("Could not find insert indexes")
|
||||||
|
filtered.forEach {
|
||||||
|
val insertIndex = it.location.index + 2
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"invoke-static { v$register }, " +
|
||||||
|
"$INTEGRATIONS_CLASS_DESCRIPTOR->${hook.methodName}(${hook.parameters})V",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeButtonsFingerprint.apply {
|
||||||
|
resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)
|
||||||
|
}.resultOrThrow().mutableMethod.apply {
|
||||||
|
// Hook the current navigation bar enum value. Note, the 'You' tab does not have an enum value.
|
||||||
|
val navigationEnumClassName = NavigationEnumFingerprint.resultOrThrow().mutableClass.type
|
||||||
|
addHook(Hook.SET_LAST_APP_NAVIGATION_ENUM) {
|
||||||
|
opcode == Opcode.INVOKE_STATIC &&
|
||||||
|
getReference<MethodReference>()?.definingClass == navigationEnumClassName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook the creation of navigation tab views.
|
||||||
|
val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
|
||||||
|
addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{
|
||||||
|
MethodUtil.methodSignaturesMatch(
|
||||||
|
getReference<MethodReference>() ?: return@predicate false,
|
||||||
|
drawableTabMethod,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val imageResourceTabMethod = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method
|
||||||
|
addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) predicate@{
|
||||||
|
MethodUtil.methodSignaturesMatch(
|
||||||
|
getReference<MethodReference>() ?: return@predicate false,
|
||||||
|
imageResourceTabMethod,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook the search bar.
|
||||||
|
|
||||||
|
// Two different layouts are used at the hooked code.
|
||||||
|
// Insert before the first ViewGroup method call after inflating,
|
||||||
|
// so this works regardless which layout is used.
|
||||||
|
ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
|
val instructionIndex = indexOfFirstInstruction {
|
||||||
|
opcode == Opcode.INVOKE_VIRTUAL && getReference<MethodReference>()?.name == "setLayoutDirection"
|
||||||
|
}
|
||||||
|
|
||||||
|
val viewRegister = getInstruction<FiveRegisterInstruction>(instructionIndex).registerC
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
instructionIndex,
|
||||||
|
"invoke-static { v$viewRegister }, " +
|
||||||
|
"$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val hookNavigationButtonCreated: (String) -> Unit by lazy {
|
||||||
|
val method = NavigationBarHookCallbackFingerprint.resultOrThrow().mutableMethod
|
||||||
|
|
||||||
|
{ integrationsClassDescriptor ->
|
||||||
|
method.addInstruction(
|
||||||
|
0,
|
||||||
|
"invoke-static { p0, p1 }, " +
|
||||||
|
"$integrationsClassDescriptor->navigationTabCreated" +
|
||||||
|
"(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class Hook(val methodName: String, val parameters: String) {
|
||||||
|
SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"),
|
||||||
|
NAVIGATION_TAB_LOADED("navigationTabLoaded", "Landroid/view/View;"),
|
||||||
|
NAVIGATION_IMAGE_RESOURCE_TAB_LOADED("navigationImageResourceTabLoaded", "Landroid/view/View;"),
|
||||||
|
SEARCH_BAR_RESULTS_VIEW_LOADED("searchBarResultsViewLoaded", "Landroid/view/View;"),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.navigation
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
dependencies = [ResourceMappingPatch::class]
|
||||||
|
)
|
||||||
|
internal object NavigationBarHookResourcePatch : ResourcePatch() {
|
||||||
|
internal var imageOnlyTabResourceId: Long = -1
|
||||||
|
internal var actionBarSearchResultsViewMicId: Long = -1
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext) {
|
||||||
|
imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first {
|
||||||
|
it.type == "layout" && it.name == "image_only_tab"
|
||||||
|
}.id
|
||||||
|
|
||||||
|
actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first {
|
||||||
|
it.type == "layout" && it.name == "action_bar_search_results_view_mic"
|
||||||
|
}.id
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.navigation.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookResourcePatch
|
||||||
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object ActionBarSearchResultsFingerprint : LiteralValueFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
returnType = "Landroid/view/View;",
|
||||||
|
parameters = listOf("Landroid/view/LayoutInflater;"),
|
||||||
|
literalSupplier = { NavigationBarHookResourcePatch.actionBarSearchResultsViewMicId }
|
||||||
|
)
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
|
package app.revanced.patches.youtube.misc.navigation.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.youtube.layout.buttons.navigation.ResolvePivotBarFingerprintsPatch
|
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookResourcePatch
|
||||||
import app.revanced.util.patch.LiteralValueFingerprint
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves to the class found in [PivotBarConstructorFingerprint].
|
||||||
|
*/
|
||||||
internal object InitializeButtonsFingerprint : LiteralValueFingerprint(
|
internal object InitializeButtonsFingerprint : LiteralValueFingerprint(
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
parameters = listOf(),
|
parameters = listOf(),
|
||||||
literalSupplier = { ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId }
|
literalSupplier = { NavigationBarHookResourcePatch.imageOnlyTabResourceId }
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.navigation.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.buttons.navigation.NavigationButtonsPatch
|
||||||
|
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integrations method, used for callback into to other patches.
|
||||||
|
* Specifically, [NavigationButtonsPatch].
|
||||||
|
*/
|
||||||
|
internal object NavigationBarHookCallbackFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf(NavigationBarHookPatch.INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR, "Landroid/view/View;"),
|
||||||
|
customFingerprint = { methodDef, _ ->
|
||||||
|
methodDef.name == "navigationTabCreatedCallback" &&
|
||||||
|
methodDef.definingClass == NavigationBarHookPatch.INTEGRATIONS_CLASS_DESCRIPTOR
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.navigation.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves to the Enum class that looks up ordinal -> instance.
|
||||||
|
*/
|
||||||
|
internal object NavigationEnumFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.STATIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
strings = listOf(
|
||||||
|
"PIVOT_HOME",
|
||||||
|
"TAB_SHORTS",
|
||||||
|
"CREATION_TAB_LARGE",
|
||||||
|
"PIVOT_SUBSCRIPTIONS",
|
||||||
|
"TAB_ACTIVITY",
|
||||||
|
"VIDEO_LIBRARY_WHITE",
|
||||||
|
"INCOGNITO_CIRCLE"
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.navigation.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object PivotBarButtonsCreateDrawableViewFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
// Method has different number of parameters in some app targets.
|
||||||
|
// Parameters are checked in custom fingerprint.
|
||||||
|
returnType = "Landroid/view/View;",
|
||||||
|
customFingerprint = { methodDef, classDef ->
|
||||||
|
classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" &&
|
||||||
|
// Only one method has a Drawable parameter.
|
||||||
|
methodDef.parameterTypes.firstOrNull() == "Landroid/graphics/drawable/Drawable;"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.navigation.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object PivotBarButtonsCreateResourceViewFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
parameters = listOf("L", "Z", "I", "L"),
|
||||||
|
returnType = "Landroid/view/View;",
|
||||||
|
customFingerprint = { _, classDef ->
|
||||||
|
classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;"
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
|
package app.revanced.patches.youtube.misc.navigation.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
@@ -167,9 +167,24 @@
|
|||||||
<string name="revanced_custom_filter_summary_off">Custom filter is disabled</string>
|
<string name="revanced_custom_filter_summary_off">Custom filter is disabled</string>
|
||||||
<string name="revanced_custom_filter_strings_title">Custom filter</string>
|
<string name="revanced_custom_filter_strings_title">Custom filter</string>
|
||||||
<string name="revanced_custom_filter_strings_summary">List of component path builder strings to filter separated by new line</string>
|
<string name="revanced_custom_filter_strings_summary">List of component path builder strings to filter separated by new line</string>
|
||||||
<string name="revanced_custom_filter_toast_invalid_characters">Invalid custom filter (must be ASCII only): %s</string>
|
|
||||||
<string name="revanced_custom_filter_toast_invalid_syntax">Invalid custom filter: %s</string>
|
<string name="revanced_custom_filter_toast_invalid_syntax">Invalid custom filter: %s</string>
|
||||||
<string name="revanced_custom_filter_toast_reset">Custom filter reset to default</string>
|
<string name="revanced_hide_keyword_content_screen_title">Hide keyword content</string>
|
||||||
|
<string name="revanced_hide_keyword_content_screen_summary">Hide search and feed videos using keyword filters</string>
|
||||||
|
<string name="revanced_hide_keyword_content_home_title">Hide home videos by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_home_summary_on">Videos in the home tab are filtered by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_home_summary_off">Videos in the home tab are not filtered by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_subscriptions_title">Hide subscription videos by keywords</string>x
|
||||||
|
<string name="revanced_hide_keyword_content_subscriptions_summary_on">Videos in the subscriptions tab are filtered by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_subscriptions_summary_off">Videos in the subscriptions tab are not filtered by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_search_title">Hide search results by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_search_summary_on">Search results are filtered by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_search_summary_off">Search results are not filtered by keywords</string>
|
||||||
|
<string name="revanced_hide_keyword_content_phrases_title">Keywords to hide</string>
|
||||||
|
<string name="revanced_hide_keyword_content_phrases_summary">Keywords and phrases to hide, separated by new lines\n\nWords with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc)</string>
|
||||||
|
<string name="revanced_hide_keyword_content_about_title">About keyword filtering</string>
|
||||||
|
<string name="revanced_hide_keyword_content_about_summary">Home/Subscription/Search results are filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI components may not be hidden\n• Searching for a keyword may show no results</string>
|
||||||
|
<string name="revanced_hide_keyword_toast_invalid_common" formatted="false">Invalid keyword. Cannot use: \'%s\' as a filter</string>
|
||||||
|
<string name="revanced_hide_keyword_toast_invalid_length" formatted="false">Invalid keyword. \'%s\' is less than %s characters</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="ad.general.HideAdsResourcePatch">
|
<patch id="ad.general.HideAdsResourcePatch">
|
||||||
<string name="revanced_hide_general_ads_title">Hide general ads</string>
|
<string name="revanced_hide_general_ads_title">Hide general ads</string>
|
||||||
@@ -479,6 +494,12 @@
|
|||||||
<string name="revanced_hide_shorts_thanks_button_title">Hide thanks button</string>
|
<string name="revanced_hide_shorts_thanks_button_title">Hide thanks button</string>
|
||||||
<string name="revanced_hide_shorts_thanks_button_summary_on">Thanks button is hidden</string>
|
<string name="revanced_hide_shorts_thanks_button_summary_on">Thanks button is hidden</string>
|
||||||
<string name="revanced_hide_shorts_thanks_button_summary_off">Thanks button is shown</string>
|
<string name="revanced_hide_shorts_thanks_button_summary_off">Thanks button is shown</string>
|
||||||
|
<string name="revanced_hide_shorts_like_button_title">Hide like button</string>
|
||||||
|
<string name="revanced_hide_shorts_like_button_summary_on">Like button is hidden</string>
|
||||||
|
<string name="revanced_hide_shorts_like_button_summary_off">Like button is shown</string>
|
||||||
|
<string name="revanced_hide_shorts_dislike_button_title">Hide dislike button</string>
|
||||||
|
<string name="revanced_hide_shorts_dislike_button_summary_on">Dislike button is hidden</string>
|
||||||
|
<string name="revanced_hide_shorts_dislike_button_summary_off">Dislike button is shown</string>
|
||||||
<string name="revanced_hide_shorts_comments_button_title">Hide comments button</string>
|
<string name="revanced_hide_shorts_comments_button_title">Hide comments button</string>
|
||||||
<string name="revanced_hide_shorts_comments_button_summary_on">Comments button is hidden</string>
|
<string name="revanced_hide_shorts_comments_button_summary_on">Comments button is hidden</string>
|
||||||
<string name="revanced_hide_shorts_comments_button_summary_off">Comments button is shown</string>
|
<string name="revanced_hide_shorts_comments_button_summary_off">Comments button is shown</string>
|
||||||
@@ -494,6 +515,15 @@
|
|||||||
<string name="revanced_hide_shorts_channel_bar_title">Hide channel bar</string>
|
<string name="revanced_hide_shorts_channel_bar_title">Hide channel bar</string>
|
||||||
<string name="revanced_hide_shorts_channel_bar_summary_on">Channel bar is hidden</string>
|
<string name="revanced_hide_shorts_channel_bar_summary_on">Channel bar is hidden</string>
|
||||||
<string name="revanced_hide_shorts_channel_bar_summary_off">Channel bar is shown</string>
|
<string name="revanced_hide_shorts_channel_bar_summary_off">Channel bar is shown</string>
|
||||||
|
<string name="revanced_hide_shorts_video_title_title">Hide Shorts video title</string>
|
||||||
|
<string name="revanced_hide_shorts_video_title_summary_on">Title is hidden</string>
|
||||||
|
<string name="revanced_hide_shorts_video_title_summary_off">Title is shown</string>
|
||||||
|
<string name="revanced_hide_shorts_sound_metadata_label_title">Hide sound metadata label</string>
|
||||||
|
<string name="revanced_hide_shorts_sound_metadata_label_summary_on">Label is hidden</string>
|
||||||
|
<string name="revanced_hide_shorts_sound_metadata_label_summary_off">Label is shown</string>
|
||||||
|
<string name="revanced_hide_shorts_full_video_link_label_title">Hide full video link label</string>
|
||||||
|
<string name="revanced_hide_shorts_full_video_link_label_summary_on">Label is hidden</string>
|
||||||
|
<string name="revanced_hide_shorts_full_video_link_label_summary_off">Label is shown</string>
|
||||||
<string name="revanced_hide_shorts_sound_button_title">Hide sound button</string>
|
<string name="revanced_hide_shorts_sound_button_title">Hide sound button</string>
|
||||||
<string name="revanced_hide_shorts_sound_button_summary_on">Sound button is hidden</string>
|
<string name="revanced_hide_shorts_sound_button_summary_on">Sound button is hidden</string>
|
||||||
<string name="revanced_hide_shorts_sound_button_summary_off">Sound button is shown</string>
|
<string name="revanced_hide_shorts_sound_button_summary_off">Sound button is shown</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user