chore: Merge branch dev to main (#2982)

This commit is contained in:
oSumAtrIX 2024-04-21 03:47:03 +02:00 committed by GitHub
commit 381256a71a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
133 changed files with 1857 additions and 747 deletions

View file

@ -3,7 +3,7 @@ name: Pull strings
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: 0 * 1 * * - cron: 0 0 1 * *
jobs: jobs:
pull: pull:

View file

@ -1,3 +1,138 @@
# [4.7.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.15...v4.7.0-dev.16) (2024-04-21)
### Features
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([f6c3bc4](https://github.com/ReVanced/revanced-patches/commit/f6c3bc43190d33e06f49b74fc056d26da1bb014a))
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)
### Features
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)
### Features
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)
### Bug Fixes
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)
### Features
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
# [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18)
### Bug Fixes
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([9d6f305](https://github.com/ReVanced/revanced-patches/commit/9d6f305b7c923e62b89581d221fedbe1e3f81835))
# [4.7.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.9...v4.7.0-dev.10) (2024-04-17)
### Features
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([5abf894](https://github.com/ReVanced/revanced-patches/commit/5abf89444a3e6a211ec03c242eb9a7847542b08c))
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([6849393](https://github.com/ReVanced/revanced-patches/commit/684939314be3d0d43482f229b2adb033e7aa492a))
# [4.7.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.8...v4.7.0-dev.9) (2024-04-15)
### Bug Fixes
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([17e4ac9](https://github.com/ReVanced/revanced-patches/commit/17e4ac978a2f109fd62469a3163b636cd63c55ae))
# [4.7.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.7...v4.7.0-dev.8) (2024-04-14)
### Features
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([e0d2fe5](https://github.com/ReVanced/revanced-patches/commit/e0d2fe5bd2e681b9a5252a8e4ad582cc019b1606))
# [4.7.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.6...v4.7.0-dev.7) (2024-04-14)
### Features
* **YouTube - Hide layout components:** Hide playables ([8423515](https://github.com/ReVanced/revanced-patches/commit/842351548baa33737db09be1cbca9f87c1951341))
# [4.7.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.5...v4.7.0-dev.6) (2024-04-12)
### Features
* **YouTube - Hide Shorts components:** Hide `Shop`, `Location` and `Save sound to playlist` buttons ([#3018](https://github.com/ReVanced/revanced-patches/issues/3018)) ([5210ac4](https://github.com/ReVanced/revanced-patches/commit/5210ac431c191987264865bf8e789ea9f3fdd360))
# [4.7.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.4...v4.7.0-dev.5) (2024-04-10)
### Bug Fixes
* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#3007](https://github.com/ReVanced/revanced-patches/issues/3007)) ([e5848e9](https://github.com/ReVanced/revanced-patches/commit/e5848e99c4cc838595164ef673a77fe60d28086b))
# [4.7.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.3...v4.7.0-dev.4) (2024-04-09)
### Features
* **Amazon:** Add `Always allow deep-linking` patch ([#3000](https://github.com/ReVanced/revanced-patches/issues/3000)) ([a92b7fb](https://github.com/ReVanced/revanced-patches/commit/a92b7fb43c8b1b45577360cdc6d883fe2815c2f2))
* **Twitter:** Add `Sanitize sharing links` patch ([#3003](https://github.com/ReVanced/revanced-patches/issues/3003)) ([186b887](https://github.com/ReVanced/revanced-patches/commit/186b8874157eef1b882b05d491ba1d4ca2809535))
# [4.7.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.2...v4.7.0-dev.3) (2024-04-09)
### Bug Fixes
* **Tumblr - Fix old versions:** Improve reliability by removing remnances of Tumblr Live ([#2988](https://github.com/ReVanced/revanced-patches/issues/2988)) ([897b4db](https://github.com/ReVanced/revanced-patches/commit/897b4dbce984270ae1fd7de5bd30bd05153e45f2))
# [4.7.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.1...v4.7.0-dev.2) (2024-04-06)
### Features
* **Strava - Unlock subscription:** Remove compatible version constraint ([80a5599](https://github.com/ReVanced/revanced-patches/commit/80a55991683d7b22626224fa2935a5bf9bfcbfee))
# [4.7.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.6.1-dev.3...v4.7.0-dev.1) (2024-04-06)
### Features
* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#2951](https://github.com/ReVanced/revanced-patches/issues/2951)) ([9ae0650](https://github.com/ReVanced/revanced-patches/commit/9ae0650c0005d882299996aa442410bab4261395))
## [4.6.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.6.1-dev.2...v4.6.1-dev.3) (2024-04-06)
### Bug Fixes
* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#2958](https://github.com/ReVanced/revanced-patches/issues/2958)) ([82acb84](https://github.com/ReVanced/revanced-patches/commit/82acb84b5f6ff0722a2eb080b53da9dd3622502f))
## [4.6.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.6.1-dev.1...v4.6.1-dev.2) (2024-04-04)
### Bug Fixes
* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed ([#2959](https://github.com/ReVanced/revanced-patches/issues/2959)) ([b007e8e](https://github.com/ReVanced/revanced-patches/commit/b007e8e06a3afad79b40bec1c6a14604f059049c))
## [4.6.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.6.0...v4.6.1-dev.1) (2024-04-04)
### Bug Fixes
* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#2985](https://github.com/ReVanced/revanced-patches/issues/2985)) ([308de4a](https://github.com/ReVanced/revanced-patches/commit/308de4a63ca99b8d30d6b3242f98d6f0e2aefb37))
# [4.6.0](https://github.com/ReVanced/revanced-patches/compare/v4.5.0...v4.6.0) (2024-04-02) # [4.6.0](https://github.com/ReVanced/revanced-patches/compare/v4.5.0...v4.6.0) (2024-04-02)

View file

@ -28,6 +28,10 @@ public final class app/revanced/patches/all/misc/debugging/EnableAndroidDebuggin
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
} }
public final class app/revanced/patches/all/misc/hex/HexPatch : app/revanced/patches/shared/misc/hex/BaseHexPatch {
public fun <init> ()V
}
public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch { public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch {
public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch; public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch;
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
@ -152,6 +156,12 @@ public final class app/revanced/patches/all/telephony/sim/spoof/SpoofSimCountryP
public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Pair;)V public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Pair;)V
} }
public final class app/revanced/patches/amazon/deeplinking/DeepLinkingPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/amazon/deeplinking/DeepLinkingPatch;
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/backdrops/misc/pro/ProUnlockPatch : app/revanced/patcher/patch/BytecodePatch { public final class app/revanced/patches/backdrops/misc/pro/ProUnlockPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/backdrops/misc/pro/ProUnlockPatch; public static final field INSTANCE Lapp/revanced/patches/backdrops/misc/pro/ProUnlockPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
@ -663,6 +673,21 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes
protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String; protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String;
} }
public abstract class app/revanced/patches/shared/misc/hex/BaseHexPatch : app/revanced/patcher/patch/RawResourcePatch {
public fun <init> ()V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement {
public static final field Companion Lapp/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion;
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public final fun replacePattern ([B)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion {
}
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 {
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
public fun <init> (Ljava/util/Set;)V public fun <init> (Ljava/util/Set;)V
@ -699,6 +724,7 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch; public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch;
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
public final fun get (Ljava/lang/String;Ljava/lang/String;)J
} }
public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement { public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement {
@ -838,6 +864,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/ListPref
} }
public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference { public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getSelectable ()Z public final fun getSelectable ()Z
@ -1062,10 +1090,6 @@ public final class app/revanced/patches/tumblr/fixes/FixOldVersionsPatch : app/r
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/tumblr/fixes/fingerprints/HttpPathParserFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint {
public static final field INSTANCE Lapp/revanced/patches/tumblr/fixes/fingerprints/HttpPathParserFingerprint;
}
public final class app/revanced/patches/tumblr/live/DisableTumblrLivePatch : app/revanced/patcher/patch/BytecodePatch { public final class app/revanced/patches/tumblr/live/DisableTumblrLivePatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/tumblr/live/DisableTumblrLivePatch; public static final field INSTANCE Lapp/revanced/patches/tumblr/live/DisableTumblrLivePatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
@ -1200,6 +1224,12 @@ public final class app/revanced/patches/twitter/misc/links/OpenLinksWithAppChoos
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/twitter/misc/links/SanitizeSharingLinksPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/links/SanitizeSharingLinksPatch;
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/vsco/misc/pro/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch { public final class app/revanced/patches/vsco/misc/pro/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/vsco/misc/pro/UnlockProPatch; public static final field INSTANCE Lapp/revanced/patches/vsco/misc/pro/UnlockProPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
@ -1817,11 +1847,12 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
public final class app/revanced/util/BytecodeUtilsKt { public final class app/revanced/util/BytecodeUtilsKt {
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
public static final fun findIndexForIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod; public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException; public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult; public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public static final fun returnEarly (Ljava/util/List;Z)V public static final fun returnEarly (Ljava/util/List;Z)V

View file

@ -15,7 +15,7 @@ repositories {
mavenLocal() mavenLocal()
google() google()
maven { maven {
// A repository must be speficied for some reason. "registry" is a dummy. // A repository must be specified for some reason. "registry" is a dummy.
url = uri("https://maven.pkg.github.com/revanced/registry") url = uri("https://maven.pkg.github.com/revanced/registry")
credentials { credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR") username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")

View file

@ -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.6.0 version = 4.7.0-dev.16

View file

@ -0,0 +1,55 @@
package app.revanced.patches.all.misc.hex
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.registerNewPatchOption
import app.revanced.patches.shared.misc.hex.BaseHexPatch
import app.revanced.util.Utils.trimIndentMultiline
import app.revanced.patcher.patch.Patch as PatchClass
@Patch(
name = "Hex",
description = "Replaces a hexadecimal patterns of bytes of files in an APK.",
use = false,
)
@Suppress("unused")
class HexPatch : BaseHexPatch() {
// TODO: Instead of stringArrayOption, use a custom option type to work around
// https://github.com/ReVanced/revanced-library/issues/48.
// Replace the custom option type with a stringArrayOption once the issue is resolved.
private val replacementsOption by registerNewPatchOption<PatchClass<*>, List<String>>(
key = "replacements",
title = "replacements",
description = """
Hexadecimal patterns to search for and replace with another in a target file.
A pattern is a sequence of case insensitive strings, each representing hexadecimal bytes, separated by spaces.
An example pattern is 'aa 01 02 FF'.
Every pattern must be followed by a pipe ('|'), the replacement pattern,
another pipe ('|'), and the path to the file to make the changes in relative to the APK root.
The replacement pattern must have the same length as the original pattern.
Full example of a valid input:
'aa 01 02 FF|00 00 00 00|path/to/file'
""".trimIndentMultiline(),
required = true,
valueType = "StringArray",
)
override val replacements
get() = replacementsOption!!.map { from ->
val (pattern, replacementPattern, targetFilePath) = try {
from.split("|", limit = 3)
} catch (e: Exception) {
throw PatchException(
"Invalid input: $from.\n" +
"Every pattern must be followed by a pipe ('|'), " +
"the replacement pattern, another pipe ('|'), " +
"and the path to the file to make the changes in relative to the APK root. ",
)
}
Replacement(pattern, replacementPattern, targetFilePath)
}
}

View file

@ -0,0 +1,11 @@
package app.revanced.patches.amazon.deeplinking
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object DeepLinkingFingerprint : MethodFingerprint(
"Z",
parameters = listOf("L"),
accessFlags = AccessFlags.PRIVATE.value,
strings = listOf("https://www.", "android.intent.action.VIEW")
)

View file

@ -0,0 +1,28 @@
package app.revanced.patches.amazon.deeplinking
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.util.exception
@Patch(
name = "Always allow deep-linking",
description = "Open Amazon links, even if the app is not set to handle Amazon links.",
compatiblePackages = [CompatiblePackage("com.amazon.mShop.android.shopping")]
)
@Suppress("unused")
object DeepLinkingPatch : BytecodePatch(
setOf(DeepLinkingFingerprint)
) {
override fun execute(context: BytecodeContext) {
DeepLinkingFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
) ?: throw DeepLinkingFingerprint.exception
}
}

View file

@ -2,23 +2,28 @@ package app.revanced.patches.music.layout.premium
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.layout.premium.fingerprints.MembershipSettingsFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch( @Patch(
name = "Hide 'Get Music Premium' label", name = "Hide 'Get Music Premium' label",
description = "Hides the red \"Get Music Premium\" label from the account menu.", description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
) )
@Suppress("unused") @Suppress("unused")
object HideGetPremiumPatch : BytecodePatch( object HideGetPremiumPatch : BytecodePatch(
setOf(HideGetPremiumFingerprint), setOf(
HideGetPremiumFingerprint,
MembershipSettingsFingerprint,
),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
HideGetPremiumFingerprint.result?.let { HideGetPremiumFingerprint.result?.let {
@ -41,5 +46,13 @@ object HideGetPremiumPatch : BytecodePatch(
) )
} }
} ?: throw HideGetPremiumFingerprint.exception } ?: throw HideGetPremiumFingerprint.exception
MembershipSettingsFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
const/4 v0, 0x0
return-object v0
""",
) ?: throw MembershipSettingsFingerprint.exception
} }
} }

View file

@ -12,6 +12,8 @@ internal object HideGetPremiumFingerprint : MethodFingerprint(
listOf( listOf(
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.CONST_16, Opcode.CONST_16,
Opcode.GOTO,
Opcode.NOP,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
), ),
listOf("FEmusic_history", "FEmusic_offline"), listOf("FEmusic_history", "FEmusic_offline"),

View file

@ -0,0 +1,20 @@
package app.revanced.patches.music.layout.premium.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 MembershipSettingsFingerprint : MethodFingerprint(
returnType = "Ljava/lang/CharSequence;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT
)
)

View file

@ -13,6 +13,7 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
Opcode.GOTO, Opcode.GOTO,
Opcode.NOP,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID, Opcode.RETURN_VOID,
), ),

View file

@ -5,7 +5,6 @@ import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption 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.IntegrationsPatch import app.revanced.patches.music.misc.integrations.IntegrationsPatch
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 import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
@ -21,7 +20,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
CastDynamiteModuleV2Fingerprint, CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint, CastContextFetchFingerprint,
), ),
mainActivityOnCreateFingerprint = ApplicationInitFingerprint, mainActivityOnCreateFingerprint = MusicActivityOnCreateFingerprint,
integrationsPatchDependency = IntegrationsPatch::class, integrationsPatchDependency = IntegrationsPatch::class,
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch, gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
compatiblePackages = setOf(CompatiblePackage("com.google.android.apps.youtube.music")), compatiblePackages = setOf(CompatiblePackage("com.google.android.apps.youtube.music")),

View file

@ -0,0 +1,11 @@
package app.revanced.patches.music.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object MusicActivityOnCreateFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("Landroid/os/Bundle;"),
customFingerprint = { methodDef, classDef ->
methodDef.name == "onCreate" && classDef.type.endsWith("/MusicActivity;")
}
)

View file

@ -98,9 +98,9 @@ abstract class BaseGmsCoreSupportPatch(
// Verify GmsCore is installed and whitelisted for power optimizations and background usage. // Verify GmsCore is installed and whitelisted for power optimizations and background usage.
mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstructions( mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstructions(
1, // Hack to not disturb other patches (such as the YTMusic integrations patch). 0,
"invoke-static/range { p0 .. p0 }, Lapp/revanced/integrations/shared/GmsCoreSupport;->" + "invoke-static/range { p0 .. p0 }, Lapp/revanced/integrations/shared/GmsCoreSupport;->" +
"checkGmsCore(Landroid/content/Context;)V", "checkGmsCore(Landroid/app/Activity;)V",
) ?: throw mainActivityOnCreateFingerprint.exception ) ?: throw mainActivityOnCreateFingerprint.exception
// Change the vendor of GmsCore in ReVanced Integrations. // Change the vendor of GmsCore in ReVanced Integrations.

View file

@ -0,0 +1,120 @@
package app.revanced.patches.shared.misc.hex
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.RawResourcePatch
import kotlin.math.max
abstract class BaseHexPatch : RawResourcePatch() {
internal abstract val replacements: List<Replacement>
override fun execute(context: ResourceContext) {
replacements.groupBy { it.targetFilePath }.forEach { (targetFilePath, replacements) ->
val targetFile = try {
context[targetFilePath, true]
} catch (e: Exception) {
throw PatchException("Could not find target file: $targetFilePath")
}
// TODO: Use a file channel to read and write the file instead of reading the whole file into memory,
// in order to reduce memory usage.
val targetFileBytes = targetFile.readBytes()
replacements.forEach { replacement ->
replacement.replacePattern(targetFileBytes)
}
targetFile.writeBytes(targetFileBytes)
}
}
/**
* Represents a pattern to search for and its replacement pattern.
*
* @property pattern The pattern to search for.
* @property replacementPattern The pattern to replace the [pattern] with.
* @property targetFilePath The path to the file to make the changes in relative to the APK root.
*/
class Replacement(
private val pattern: String,
replacementPattern: String,
internal val targetFilePath: String,
) {
private val patternBytes = pattern.toByteArrayPattern()
private val replacementPattern = replacementPattern.toByteArrayPattern()
init {
if (this.patternBytes.size != this.replacementPattern.size) {
throw PatchException("Pattern and replacement pattern must have the same length: $pattern")
}
}
/**
* Replaces the [patternBytes] with the [replacementPattern] in the [targetFileBytes].
*
* @param targetFileBytes The bytes of the file to make the changes in.
*/
fun replacePattern(targetFileBytes: ByteArray) {
val startIndex = indexOfPatternIn(targetFileBytes)
if (startIndex == -1) {
throw PatchException("Pattern not found in target file: $pattern")
}
replacementPattern.copyInto(targetFileBytes, startIndex)
}
// TODO: Allow searching in a file channel instead of a byte array to reduce memory usage.
/**
* Returns the index of the first occurrence of [patternBytes] in the haystack
* using the Boyer-Moore algorithm.
*
* @param haystack The array to search in.
*
* @return The index of the first occurrence of the [patternBytes] in the haystack or -1
* if the [patternBytes] is not found.
*/
private fun indexOfPatternIn(haystack: ByteArray): Int {
val needle = patternBytes
val haystackLength = haystack.size - 1
val needleLength = needle.size - 1
val right = IntArray(256) { -1 }
for (i in 0 until needleLength) right[needle[i].toInt().and(0xFF)] = i
var skip: Int
for (i in 0..haystackLength - needleLength) {
skip = 0
for (j in needleLength - 1 downTo 0)
if (needle[j] != haystack[i + j]) {
skip = max(1, j - right[haystack[i + j].toInt().and(0xFF)])
break
}
if (skip == 0) return i
}
return -1
}
companion object {
/**
* Convert a string representing a pattern of hexadecimal bytes to a byte array.
*
* @return The byte array representing the pattern.
* @throws PatchException If the pattern is invalid.
*/
private fun String.toByteArrayPattern() = try {
split(" ").map { it.toInt(16).toByte() }.toByteArray()
} catch (e: NumberFormatException) {
throw PatchException(
"Could not parse pattern: $this. A pattern is a sequence of case insensitive strings " +
"representing hexadecimal bytes separated by spaces",
e,
)
}
}
}
}

View file

@ -2,17 +2,21 @@ package app.revanced.patches.shared.misc.integrations
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver
import app.revanced.patches.shared.misc.integrations.fingerprints.ReVancedUtilsPatchesVersionFingerprint
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.ClassDef import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.Method
import java.util.jar.JarFile
abstract class BaseIntegrationsPatch( abstract class BaseIntegrationsPatch(
private val hooks: Set<IntegrationsFingerprint>, private val hooks: Set<IntegrationsFingerprint>,
) : BytecodePatch(hooks) { ) : BytecodePatch(hooks + setOf(ReVancedUtilsPatchesVersionFingerprint)) {
@Deprecated( @Deprecated(
"Use the constructor without the integrationsDescriptor parameter", "Use the constructor without the integrationsDescriptor parameter",
@ -34,6 +38,46 @@ abstract class BaseIntegrationsPatch(
hooks.forEach { hook -> hooks.forEach { hook ->
hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR) hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR)
} }
// Modify Utils method to include the patches release version version.
ReVancedUtilsPatchesVersionFingerprint.resultOrThrow().mutableMethod.apply {
val manifestValue = getPatchesManifestEntry("Version")
addInstructions(
0,
"""
const-string v0, "$manifestValue"
return-object v0
""",
)
}
}
/**
* @return The value for the manifest entry,
* or "Unknown" if the entry does not exist or is blank.
*/
@Suppress("SameParameterValue")
private fun getPatchesManifestEntry(attributeKey: String) = JarFile(getCurrentJarFilePath()).use { jarFile ->
jarFile.manifest.mainAttributes.entries.firstOrNull { it.key.toString() == attributeKey }?.value?.toString()
?: "Unknown"
}
/**
* @return The file path for the jar this classfile is contained inside.
*/
private fun getCurrentJarFilePath(): String {
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
val classUrl = object {}::class.java.classLoader.getResource(className)
if (classUrl != null) {
val urlString = classUrl.toString()
if (urlString.startsWith("jar:file:")) {
val end = urlString.indexOf('!')
return urlString.substring("jar:file:".length, end)
}
}
throw IllegalStateException("Not running from inside a JAR file.")
} }
/** /**
@ -50,7 +94,7 @@ abstract class BaseIntegrationsPatch(
strings: Iterable<String>? = null, strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {}, private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {} private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : MethodFingerprint( ) : MethodFingerprint(
returnType, returnType,
accessFlags, accessFlags,
@ -59,9 +103,11 @@ abstract class BaseIntegrationsPatch(
strings, strings,
customFingerprint, customFingerprint,
) { ) {
@Deprecated("Previous constructor that is missing the insert index." + @Deprecated(
"Previous constructor that is missing the insert index." +
"Here only for binary compatibility, " + "Here only for binary compatibility, " +
"and this can be removed after the next major version update.") "and this can be removed after the next major version update.",
)
constructor( constructor(
returnType: String? = null, returnType: String? = null,
accessFlags: Int? = null, accessFlags: Int? = null,
@ -69,7 +115,7 @@ abstract class BaseIntegrationsPatch(
opcodes: Iterable<Opcode?>? = null, opcodes: Iterable<Opcode?>? = null,
strings: Iterable<String>? = null, strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {} contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : this( ) : this(
returnType, returnType,
accessFlags, accessFlags,
@ -78,7 +124,7 @@ abstract class BaseIntegrationsPatch(
strings, strings,
customFingerprint, customFingerprint,
object : IHookInsertIndexResolver {}, object : IHookInsertIndexResolver {},
contextRegisterResolver contextRegisterResolver,
) )
fun invoke(integrationsDescriptor: String) { fun invoke(integrationsDescriptor: String) {
@ -103,7 +149,7 @@ abstract class BaseIntegrationsPatch(
} }
} }
private companion object { internal companion object {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;" internal const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
} }
} }

View file

@ -0,0 +1,16 @@
package app.revanced.patches.shared.misc.integrations.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
import com.android.tools.smali.dexlib2.AccessFlags
internal object ReVancedUtilsPatchesVersionFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "getPatchesReleaseVersion" &&
classDef.type == BaseIntegrationsPatch.INTEGRATIONS_CLASS_DESCRIPTOR
}
)

View file

@ -8,19 +8,15 @@ import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
object ResourceMappingPatch : ResourcePatch() { object ResourceMappingPatch : ResourcePatch() {
internal lateinit var resourceMappings: List<ResourceElement> private val resourceMappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
private set
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors() private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT) private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
// save the file in memory to concurrently read from // sSve the file in memory to concurrently read from it.
val resourceXmlFile = context.get("res/values/public.xml").readBytes() val resourceXmlFile = context.get("res/values/public.xml").readBytes()
// create a synchronized list to store the resource mappings
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
for (threadIndex in 0 until THREAD_COUNT) { for (threadIndex in 0 until THREAD_COUNT) {
threadPoolExecutor.execute thread@{ threadPoolExecutor.execute thread@{
context.xmlEditor[resourceXmlFile.inputStream()].use { editor -> context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
@ -33,7 +29,7 @@ object ResourceMappingPatch : ResourcePatch() {
val batchStart = jobSize * threadIndex val batchStart = jobSize * threadIndex
val batchEnd = jobSize * (threadIndex + 1) val batchEnd = jobSize * (threadIndex + 1)
element@ for (i in batchStart until batchEnd) { element@ for (i in batchStart until batchEnd) {
// make sure to not go out of bounds when rounding errors occur at calculating the jobSize // Prevent out of bounds.
if (i >= resourcesLength) return@thread if (i >= resourcesLength) return@thread
val node = resources.item(i) val node = resources.item(i)
@ -46,18 +42,18 @@ object ResourceMappingPatch : ResourcePatch() {
val id = node.getAttribute("id").substring(2).toLong(16) val id = node.getAttribute("id").substring(2).toLong(16)
mappings.add(ResourceElement(typeAttribute, nameAttribute, id)) resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id))
} }
} }
} }
} }
threadPoolExecutor threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
.also { it.shutdown() }
.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
resourceMappings = mappings
} }
operator fun get(type: String, name: String) = resourceMappings.first {
it.type == type && it.name == name
}.id
data class ResourceElement(val type: String, val name: String, val id: Long) data class ResourceElement(val type: String, val name: String, val id: Long)
} }

View file

@ -16,10 +16,19 @@ import org.w3c.dom.Document
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
class NonInteractivePreference( class NonInteractivePreference(
key: String, key: String,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary", summaryKey: String? = "${key}_summary",
tag: String = "Preference", tag: String = "Preference",
val selectable: Boolean = false val selectable: Boolean = false
) : BasePreference(null, "${key}_title", summaryKey, tag) { ) : BasePreference(key, titleKey, summaryKey, tag) {
@Deprecated("Here only for binary compatibility, and should be removed after the next major version update.")
constructor(
key: String,
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
selectable: Boolean = false
) : this(key, "${key}_title", summaryKey, tag, selectable)
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) = override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply { super.serialize(ownerDocument, resourceCallback).apply {

View file

@ -11,12 +11,11 @@ object PremiumNavbarTabResourcePatch : ResourcePatch() {
internal var premiumTabId = -1L internal var premiumTabId = -1L
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
premiumTabId = ResourceMappingPatch.resourceMappings.single { premiumTabId = ResourceMappingPatch["id", "premium_tab"]
it.type == "id" && it.name == "premium_tab"
}.id
showBottomNavigationItemsTextId = ResourceMappingPatch.resourceMappings.single { showBottomNavigationItemsTextId = ResourceMappingPatch[
it.type == "bool" && it.name == "show_bottom_navigation_items_text" "bool",
}.id "show_bottom_navigation_items_text",
]
} }
} }

View file

@ -1,17 +1,16 @@
package app.revanced.patches.strava.subscription package app.revanced.patches.strava.subscription
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.strava.subscription.fingerprints.GetSubscribedFingerprint import app.revanced.patches.strava.subscription.fingerprints.GetSubscribedFingerprint
import app.revanced.util.exception
@Patch( @Patch(
name = "Unlock subscription features", name = "Unlock subscription features",
description = "Unlocks \"Routes\", \"Matched Runs\" and \"Segment Efforts\".", description = "Unlocks \"Routes\", \"Matched Runs\" and \"Segment Efforts\".",
compatiblePackages = [CompatiblePackage("com.strava", ["320.12"])] compatiblePackages = [CompatiblePackage("com.strava")],
) )
@Suppress("unused") @Suppress("unused")
object UnlockSubscriptionPatch : BytecodePatch(setOf(GetSubscribedFingerprint)) { object UnlockSubscriptionPatch : BytecodePatch(setOf(GetSubscribedFingerprint)) {

View file

@ -5,34 +5,63 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.tumblr.fixes.fingerprints.AddQueryParamFingerprint
import app.revanced.patches.tumblr.fixes.fingerprints.HttpPathParserFingerprint import app.revanced.patches.tumblr.fixes.fingerprints.HttpPathParserFingerprint
import app.revanced.util.exception import app.revanced.util.exception
@Patch( @Patch(
name = "Fix old versions", name = "Fix old versions",
description = "Fixes old versions of the app (v33.2 and earlier) breaking due to Tumblr removing remnants of Tumblr" + description = "Fixes old versions of the app (v33.2 and earlier) breaking due to Tumblr removing remnants of Tumblr" +
" Live from the API, which causes many requests to fail. This patch has no effect on newer versions of the app.", " Live from the API, which causes many requests to fail. This patch has no effect on newer versions of the app.",
compatiblePackages = [CompatiblePackage("com.tumblr")], compatiblePackages = [CompatiblePackage("com.tumblr")],
use = false, use = false,
) )
@Suppress("unused") @Suppress("unused")
object FixOldVersionsPatch : BytecodePatch( object FixOldVersionsPatch : BytecodePatch(
setOf(HttpPathParserFingerprint), setOf(HttpPathParserFingerprint, AddQueryParamFingerprint),
) { ) {
override fun execute(context: BytecodeContext) = override fun execute(context: BytecodeContext) {
val liveQueryParameters = listOf(
",?live_now",
",?live_streaming_user_id",
)
HttpPathParserFingerprint.result?.let { HttpPathParserFingerprint.result?.let {
val endIndex = it.scanResult.patternScanResult!!.endIndex val endIndex = it.scanResult.patternScanResult!!.endIndex
// Remove the live query parameters from the path when it's specified via a @METHOD annotation.
it.mutableMethod.addInstructions( for (liveQueryParameter in liveQueryParameters) {
endIndex + 1, it.mutableMethod.addInstructions(
""" endIndex + 1,
# Remove "?live_now" from the request path p2. """
# p2 = p2.replace(p1, p3) # urlPath = urlPath.replace(liveQueryParameter, "")
const-string p1, ",?live_now" const-string p1, "$liveQueryParameter"
const-string p3, "" const-string p3, ""
invoke-virtual {p2, p1, p3}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String; invoke-virtual {p2, p1, p3}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
move-result-object p2 move-result-object p2
""", """,
) )
}
} ?: throw HttpPathParserFingerprint.exception } ?: throw HttpPathParserFingerprint.exception
AddQueryParamFingerprint.result?.let {
// Remove the live query parameters when passed via a parameter which has the @Query annotation.
// e.g. an API call could be defined like this:
// @GET("api/me/info")
// ApiResponse getCurrentUserInfo(@Query("fields[blog]") String value)
// which would result in the path "api/me/inf0?fields[blog]=${value}"
// Here we make sure that this value doesn't contain the broken query parameters.
for (liveQueryParameter in liveQueryParameters) {
it.mutableMethod.addInstructions(
0,
"""
# queryParameterValue = queryParameterValue.replace(liveQueryParameter, "")
const-string v0, "$liveQueryParameter"
const-string v1, ""
invoke-virtual {p2, v0, v1}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
move-result-object p2
""",
)
}
} ?: throw AddQueryParamFingerprint.exception
}
} }

View file

@ -0,0 +1,11 @@
package app.revanced.patches.tumblr.fixes.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
// Fingerprint for the addQueryParam method from retrofit2
// https://github.com/square/retrofit/blob/trunk/retrofit/src/main/java/retrofit2/RequestBuilder.java#L186
// Injecting here allows modifying dynamically set query parameters
internal object AddQueryParamFingerprint : MethodFingerprint(
strings = listOf("Malformed URL. Base: ", ", Relative: "),
parameters = listOf("Ljava/lang/String;", "Ljava/lang/String;", "Z"),
)

View file

@ -3,13 +3,13 @@ package app.revanced.patches.tumblr.fixes.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
// Fingerprint for the parseHttpMethodAndPath from retrofit2 // Fingerprint for the parseHttpMethodAndPath method from retrofit2
// https://github.com/square/retrofit/blob/ebf87b10997e2136af4d335276fa950221852c64/retrofit/src/main/java/retrofit2/RequestFactory.java#L270-L302 // https://github.com/square/retrofit/blob/ebf87b10997e2136af4d335276fa950221852c64/retrofit/src/main/java/retrofit2/RequestFactory.java#L270-L302
// Injecting here allows modifying the path/query params of API endpoints defined via annotations // Injecting here allows modifying the path/query params of API endpoints defined via annotations
object HttpPathParserFingerprint : MethodFingerprint( internal object HttpPathParserFingerprint : MethodFingerprint(
strings = listOf("Only one HTTP method is allowed. Found: %s and %s."), strings = listOf("Only one HTTP method is allowed. Found: %s and %s."),
opcodes = listOf( opcodes = listOf(
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.IPUT_BOOLEAN Opcode.IPUT_BOOLEAN,
) ),
) )

View file

@ -0,0 +1,29 @@
package app.revanced.patches.twitter.misc.links
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.twitter.misc.links.fingerprints.SanitizeSharingLinksFingerprint
import app.revanced.util.exception
@Patch(
name = "Sanitize sharing links",
description = "Removes the tracking query parameters from links before they are shared.",
compatiblePackages = [CompatiblePackage("com.twitter.android")],
)
object SanitizeSharingLinksPatch : BytecodePatch(
setOf(SanitizeSharingLinksFingerprint),
) {
override fun execute(context: BytecodeContext) {
SanitizeSharingLinksFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
# Method takes in a link (string, param 0) and then appends the tracking query params,
# so all we need to do is return back the passed-in string
return-object p0
""",
) ?: throw SanitizeSharingLinksFingerprint.exception
}
}

View file

@ -0,0 +1,8 @@
package app.revanced.patches.twitter.misc.links.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object SanitizeSharingLinksFingerprint : MethodFingerprint(
strings = listOf("<this>", "shareParam", "sessionToken"),
returnType = "Ljava/lang/String;",
)

View file

@ -42,7 +42,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View file

@ -14,8 +14,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
LithoFilterPatch::class, LithoFilterPatch::class,
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
object HideAdsResourcePatch : ResourcePatch() { object HideAdsResourcePatch : ResourcePatch() {
private const val FILTER_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR =
@ -30,16 +30,16 @@ object HideAdsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_general_ads"), SwitchPreference("revanced_hide_general_ads"),
SwitchPreference("revanced_hide_fullscreen_ads"), SwitchPreference("revanced_hide_fullscreen_ads"),
SwitchPreference("revanced_hide_buttoned_ads"), SwitchPreference("revanced_hide_buttoned_ads"),
SwitchPreference("revanced_hide_paid_content_ads"), SwitchPreference("revanced_hide_paid_promotion_label"),
SwitchPreference("revanced_hide_self_sponsor_ads"), SwitchPreference("revanced_hide_self_sponsor_ads"),
SwitchPreference("revanced_hide_products_banner"), SwitchPreference("revanced_hide_products_banner"),
SwitchPreference("revanced_hide_shopping_links"), SwitchPreference("revanced_hide_shopping_links"),
SwitchPreference("revanced_hide_web_search_results"), SwitchPreference("revanced_hide_web_search_results"),
SwitchPreference("revanced_hide_merchandise_banners") SwitchPreference("revanced_hide_merchandise_banners"),
) )
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id adAttributionId = ResourceMappingPatch["id", "ad_attribution"]
} }
} }

View file

@ -36,7 +36,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -41,7 +41,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -29,7 +29,9 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View file

@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -35,7 +35,9 @@ import app.revanced.util.resultOrThrow
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View file

@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -36,7 +36,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
], ],

View file

@ -20,7 +20,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
dependencies = [ dependencies = [
IntegrationsPatch::class, IntegrationsPatch::class,
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
SwipeControlsResourcePatch::class SwipeControlsResourcePatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@ -42,17 +42,22 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43", // 19.12.x has an issue with opening YT using external links,
] // and the app then crashes if double tap to skip forward/back is immediately used.
// The stack trace shows a call coming from integrations SwipeController,
// but it may be a bug in YT itself as other target versions do not have this issue.
],
),
],
) )
@Suppress("unused") @Suppress("unused")
object SwipeControlsBytecodePatch : BytecodePatch( object SwipeControlsBytecodePatch : BytecodePatch(
setOf( setOf(
MainActivityFingerprint, MainActivityFingerprint,
SwipeControlsHostActivityFingerprint SwipeControlsHostActivityFingerprint,
) ),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
@ -74,7 +79,7 @@ object SwipeControlsBytecodePatch : BytecodePatch(
accessFlags and AccessFlags.FINAL.value.inv(), accessFlags and AccessFlags.FINAL.value.inv(),
annotations, annotations,
hiddenApiRestrictions, hiddenApiRestrictions,
implementation implementation,
).toMutable() ).toMutable()
} }
} }

View file

@ -24,6 +24,7 @@ internal object SwipeControlsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_swipe_press_to_engage"), SwitchPreference("revanced_swipe_press_to_engage"),
SwitchPreference("revanced_swipe_haptic_feedback"), SwitchPreference("revanced_swipe_haptic_feedback"),
SwitchPreference("revanced_swipe_save_and_restore_brightness"), SwitchPreference("revanced_swipe_save_and_restore_brightness"),
SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER), TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER),

View file

@ -40,7 +40,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
], ],

View file

@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -14,7 +14,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource import app.revanced.util.indexOfIdResourceOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.Instruction 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.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@ -49,27 +49,29 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
] ],
),
],
) )
@Suppress("unused") @Suppress("unused")
object HideAutoplayButtonPatch : BytecodePatch( object HideAutoplayButtonPatch : BytecodePatch(
setOf(LayoutConstructorFingerprint) setOf(LayoutConstructorFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_autoplay_button") SwitchPreference("revanced_hide_autoplay_button"),
) )
LayoutConstructorFingerprint.result?.mutableMethod?.apply { LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions val layoutGenMethodInstructions = implementation!!.instructions
// resolve the offsets of where to insert the branch instructions and ... // resolve the offsets of where to insert the branch instructions and ...
val insertIndex = findIndexForIdResource("autonav_preview_stub") val insertIndex = indexOfIdResourceOrThrow("autonav_preview_stub")
// where to branch away // where to branch away
val branchIndex = val branchIndex =
@ -90,7 +92,7 @@ object HideAutoplayButtonPatch : BytecodePatch(
move-result v$clobberRegister move-result v$clobberRegister
if-eqz v$clobberRegister, :hidden if-eqz v$clobberRegister, :hidden
""", """,
ExternalLabel("hidden", jumpInstruction) ExternalLabel("hidden", jumpInstruction),
) )
} ?: throw LayoutConstructorFingerprint.exception } ?: throw LayoutConstructorFingerprint.exception
} }

View file

@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.Opcode
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -47,7 +47,9 @@ 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.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View file

@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -38,7 +38,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object AlbumCardsResourcePatch : ResourcePatch() { internal object AlbumCardsResourcePatch : ResourcePatch() {
@ -22,11 +22,9 @@ internal object AlbumCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences( SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_album_cards") SwitchPreference("revanced_hide_album_cards"),
) )
albumCardId = ResourceMappingPatch.resourceMappings.single { albumCardId = ResourceMappingPatch["layout", "album_card"]
it.type == "layout" && it.name == "album_card"
}.id
} }
} }

View file

@ -1,73 +1,13 @@
package app.revanced.patches.youtube.layout.hide.breakingnews package app.revanced.patches.youtube.layout.hide.breakingnews
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext 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.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patches.youtube.layout.hide.general.HideLayoutComponentsPatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.layout.hide.breakingnews.fingerprints.BreakingNewsFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch( @Deprecated("This patch has been merged to HideLayoutComponentsPatch.")
name = "Hide breaking news shelf",
description = "Adds an option to hide the breaking news shelf on the homepage tab.",
dependencies = [
IntegrationsPatch::class,
BreakingNewsResourcePatch::class
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34",
"19.02.39",
"19.03.36",
"19.04.38",
"19.05.36",
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
]
)
@Suppress("unused")
object BreakingNewsPatch : BytecodePatch( object BreakingNewsPatch : BytecodePatch(
setOf(BreakingNewsFingerprint) dependencies = setOf(HideLayoutComponentsPatch::class),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
BreakingNewsFingerprint.result?.let {
val insertIndex = it.scanResult.patternScanResult!!.endIndex - 1
val moveResultIndex = insertIndex - 1
it.mutableMethod.apply {
val breakingNewsViewRegister =
getInstruction<OneRegisterInstruction>(moveResultIndex).registerA
addInstruction(
insertIndex,
"""
invoke-static {v$breakingNewsViewRegister},
Lapp/revanced/integrations/youtube/patches/HideBreakingNewsPatch;
->
hideBreakingNews(Landroid/view/View;)V
"""
)
}
} ?: throw BreakingNewsFingerprint.exception
} }
} }

View file

@ -1,32 +0,0 @@
package app.revanced.patches.youtube.layout.hide.breakingnews
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch(
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
],
)
internal object BreakingNewsResourcePatch : ResourcePatch() {
internal var horizontalCardListId: Long = -1
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_breaking_news")
)
horizontalCardListId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "horizontal_card_list"
}.id
}
}

View file

@ -1,20 +0,0 @@
package app.revanced.patches.youtube.layout.hide.breakingnews.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.breakingnews.BreakingNewsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object BreakingNewsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IPUT_OBJECT,
),
literalSupplier = { BreakingNewsResourcePatch.horizontalCardListId }
)

View file

@ -38,7 +38,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]
@ -55,9 +57,10 @@ object CommentsPatch : ResourcePatch() {
PreferenceScreen( PreferenceScreen(
"revanced_comments_screen", "revanced_comments_screen",
preferences = setOf( preferences = setOf(
SwitchPreference("revanced_hide_comments_section"), SwitchPreference("revanced_hide_preview_comment"),
SwitchPreference("revanced_hide_preview_comment") SwitchPreference("revanced_hide_comments_section")
) ),
sorting = PreferenceScreen.Sorting.UNSORTED
) )
) )

View file

@ -38,7 +38,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object CrowdfundingBoxResourcePatch : ResourcePatch() { internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
@ -22,11 +22,12 @@ internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences( SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_crowdfunding_box") SwitchPreference("revanced_hide_crowdfunding_box"),
) )
crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single { crowdfundingBoxId = ResourceMappingPatch[
it.type == "layout" && it.name == "donation_companion" "layout",
}.id "donation_companion",
]
} }
} }

View file

@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object HideEndscreenCardsResourcePatch : ResourcePatch() { internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
@ -24,15 +24,13 @@ internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_endscreen_cards") SwitchPreference("revanced_hide_endscreen_cards"),
) )
fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single { fun idOf(name: String) = ResourceMappingPatch["layout", "endscreen_element_layout_$name"]
it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id
layoutCircle = findEndscreenResourceId("circle") layoutCircle = idOf("circle")
layoutIcon = findEndscreenResourceId("icon") layoutIcon = idOf("icon")
layoutVideo = findEndscreenResourceId("video") layoutVideo = idOf("video")
} }
} }

View file

@ -38,7 +38,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -25,15 +25,12 @@ internal object HideFilterBarResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_filter_bar_feed_in_feed"), SwitchPreference("revanced_hide_filter_bar_feed_in_feed"),
SwitchPreference("revanced_hide_filter_bar_feed_in_search"), SwitchPreference("revanced_hide_filter_bar_feed_in_search"),
SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"), SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"),
) ),
) ),
) )
relatedChipCloudMarginId = "related_chip_cloud_reduced_margins".layoutResourceId("layout") relatedChipCloudMarginId = ResourceMappingPatch["layout", "related_chip_cloud_reduced_margins"]
filterBarHeightId = "filter_bar_height".layoutResourceId() filterBarHeightId = ResourceMappingPatch["dimen", "filter_bar_height"]
barContainerHeightId = "bar_container_height".layoutResourceId() barContainerHeightId = ResourceMappingPatch["dimen", "bar_container_height"]
} }
private fun String.layoutResourceId(type: String = "dimen") =
ResourceMappingPatch.resourceMappings.single { it.type == type && it.name == this }.id
} }

View file

@ -34,7 +34,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -1,7 +1,6 @@
package app.revanced.patches.youtube.layout.hide.floatingmicrophone package app.revanced.patches.youtube.layout.hide.floatingmicrophone
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
@ -13,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() { internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
internal var fabButtonId: Long = -1 internal var fabButtonId: Long = -1
@ -23,10 +22,9 @@ internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences( SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_hide_floating_microphone_button") SwitchPreference("revanced_hide_floating_microphone_button"),
) )
fabButtonId = ResourceMappingPatch.resourceMappings.find { it.type == "id" && it.name == "fab" }?.id fabButtonId = ResourceMappingPatch["id", "fab"]
?: throw PatchException("Can not find required fab button resource id")
} }
} }

View file

@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -1,6 +1,7 @@
package app.revanced.patches.youtube.layout.hide.general package app.revanced.patches.youtube.layout.hide.general
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -11,22 +12,19 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch 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.*
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.Sorting import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.layout.hide.general.fingerprints.HideShowMoreButtonFingerprint
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
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.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.resultOrThrow 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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@Patch( @Patch(
@ -36,8 +34,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
LithoFilterPatch::class, LithoFilterPatch::class,
SettingsPatch::class, SettingsPatch::class,
AddResourcesPatch::class, AddResourcesPatch::class,
HideLayoutComponentsResourcePatch::class,
NavigationBarHookPatch::class, NavigationBarHookPatch::class,
PlayerTypeHookPatch::class // Used by Keyword Content filter.
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@ -59,14 +57,16 @@ 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.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],
) )
@Suppress("unused") @Suppress("unused")
object HideLayoutComponentsPatch : BytecodePatch( object HideLayoutComponentsPatch : BytecodePatch(
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint), setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint, HideShowMoreButtonFingerprint),
) { ) {
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR = private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/components/LayoutComponentsFilter;" "Lapp/revanced/integrations/youtube/patches/components/LayoutComponentsFilter;"
@ -103,6 +103,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_info_panels"), SwitchPreference("revanced_hide_info_panels"),
SwitchPreference("revanced_hide_join_membership_button"), SwitchPreference("revanced_hide_join_membership_button"),
SwitchPreference("revanced_hide_medical_panels"), SwitchPreference("revanced_hide_medical_panels"),
SwitchPreference("revanced_hide_playables"),
SwitchPreference("revanced_hide_quick_actions"), SwitchPreference("revanced_hide_quick_actions"),
SwitchPreference("revanced_hide_related_videos"), SwitchPreference("revanced_hide_related_videos"),
SwitchPreference("revanced_hide_subscribers_community_guidelines"), SwitchPreference("revanced_hide_subscribers_community_guidelines"),
@ -115,6 +116,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_compact_banner"), SwitchPreference("revanced_hide_compact_banner"),
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_horizontal_shelves"),
SwitchPreference("revanced_hide_image_shelf"), SwitchPreference("revanced_hide_image_shelf"),
SwitchPreference("revanced_hide_latest_posts_ads"), SwitchPreference("revanced_hide_latest_posts_ads"),
SwitchPreference("revanced_hide_mix_playlists"), SwitchPreference("revanced_hide_mix_playlists"),
@ -122,9 +124,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_notify_me_button"), SwitchPreference("revanced_hide_notify_me_button"),
SwitchPreference("revanced_hide_search_result_recommendations"), SwitchPreference("revanced_hide_search_result_recommendations"),
SwitchPreference("revanced_hide_search_result_shelf_header"), SwitchPreference("revanced_hide_search_result_shelf_header"),
) SwitchPreference("revanced_hide_show_more_button"),
SettingsPatch.PreferenceScreen.FEED.addPreferences(
PreferenceScreen( PreferenceScreen(
key = "revanced_hide_keyword_content_screen", key = "revanced_hide_keyword_content_screen",
sorting = Sorting.UNSORTED, sorting = Sorting.UNSORTED,
@ -133,9 +133,9 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_keyword_content_subscriptions"), SwitchPreference("revanced_hide_keyword_content_subscriptions"),
SwitchPreference("revanced_hide_keyword_content_search"), SwitchPreference("revanced_hide_keyword_content_search"),
TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE), TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
NonInteractivePreference("revanced_hide_keyword_content_about") NonInteractivePreference("revanced_hide_keyword_content_about"),
) ),
) ),
) )
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences( SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
@ -203,5 +203,24 @@ object HideLayoutComponentsPatch : BytecodePatch(
} }
// endregion // endregion
// region Show more button
HideShowMoreButtonFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val moveRegisterIndex = it.scanResult.patternScanResult!!.endIndex
val viewRegister =
getInstruction<OneRegisterInstruction>(moveRegisterIndex).registerA
val insertIndex = moveRegisterIndex + 1
addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, " +
"$LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->hideShowMoreButton(Landroid/view/View;)V",
)
}
}
// endregion
} }
} }

View file

@ -0,0 +1,26 @@
package app.revanced.patches.youtube.layout.hide.general
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch(
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class,
],
)
internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
internal var expandButtonDownId: Long = -1
override fun execute(context: ResourceContext) {
expandButtonDownId = ResourceMappingPatch[
"layout",
"expand_button_down",
]
}
}

View file

@ -0,0 +1,15 @@
package app.revanced.patches.youtube.layout.hide.general.fingerprints
import app.revanced.patches.youtube.layout.hide.general.HideLayoutComponentsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode
internal object HideShowMoreButtonFingerprint : LiteralValueFingerprint(
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT
),
literalSupplier = { HideLayoutComponentsResourcePatch.expandButtonDownId }
)

View file

@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
object HideInfocardsResourcePatch : ResourcePatch() { object HideInfocardsResourcePatch : ResourcePatch() {
@ -22,11 +22,12 @@ object HideInfocardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_info_cards") SwitchPreference("revanced_hide_info_cards"),
) )
drawerResourceId = ResourceMappingPatch.resourceMappings.single { drawerResourceId = ResourceMappingPatch[
it.type == "id" && it.name == "info_cards_drawer_header" "id",
}.id "info_cards_drawer_header",
]
} }
} }

View file

@ -1,65 +1,12 @@
package app.revanced.patches.youtube.layout.hide.loadmorebutton package app.revanced.patches.youtube.layout.hide.loadmorebutton
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext 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.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patches.youtube.layout.hide.general.HideLayoutComponentsPatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.layout.hide.loadmorebutton.fingerprints.HideLoadMoreButtonFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch( @Deprecated("This patch class has been merged into HideLayoutComponentsPatch.")
name = "Hide \'Load more\' button",
description = "Adds an option to hide the button under videos that loads similar videos.",
dependencies = [HideLoadMoreButtonResourcePatch::class],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
"18.43.45",
"18.44.41",
"18.45.43",
"18.48.39",
"18.49.37",
"19.01.34",
"19.02.39",
"19.03.36",
"19.04.38",
"19.05.36",
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
]
)
@Suppress("unused")
object HideLoadMoreButtonPatch : BytecodePatch( object HideLoadMoreButtonPatch : BytecodePatch(
setOf(HideLoadMoreButtonFingerprint) dependencies = setOf(HideLayoutComponentsPatch::class)
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = override fun execute(context: BytecodeContext) {}
"Lapp/revanced/integrations/youtube/patches/HideLoadMoreButtonPatch;"
override fun execute(context: BytecodeContext) {
HideLoadMoreButtonFingerprint.result?.let {
it.mutableMethod.apply {
val moveRegisterIndex = it.scanResult.patternScanResult!!.endIndex
val viewRegister =
getInstruction<OneRegisterInstruction>(moveRegisterIndex).registerA
val insertIndex = moveRegisterIndex + 1
addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->hideLoadMoreButton(Landroid/view/View;)V"
)
}
} ?: throw HideLoadMoreButtonFingerprint.exception
}
} }

View file

@ -1,32 +0,0 @@
package app.revanced.patches.youtube.layout.hide.loadmorebutton
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch(
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
]
)
internal object HideLoadMoreButtonResourcePatch : ResourcePatch() {
internal var expandButtonDownId: Long = -1
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_load_more_button")
)
expandButtonDownId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "expand_button_down"
}.id
}
}

View file

@ -1,15 +0,0 @@
package app.revanced.patches.youtube.layout.hide.loadmorebutton.fingerprints
import app.revanced.patches.youtube.layout.hide.loadmorebutton.HideLoadMoreButtonResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode
internal object HideLoadMoreButtonFingerprint : LiteralValueFingerprint(
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT
),
literalSupplier = { HideLoadMoreButtonResourcePatch.expandButtonDownId }
)

View file

@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]
@ -64,6 +66,7 @@ object HidePlayerFlyoutMenuPatch : ResourcePatch() {
SwitchPreference("revanced_hide_player_flyout_report"), SwitchPreference("revanced_hide_player_flyout_report"),
SwitchPreference("revanced_hide_player_flyout_help"), SwitchPreference("revanced_hide_player_flyout_help"),
SwitchPreference("revanced_hide_player_flyout_speed"), SwitchPreference("revanced_hide_player_flyout_speed"),
SwitchPreference("revanced_hide_player_flyout_lock_screen"),
SwitchPreference("revanced_hide_player_flyout_more_info"), SwitchPreference("revanced_hide_player_flyout_more_info"),
SwitchPreference("revanced_hide_player_flyout_audio_track"), SwitchPreference("revanced_hide_player_flyout_audio_track"),
SwitchPreference("revanced_hide_player_flyout_watch_in_vr"), SwitchPreference("revanced_hide_player_flyout_watch_in_vr"),

View file

@ -36,7 +36,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -41,7 +41,9 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -1,8 +1,5 @@
package app.revanced.patches.youtube.layout.hide.shorts package app.revanced.patches.youtube.layout.hide.shorts
import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource
import app.revanced.util.injectHideViewCall
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -15,7 +12,9 @@ import app.revanced.patches.youtube.layout.hide.shorts.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
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.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.util.exception
import app.revanced.util.indexOfIdResourceOrThrow
import app.revanced.util.injectHideViewCall
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.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@ -29,11 +28,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
HideShortsComponentsResourcePatch::class, HideShortsComponentsResourcePatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
NavigationBarHookPatch::class, NavigationBarHookPatch::class,
PlayerTypeHookPatch::class
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.youtube", [ "com.google.android.youtube",
[
"18.32.39", "18.32.39",
"18.37.36", "18.37.36",
"18.38.44", "18.38.44",
@ -50,10 +49,12 @@ 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.38",
] "19.10.39",
) "19.11.43",
] ],
),
],
) )
@Suppress("unused") @Suppress("unused")
object HideShortsComponentsPatch : BytecodePatch( object HideShortsComponentsPatch : BytecodePatch(
@ -62,8 +63,8 @@ object HideShortsComponentsPatch : BytecodePatch(
ReelConstructorFingerprint, ReelConstructorFingerprint,
BottomNavigationBarFingerprint, BottomNavigationBarFingerprint,
RenderBottomNavigationBarParentFingerprint, RenderBottomNavigationBarParentFingerprint,
SetPivotBarVisibilityParentFingerprint SetPivotBarVisibilityParentFingerprint,
) ),
) { ) {
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;" private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
@ -81,7 +82,7 @@ object HideShortsComponentsPatch : BytecodePatch(
insertIndex, insertIndex,
viewRegister, viewRegister,
FILTER_CLASS_DESCRIPTOR, FILTER_CLASS_DESCRIPTOR,
"hideShortsShelf" "hideShortsShelf",
) )
} }
} // Do not throw an exception if not resolved. } // Do not throw an exception if not resolved.
@ -95,7 +96,6 @@ object HideShortsComponentsPatch : BytecodePatch(
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) } ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
} ?: throw CreateShortsButtonsFingerprint.exception } ?: throw CreateShortsButtonsFingerprint.exception
// endregion // endregion
// region Hide the Shorts buttons in newer versions of YouTube. // region Hide the Shorts buttons in newer versions of YouTube.
@ -108,8 +108,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to get the pivotBar view. // Hook to get the pivotBar view.
SetPivotBarVisibilityParentFingerprint.result?.let { SetPivotBarVisibilityParentFingerprint.result?.let {
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) {
throw SetPivotBarVisibilityFingerprint.exception throw SetPivotBarVisibilityFingerprint.exception
}
SetPivotBarVisibilityFingerprint.result!!.let { result -> SetPivotBarVisibilityFingerprint.result!!.let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
@ -118,7 +119,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction( addInstruction(
insertIndex, insertIndex,
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" + "sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
) )
} }
} }
@ -126,8 +127,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to hide the navigation bar when Shorts are being played. // Hook to hide the navigation bar when Shorts are being played.
RenderBottomNavigationBarParentFingerprint.result?.let { RenderBottomNavigationBarParentFingerprint.result?.let {
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) {
throw RenderBottomNavigationBarFingerprint.exception throw RenderBottomNavigationBarFingerprint.exception
}
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply { RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V") addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
@ -144,7 +146,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction( addInstruction(
insertIndex, insertIndex,
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" + "invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;" "hideNavigationBar(Landroid/view/View;)Landroid/view/View;",
) )
} }
} ?: throw BottomNavigationBarFingerprint.exception } ?: throw BottomNavigationBarFingerprint.exception
@ -152,14 +154,14 @@ object HideShortsComponentsPatch : BytecodePatch(
// endregion // endregion
} }
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) { private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"), COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
REMIX("reel_dyn_remix", "hideShortsRemixButton"), REMIX("reel_dyn_remix", "hideShortsRemixButton"),
SHARE("reel_dyn_share", "hideShortsShareButton"); SHARE("reel_dyn_share", "hideShortsShareButton"),
;
fun injectHideCall(method: MutableMethod) { fun injectHideCall(method: MutableMethod) {
val referencedIndex = method.findIndexForIdResource(resourceName) val referencedIndex = method.indexOfIdResourceOrThrow(resourceName)
val setIdIndex = referencedIndex + 1 val setIdIndex = referencedIndex + 1
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC

View file

@ -34,10 +34,14 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_sound_button"), SwitchPreference("revanced_hide_shorts_sound_button"),
// Everything else. // Everything else.
SwitchPreference("revanced_hide_shorts_thanks_button"),
SwitchPreference("revanced_hide_shorts_join_button"), SwitchPreference("revanced_hide_shorts_join_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button"), SwitchPreference("revanced_hide_shorts_subscribe_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button_paused"), SwitchPreference("revanced_hide_shorts_paused_overlay_buttons"),
SwitchPreference("revanced_hide_shorts_save_sound_button"),
SwitchPreference("revanced_hide_shorts_shop_button"),
SwitchPreference("revanced_hide_shorts_tagged_products"),
SwitchPreference("revanced_hide_shorts_search_suggestions"),
SwitchPreference("revanced_hide_shorts_location_label"),
SwitchPreference("revanced_hide_shorts_channel_bar"), SwitchPreference("revanced_hide_shorts_channel_bar"),
SwitchPreference("revanced_hide_shorts_info_panel"), SwitchPreference("revanced_hide_shorts_info_panel"),
SwitchPreference("revanced_hide_shorts_full_video_link_label"), SwitchPreference("revanced_hide_shorts_full_video_link_label"),
@ -46,15 +50,19 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_navigation_bar"), SwitchPreference("revanced_hide_shorts_navigation_bar"),
) )
ResourceMappingPatch.resourceMappings.find { reelPlayerRightCellButtonHeight = ResourceMappingPatch[
it.type == "layout" && it.name == "reel_multiple_items_shelf" "dimen",
}?.also { "reel_player_right_cell_button_height",
reelMultipleItemShelfId = it.id ]
}
reelPlayerRightCellButtonHeight = // Resource not present in new versions of the app.
ResourceMappingPatch.resourceMappings.single { try {
it.type == "dimen" && it.name == "reel_player_right_cell_button_height" ResourceMappingPatch[
}.id "dimen",
"reel_player_right_cell_button_height",
]
} catch (e: NoSuchElementException) {
return
}.also { reelPlayerRightCellButtonHeight = it }
} }
} }

View file

@ -1,13 +1,10 @@
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint( internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, // YT 19.12.x moved this code inside another method, and each method has different parameters.
returnType = "V", returnType = "V",
parameters = listOf("Z", "Z", "L"),
literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight } literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight }
) )

View file

@ -33,7 +33,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() { internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
@ -22,11 +22,12 @@ internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_suggested_video_end_screen") SwitchPreference("revanced_disable_suggested_video_end_screen"),
) )
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch.resourceMappings.single { sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch[
it.type == "layout" && it.name == "size_adjustable_lite_autonav_overlay" "layout",
}.id "size_adjustable_lite_autonav_overlay",
]
} }
} }

View file

@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -30,7 +30,9 @@ import org.w3c.dom.Element
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View file

@ -10,7 +10,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch( @Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class] dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
) )
internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() { internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
internal var scrimOverlayId = -1L internal var scrimOverlayId = -1L
@ -19,11 +19,12 @@ internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER) TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER),
) )
scrimOverlayId = ResourceMappingPatch.resourceMappings.single { scrimOverlayId = ResourceMappingPatch[
it.type == "id" && it.name == "scrim_overlay" "id",
}.id "scrim_overlay",
]
} }
} }

View file

@ -64,7 +64,9 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -12,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
@Patch( @Patch(
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() { internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
internal var oldUIDislikeId: Long = -1 internal var oldUIDislikeId: Long = -1
@ -25,11 +25,12 @@ internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
key = "revanced_settings_screen_09", key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title", titleKey = "revanced_ryd_settings_title",
summaryKey = null, summaryKey = null,
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent") intent = SettingsPatch.newIntent("revanced_ryd_settings_intent"),
) )
oldUIDislikeId = ResourceMappingPatch.resourceMappings.single { oldUIDislikeId = ResourceMappingPatch[
it.type == "id" && it.name == "dislike_button" "id",
}.id "dislike_button",
]
} }
} }

View file

@ -39,7 +39,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -15,18 +15,18 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
fun findColorResource(resourceName: String): Long { reelTimeBarPlayedColorId = ResourceMappingPatch[
return ResourceMappingPatch.resourceMappings "color",
.find { it.type == "color" && it.name == resourceName }?.id "reel_time_bar_played_color",
?: throw PatchException("Could not find color resource: $resourceName") ]
} inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch[
"color",
reelTimeBarPlayedColorId = "inline_time_bar_colorized_bar_played_color_dark",
findColorResource("reel_time_bar_played_color") ]
inlineTimeBarColorizedBarPlayedColorDarkId = inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch[
findColorResource("inline_time_bar_colorized_bar_played_color_dark") "color",
inlineTimeBarPlayedNotHighlightedColorId = "inline_time_bar_played_not_highlighted_color",
findColorResource("inline_time_bar_played_not_highlighted_color") ]
// Edit the resume playback drawable and replace the progress bar with a custom drawable // Edit the resume playback drawable and replace the progress bar with a custom drawable
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor -> context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
@ -39,10 +39,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
} }
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
val replacementNode = val replacementNode = document.createElement(
document.createElement( "app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable", )
)
scaleNode.replaceChild(replacementNode, shapeNode) scaleNode.replaceChild(replacementNode, shapeNode)
} }
} }

View file

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.layout.sponsorblock package app.revanced.patches.youtube.layout.sponsorblock
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
@ -25,6 +24,7 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.* import com.android.tools.smali.dexlib2.iface.instruction.*
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.", description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.",
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.youtube", [ "com.google.android.youtube",
[
"18.48.39", "18.48.39",
"18.49.37", "18.49.37",
"19.01.34", "19.01.34",
@ -48,9 +49,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
],
),
], ],
dependencies = [ dependencies = [
IntegrationsPatch::class, IntegrationsPatch::class,
@ -60,8 +63,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
// Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts. // Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts.
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
PlayerControlsBytecodePatch::class, PlayerControlsBytecodePatch::class,
SponsorBlockResourcePatch::class SponsorBlockResourcePatch::class,
] ],
) )
@Suppress("unused") @Suppress("unused")
object SponsorBlockBytecodePatch : BytecodePatch( object SponsorBlockBytecodePatch : BytecodePatch(
@ -69,8 +72,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
SeekbarFingerprint, SeekbarFingerprint,
AppendTimeFingerprint, AppendTimeFingerprint,
LayoutConstructorFingerprint, LayoutConstructorFingerprint,
AutoRepeatParentFingerprint AutoRepeatParentFingerprint,
) ),
) { ) {
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;" "Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
@ -83,8 +86,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
LayoutConstructorFingerprint.result?.let { LayoutConstructorFingerprint.result?.let {
if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) {
throw ControlsOverlayFingerprint.exception throw ControlsOverlayFingerprint.exception
}
} ?: throw LayoutConstructorFingerprint.exception } ?: throw LayoutConstructorFingerprint.exception
/* /*
@ -93,7 +97,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
with(VideoInformationPatch) { with(VideoInformationPatch) {
videoTimeHook( videoTimeHook(
INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR,
"setVideoTime" "setVideoTime",
) )
} }
@ -121,7 +125,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
moveRectangleToRegisterIndex + 1, moveRectangleToRegisterIndex + 1,
"invoke-static/range {p0 .. p0}, " + "invoke-static/range {p0 .. p0}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V" "$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V",
) )
for ((index, instruction) in seekbarMethodInstructions.withIndex()) { for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
@ -136,7 +140,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
insertIndex, insertIndex,
"invoke-static {v${invokeInstruction.registerC}}, " + "invoke-static {v${invokeInstruction.registerC}}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V" "$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
) )
break break
} }
@ -154,7 +158,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
} }
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
i, i,
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V" "invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V",
) )
break break
@ -166,9 +170,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
val controlsLayoutStubResourceId = val controlsLayoutStubResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id ResourceMappingPatch["id", "controls_layout_stub"]
val zoomOverlayResourceId = val zoomOverlayResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id ResourceMappingPatch["id", "video_zoom_overlay_stub"]
methods@ for (method in controlsMethodResult.mutableClass.methods) { methods@ for (method in controlsMethodResult.mutableClass.methods) {
val instructions = method.implementation?.instructions!! val instructions = method.implementation?.instructions!!
@ -188,7 +192,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
""" """,
) )
} }
@ -201,7 +205,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
""".trimIndent() """.trimIndent(),
) )
} }
} }
@ -223,7 +227,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String; invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister move-result-object v$targetRegister
""" """,
) )
// initialize the player controller // initialize the player controller
@ -236,10 +240,10 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
addInstruction( addInstruction(
startIndex + 3, startIndex + 3,
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V" "invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V",
) )
} }
} ?: throw ControlsOverlayFingerprint.exception } ?: throw ControlsOverlayFingerprint.exception
// get rectangle field name // get rectangle field name
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef) RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
@ -258,7 +262,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) { fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
val register = (instruction as OneRegisterInstruction).registerA val register = (instruction as OneRegisterInstruction).registerA
this.replaceInstruction( this.replaceInstruction(
index, "const-string v$register, \"$with\"" index,
"const-string v$register, \"$with\"",
) )
} }
for ((index, it) in method.implementation!!.instructions.withIndex()) { for ((index, it) in method.implementation!!.instructions.withIndex()) {
@ -268,13 +273,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction( "replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
index, index,
it, it,
rectangleFieldName rectangleFieldName,
) )
} }
} }
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings") } ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
// The vote and create segment buttons automatically change their visibility when appropriate, // The vote and create segment buttons automatically change their visibility when appropriate,
// but if buttons are showing when the end of the video is reached then they will not automatically hide. // but if buttons are showing when the end of the video is reached then they will not automatically hide.
// Add a hook to forcefully hide when the end of the video is reached. // Add a hook to forcefully hide when the end of the video is reached.
@ -283,7 +287,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef) it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef)
}.result?.mutableMethod?.addInstruction( }.result?.mutableMethod?.addInstruction(
0, 0,
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V" "invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V",
) ?: throw AutoRepeatFingerprint.exception ) ?: throw AutoRepeatFingerprint.exception
// TODO: isSBChannelWhitelisting implementation // TODO: isSBChannelWhitelisting implementation

View file

@ -43,8 +43,10 @@ internal object SponsorBlockResourcePatch : ResourcePatch() {
// required resource for back button, because when the base APK is used, this resource will not exist // required resource for back button, because when the base APK is used, this resource will not exist
"drawable", "drawable",
"revanced_sb_adjust.xml", "revanced_sb_adjust.xml",
"revanced_sb_backward.xml",
"revanced_sb_compare.xml", "revanced_sb_compare.xml",
"revanced_sb_edit.xml", "revanced_sb_edit.xml",
"revanced_sb_forward.xml",
"revanced_sb_logo.xml", "revanced_sb_logo.xml",
"revanced_sb_publish.xml", "revanced_sb_publish.xml",
"revanced_sb_voting.xml", "revanced_sb_voting.xml",

View file

@ -38,7 +38,9 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -43,7 +43,9 @@ 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.38",
"19.10.39",
"19.11.43"
) )
) )
] ]

View file

@ -12,7 +12,7 @@ internal object MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerpr
opcodes = listOf( opcodes = listOf(
Opcode.CONST_HIGH16, Opcode.CONST_HIGH16,
Opcode.ADD_FLOAT_2ADDR, Opcode.ADD_FLOAT_2ADDR,
Opcode.MUL_FLOAT, null, // Opcode.MUL_FLOAT or Opcode.MUL_FLOAT_2ADDR
Opcode.CONST_4, Opcode.CONST_4,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,

View file

@ -10,11 +10,14 @@ import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatc
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperDarkColorFingerprint
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperLightColorFingerprint
import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoadingScreenFingerprint import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoadingScreenFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
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 app.revanced.util.indexOfFirstWideLiteralInstructionValue import app.revanced.util.indexOfFirstWideLiteralInstructionValue
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch( @Patch(
@ -47,14 +50,20 @@ 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.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]
) )
@Suppress("unused") @Suppress("unused")
object ThemeBytecodePatch : BytecodePatch( object ThemeBytecodePatch : BytecodePatch(
setOf(UseGradientLoadingScreenFingerprint) setOf(
UseGradientLoadingScreenFingerprint,
ThemeHelperLightColorFingerprint,
ThemeHelperDarkColorFingerprint
)
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;" "Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;"
@ -121,6 +130,21 @@ object ThemeBytecodePatch : BytecodePatch(
) )
} ?: throw UseGradientLoadingScreenFingerprint.exception } ?: throw UseGradientLoadingScreenFingerprint.exception
mapOf(
ThemeHelperLightColorFingerprint to lightThemeBackgroundColor,
ThemeHelperDarkColorFingerprint to darkThemeBackgroundColor
).forEach { (fingerprint, color) ->
fingerprint.resultOrThrow().mutableMethod.apply {
addInstructions(
0, """
const-string v0, "$color"
return-object v0
"""
)
}
}
LithoColorHookPatch.lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getValue") LithoColorHookPatch.lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getValue")
} }
} }

View file

@ -0,0 +1,16 @@
package app.revanced.patches.youtube.layout.theme.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.AccessFlags
internal object ThemeHelperDarkColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "darkThemeResourceName" &&
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
}
)

View file

@ -0,0 +1,16 @@
package app.revanced.patches.youtube.layout.theme.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.AccessFlags
internal object ThemeHelperLightColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "lightThemeResourceName" &&
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
}
)

View file

@ -23,7 +23,6 @@ import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.reques
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint
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.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.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
@ -40,8 +39,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsPatch::class, SettingsPatch::class,
AddResourcesPatch::class, AddResourcesPatch::class,
NavigationBarHookPatch::class, NavigationBarHookPatch::class
PlayerTypeHookPatch::class
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@ -63,7 +61,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View file

@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -14,7 +14,7 @@ import app.revanced.util.exception
@Patch( @Patch(
name = "Spoof device dimensions", name = "Spoof device dimensions",
description = "Adds an option to spoof the device dimensions which unlocks higher video qualities if they aren't available on the device.", description = "Adds an option to spoof the device dimensions which can unlock higher video qualities.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class], dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View file

@ -11,8 +11,9 @@ object SpoofSignatureResourcePatch : ResourcePatch() {
internal var scrubbedPreviewThumbnailResourceId: Long = -1 internal var scrubbedPreviewThumbnailResourceId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single { scrubbedPreviewThumbnailResourceId = ResourceMappingPatch[
it.type == "id" && it.name == "thumbnail" "id",
}.id "thumbnail",
]
} }
} }

View file

@ -44,7 +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.38",
"19.10.39",
"19.11.43"
), ),
), ),
), ),

View file

@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

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