mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-09 19:03:55 +01:00
Compare commits
22 Commits
v3.3.0-dev
...
v4.0.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30c6749f61 | ||
|
|
08c30791ae | ||
|
|
002f11a854 | ||
|
|
861e9a399e | ||
|
|
795aee13e4 | ||
|
|
09f29e6119 | ||
|
|
784aa2f246 | ||
|
|
4ddd5a0b8f | ||
|
|
1482e7e1e8 | ||
|
|
806e94481c | ||
|
|
edcb6eac6d | ||
|
|
4dced95d54 | ||
|
|
62c9085096 | ||
|
|
50a9f09703 | ||
|
|
9633b4eef0 | ||
|
|
2a94ad681c | ||
|
|
9e79e9e72c | ||
|
|
429badef1a | ||
|
|
138b2f8960 | ||
|
|
60d70e5877 | ||
|
|
2debdc1056 | ||
|
|
ad1ea4661f |
68
CHANGELOG.md
68
CHANGELOG.md
@@ -1,3 +1,71 @@
|
||||
# [4.0.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.8...v4.0.0-dev.9) (2024-01-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Enable slide to seek:** Change patch default to excluded and add description disclaimer ([#2610](https://github.com/ReVanced/revanced-patches/issues/2610)) ([2fdc4c2](https://github.com/ReVanced/revanced-patches/commit/2fdc4c23b5f39153ad71071359274c39129d691f))
|
||||
|
||||
# [4.0.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.7...v4.0.0-dev.8) (2024-01-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Shorten setting titles to fit on screen ([#2579](https://github.com/ReVanced/revanced-patches/issues/2579)) ([b2a5dd3](https://github.com/ReVanced/revanced-patches/commit/b2a5dd3efc39ae8a42159858b9c00b5b2f8655a4))
|
||||
|
||||
# [4.0.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.6...v4.0.0-dev.7) (2024-01-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use new integrations patch path ([51e2f3b](https://github.com/ReVanced/revanced-patches/commit/51e2f3b476b49460e2f3fc2b5f302a3a72d7963f))
|
||||
|
||||
# [4.0.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.5...v4.0.0-dev.6) (2024-01-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Tiktok - Playback speed:** Remember playback speed ([#2506](https://github.com/ReVanced/revanced-patches/issues/2506)) ([d2970e5](https://github.com/ReVanced/revanced-patches/commit/d2970e54fbbd7e4b1ae1d354ae2d5c4bbe9336b0))
|
||||
|
||||
# [4.0.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.4...v4.0.0-dev.5) (2024-01-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Change header:** Improve patch descriptions ([#2581](https://github.com/ReVanced/revanced-patches/issues/2581)) ([43a5677](https://github.com/ReVanced/revanced-patches/commit/43a5677397380f14a049ae95532fd5096b94c938))
|
||||
|
||||
# [4.0.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.3...v4.0.0-dev.4) (2024-01-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **MyFitnessPal:** Add `Hide ads` patch ([#2594](https://github.com/ReVanced/revanced-patches/issues/2594)) ([fd4b3c7](https://github.com/ReVanced/revanced-patches/commit/fd4b3c79a83f8de6256611629263d3e29e66f2c2))
|
||||
|
||||
# [4.0.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.2...v4.0.0-dev.3) (2024-01-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Change package name:** Mention caveat of the patch in the description ([427b81a](https://github.com/ReVanced/revanced-patches/commit/427b81a79a5a1de79f14d2261059fb098b22227f))
|
||||
|
||||
# [4.0.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.0.0-dev.1...v4.0.0-dev.2) (2024-01-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Change header:** Change to ReVanced borderless logo header by default ([#2512](https://github.com/ReVanced/revanced-patches/issues/2512)) ([75f785d](https://github.com/ReVanced/revanced-patches/commit/75f785d1ef6026cbbdf7073c10aace1b28d93a30))
|
||||
|
||||
# [4.0.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v3.3.0-dev.2...v4.0.0-dev.1) (2024-01-01)
|
||||
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* Fix package and code structure ([#2541](https://github.com/ReVanced/revanced-patches/issues/2541)) ([a08457e](https://github.com/ReVanced/revanced-patches/commit/a08457e406f4b2e37458a4835c11d370a02d2ce6))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Various public APIs have changed names and packages or were removed entirely
|
||||
|
||||
# [3.3.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v3.3.0-dev.1...v3.3.0-dev.2) (2024-01-01)
|
||||
|
||||
|
||||
|
||||
@@ -333,6 +333,20 @@ public final class app/revanced/patches/myexpenses/misc/pro/UnlockProPatch : app
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/myfitnesspal/ads/HideAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/myfitnesspal/ads/HideAdsPatch;
|
||||
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/myfitnesspal/ads/fingerprints/IsPremiumUseCaseImplFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint {
|
||||
public static final field INSTANCE Lapp/revanced/patches/myfitnesspal/ads/fingerprints/IsPremiumUseCaseImplFingerprint;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/myfitnesspal/ads/fingerprints/MainActivityNavigateToNativePremiumUpsellFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint {
|
||||
public static final field INSTANCE Lapp/revanced/patches/myfitnesspal/ads/fingerprints/MainActivityNavigateToNativePremiumUpsellFingerprint;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch : app/revanced/patcher/patch/ResourcePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/netguard/broadcasts/removerestriction/RemoveBroadcastsRestrictionPatch;
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
@@ -525,6 +539,7 @@ public final class app/revanced/patches/shared/fingerprints/HomeActivityFingerpr
|
||||
|
||||
public abstract class app/revanced/patches/shared/integrations/AbstractIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
|
||||
public fun <init> (Ljava/util/Set;)V
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
@@ -616,13 +631,6 @@ public abstract class app/revanced/patches/shared/settings/preference/BaseResour
|
||||
public static synthetic fun serialize$default (Lapp/revanced/patches/shared/settings/preference/BaseResource;Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lorg/w3c/dom/Element;
|
||||
}
|
||||
|
||||
public abstract class app/revanced/patches/shared/settings/preference/DefaultBasePreference : app/revanced/patches/shared/settings/preference/BasePreference {
|
||||
public fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Ljava/lang/String;Ljava/lang/Object;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Ljava/lang/String;Ljava/lang/Object;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getDefault ()Ljava/lang/Object;
|
||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/settings/preference/SummaryType : java/lang/Enum {
|
||||
public static final field DEFAULT Lapp/revanced/patches/shared/settings/preference/SummaryType;
|
||||
public static final field OFF Lapp/revanced/patches/shared/settings/preference/SummaryType;
|
||||
@@ -650,11 +658,9 @@ public final class app/revanced/patches/shared/settings/preference/impl/InputTyp
|
||||
public static fun values ()[Lapp/revanced/patches/shared/settings/preference/impl/InputType;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/settings/preference/impl/ListPreference : app/revanced/patches/shared/settings/preference/DefaultBasePreference {
|
||||
public fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Ljava/lang/String;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getEntries ()Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;
|
||||
public final fun getEntryValues ()Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;
|
||||
public final class app/revanced/patches/shared/settings/preference/impl/ListPreference : app/revanced/patches/shared/settings/preference/BasePreference {
|
||||
public fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/ArrayResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||
}
|
||||
|
||||
@@ -700,18 +706,18 @@ public final class app/revanced/patches/shared/settings/preference/impl/StringRe
|
||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/settings/preference/impl/SwitchPreference : app/revanced/patches/shared/settings/preference/DefaultBasePreference {
|
||||
public fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Z)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final class app/revanced/patches/shared/settings/preference/impl/SwitchPreference : app/revanced/patches/shared/settings/preference/BasePreference {
|
||||
public fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getSummaryOff ()Lapp/revanced/patches/shared/settings/preference/impl/StringResource;
|
||||
public final fun getSummaryOn ()Lapp/revanced/patches/shared/settings/preference/impl/StringResource;
|
||||
public final fun getUserDialogMessage ()Lapp/revanced/patches/shared/settings/preference/impl/StringResource;
|
||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/settings/preference/impl/TextPreference : app/revanced/patches/shared/settings/preference/DefaultBasePreference {
|
||||
public fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/InputType;Ljava/lang/String;Ljava/lang/String;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/InputType;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final class app/revanced/patches/shared/settings/preference/impl/TextPreference : app/revanced/patches/shared/settings/preference/BasePreference {
|
||||
public fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/InputType;Ljava/lang/String;)V
|
||||
public synthetic fun <init> (Ljava/lang/String;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/StringResource;Lapp/revanced/patches/shared/settings/preference/impl/InputType;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getInputType ()Lapp/revanced/patches/shared/settings/preference/impl/InputType;
|
||||
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
|
||||
}
|
||||
@@ -1136,6 +1142,12 @@ public final class app/revanced/patches/youtube/layout/branding/CustomBrandingPa
|
||||
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch : app/revanced/patcher/patch/ResourcePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch;
|
||||
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/youtube/layout/branding/header/PremiumHeadingPatch : app/revanced/patcher/patch/ResourcePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/branding/header/PremiumHeadingPatch;
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 3.3.0-dev.2
|
||||
version = 4.0.0-dev.9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
revanced-patcher = "19.1.0"
|
||||
revanced-patcher = "19.2.0"
|
||||
smali = "3.0.3"
|
||||
guava = "33.0.0-jre"
|
||||
gson = "2.10.1"
|
||||
|
||||
5045
package-lock.json
generated
5045
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
"@saithodev/semantic-release-backmerge": "^4.0.1",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"gradle-semantic-release-plugin": "^1.8.0",
|
||||
"gradle-semantic-release-plugin": "^1.9.0",
|
||||
"semantic-release": "^22.0.12"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -18,7 +18,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
)
|
||||
@Suppress("unused")
|
||||
object SpoofWifiPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = "Lapp/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = "Lapp/revanced/integrations/all/connectivity/wifi/spoof/SpoofWifiPatch"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
|
||||
|
||||
override fun filterMap(
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.io.Closeable
|
||||
|
||||
@Patch(
|
||||
name = "Change package name",
|
||||
description = "Appends \".revanced\" to the package name by default.",
|
||||
description = "Appends \".revanced\" to the package name by default. Changing the package name of the app can lead to unexpected issues.",
|
||||
use = false
|
||||
)
|
||||
@Suppress("unused")
|
||||
@@ -59,4 +59,4 @@ object ChangePackageNamePatch : ResourcePatch(), Closeable {
|
||||
|
||||
manifest.setAttribute("package", replacementPackageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
abstract class AbstractTransformInstructionsPatch<T> : BytecodePatch() {
|
||||
|
||||
abstract fun filterMap(
|
||||
classDef: ClassDef,
|
||||
method: Method,
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
@Suppress("unused")
|
||||
object RemoveCaptureRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
|
||||
"Lapp/revanced/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch"
|
||||
"Lapp/revanced/integrations/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
|
||||
// Information about method calls we want to replace
|
||||
enum class MethodCall(
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
@Suppress("unused")
|
||||
object RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
|
||||
"Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
|
||||
"Lapp/revanced/integrations/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package app.revanced.patches.myfitnesspal.ads
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.myfitnesspal.ads.fingerprints.IsPremiumUseCaseImplFingerprint
|
||||
import app.revanced.patches.myfitnesspal.ads.fingerprints.MainActivityNavigateToNativePremiumUpsellFingerprint
|
||||
import app.revanced.util.exception
|
||||
|
||||
@Patch(
|
||||
name = "Hide ads",
|
||||
description = "Hides most of the ads across the app.",
|
||||
compatiblePackages = [CompatiblePackage("com.myfitnesspal.android")]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideAdsPatch : BytecodePatch(
|
||||
setOf(IsPremiumUseCaseImplFingerprint, MainActivityNavigateToNativePremiumUpsellFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
// Overwrite the premium status specifically for ads.
|
||||
IsPremiumUseCaseImplFingerprint.result?.mutableMethod?.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
sget-object v0, Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;
|
||||
return-object v0
|
||||
"""
|
||||
) ?: throw IsPremiumUseCaseImplFingerprint.exception
|
||||
|
||||
// Prevent the premium upsell dialog from showing when the main activity is launched.
|
||||
// In other places that are premium-only the dialog will still show.
|
||||
MainActivityNavigateToNativePremiumUpsellFingerprint.result?.mutableMethod?.replaceInstructions(
|
||||
0,
|
||||
"return-void"
|
||||
) ?: throw MainActivityNavigateToNativePremiumUpsellFingerprint.exception
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package app.revanced.patches.myfitnesspal.ads.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
object IsPremiumUseCaseImplFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC.value,
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
classDef.type.endsWith("IsPremiumUseCaseImpl;") && methodDef.name == "doWork"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.myfitnesspal.ads.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
object MainActivityNavigateToNativePremiumUpsellFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
classDef.type.endsWith("MainActivity;") && methodDef.name == "navigateToNativePremiumUpsell"
|
||||
}
|
||||
)
|
||||
@@ -26,7 +26,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
@Suppress("unused")
|
||||
object HideAdsPatch : BytecodePatch(setOf(AdPostFingerprint, NewAdPostFingerprint)) {
|
||||
private const val FILTER_METHOD_DESCRIPTOR =
|
||||
"Lapp/revanced/reddit/patches/FilterPromotedLinksPatch;" +
|
||||
"Lapp/revanced/integrations/reddit/patches/FilterPromotedLinksPatch;" +
|
||||
"->filterChildren(Ljava/lang/Iterable;)Ljava/util/List;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
@@ -11,9 +11,27 @@ import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
|
||||
abstract class AbstractIntegrationsPatch(
|
||||
private val integrationsDescriptor: String,
|
||||
private val hooks: Set<IntegrationsFingerprint>
|
||||
) : BytecodePatch(hooks) {
|
||||
|
||||
@Deprecated(
|
||||
"Use the constructor without the integrationsDescriptor parameter",
|
||||
ReplaceWith("AbstractIntegrationsPatch(hooks)")
|
||||
)
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
constructor(
|
||||
integrationsDescriptor: String,
|
||||
hooks: Set<IntegrationsFingerprint>
|
||||
) : this(hooks)
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
if (context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR) == null) throw PatchException(
|
||||
"Integrations have not been merged yet. This patch can not succeed without merging the integrations."
|
||||
)
|
||||
|
||||
for (hook in hooks) hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR)
|
||||
}
|
||||
|
||||
/**
|
||||
* [MethodFingerprint] for integrations.
|
||||
*
|
||||
@@ -53,11 +71,7 @@ abstract class AbstractIntegrationsPatch(
|
||||
}
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
if (context.findClass(integrationsDescriptor) == null) throw PatchException(
|
||||
"Integrations have not been merged yet. This patch can not succeed without merging the integrations."
|
||||
)
|
||||
|
||||
for (hook in hooks) hook.invoke(integrationsDescriptor)
|
||||
private companion object {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import app.revanced.patches.shared.settings.preference.impl.ArrayResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.mergeStrings
|
||||
import org.w3c.dom.Node
|
||||
import java.io.Closeable
|
||||
|
||||
@@ -37,6 +38,8 @@ abstract class AbstractSettingsResourcePatch(
|
||||
stringsEditor = context.xmlEditor["res/values/strings.xml"]
|
||||
arraysEditor = context.xmlEditor["res/values/arrays.xml"]
|
||||
revancedPreferencesEditor = context.xmlEditor["res/xml/$preferenceFileName.xml"]
|
||||
|
||||
context.mergeStrings("settings/host/values/strings.xml")
|
||||
}
|
||||
|
||||
internal companion object {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package app.revanced.patches.shared.settings.preference
|
||||
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import org.w3c.dom.Document
|
||||
|
||||
/**
|
||||
* Base preference class that also has a default value.
|
||||
*
|
||||
* @param key The key of the preference.
|
||||
* @param title The title of the preference.
|
||||
* @param tag The tag of the preference.
|
||||
* @param summary The summary of the preference.
|
||||
* @param default The default value of the preference.
|
||||
*/
|
||||
abstract class DefaultBasePreference<T>(
|
||||
key: String?,
|
||||
title: StringResource,
|
||||
summary: StringResource? = null,
|
||||
tag: String,
|
||||
val default: T? = null,
|
||||
) : BasePreference(key, title, summary, tag) {
|
||||
|
||||
/**
|
||||
* Serialize preference element to XML.
|
||||
* Overriding methods should invoke super and operate on its return value.
|
||||
* @param ownerDocument Target document to create elements from.
|
||||
* @param resourceCallback Called when a resource has been processed.
|
||||
* @return The serialized element.
|
||||
*/
|
||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||
super.serialize(ownerDocument, resourceCallback).apply { addDefault(default) }
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.shared.settings.preference.impl
|
||||
|
||||
import app.revanced.patches.shared.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.settings.preference.BaseResource
|
||||
import app.revanced.patches.shared.settings.preference.DefaultBasePreference
|
||||
import app.revanced.patches.shared.settings.preference.addSummary
|
||||
import org.w3c.dom.Document
|
||||
|
||||
@@ -13,16 +13,14 @@ import org.w3c.dom.Document
|
||||
* @param entries The human-readable entries of the list preference.
|
||||
* @param entryValues The entry values of the list preference.
|
||||
* @param summary The summary of the list preference.
|
||||
* @param default The default entry value of the list preference.
|
||||
*/
|
||||
class ListPreference(
|
||||
key: String,
|
||||
title: StringResource,
|
||||
val entries: ArrayResource,
|
||||
val entryValues: ArrayResource,
|
||||
summary: StringResource? = null,
|
||||
default: String? = null,
|
||||
) : DefaultBasePreference<String>(key, title, summary, "ListPreference", default) {
|
||||
private val entries: ArrayResource,
|
||||
private val entryValues: ArrayResource,
|
||||
summary: StringResource? = null
|
||||
) : BasePreference(key, title, summary, "ListPreference") {
|
||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||
super.serialize(ownerDocument, resourceCallback).apply {
|
||||
setAttribute("android:entries", "@array/${entries.also { resourceCallback.invoke(it) }.name}")
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package app.revanced.patches.shared.settings.preference.impl
|
||||
|
||||
import app.revanced.patches.shared.settings.AbstractSettingsResourcePatch.Companion.include
|
||||
import app.revanced.patches.shared.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.settings.preference.BaseResource
|
||||
import app.revanced.patches.shared.settings.preference.DefaultBasePreference
|
||||
import app.revanced.patches.shared.settings.preference.SummaryType
|
||||
import app.revanced.patches.shared.settings.preference.addSummary
|
||||
import app.revanced.patches.shared.settings.AbstractSettingsResourcePatch.Companion.include
|
||||
import org.w3c.dom.Document
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@@ -16,15 +16,13 @@ import org.w3c.dom.Element
|
||||
* @param summaryOn The summary to show when the preference is enabled.
|
||||
* @param summaryOff The summary to show when the preference is disabled.
|
||||
* @param userDialogMessage The message to show in a dialog when the user toggles the preference.
|
||||
* @param default The default value of the switch.
|
||||
*/
|
||||
class SwitchPreference(
|
||||
key: String, title: StringResource,
|
||||
val summaryOn: StringResource,
|
||||
val summaryOff: StringResource,
|
||||
val userDialogMessage: StringResource? = null,
|
||||
default: Boolean = false,
|
||||
) : DefaultBasePreference<Boolean>( key, title, null, "SwitchPreference", default) {
|
||||
) : BasePreference(key, title, null, "SwitchPreference") {
|
||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit): Element {
|
||||
userDialogMessage?.include()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.shared.settings.preference.impl
|
||||
|
||||
import app.revanced.patches.shared.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.settings.preference.BaseResource
|
||||
import app.revanced.patches.shared.settings.preference.DefaultBasePreference
|
||||
import org.w3c.dom.Document
|
||||
|
||||
/**
|
||||
@@ -11,16 +11,14 @@ import org.w3c.dom.Document
|
||||
* @param title The title of the text preference.
|
||||
* @param inputType The input type of the text preference.
|
||||
* @param summary The summary of the text preference.
|
||||
* @param default The default value of the text preference.
|
||||
*/
|
||||
class TextPreference(
|
||||
key: String?,
|
||||
title: StringResource,
|
||||
summary: StringResource?,
|
||||
val inputType: InputType = InputType.TEXT,
|
||||
default: String? = null,
|
||||
tag: String = "app.revanced.integrations.settingsmenu.ResettableEditTextPreference"
|
||||
) : DefaultBasePreference<String>(key, title, summary, tag, default) {
|
||||
tag: String = "app.revanced.integrations.shared.settings.preference.ResettableEditTextPreference"
|
||||
) : BasePreference(key, title, summary, tag) {
|
||||
|
||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||
super.serialize(ownerDocument, resourceCallback).apply {
|
||||
|
||||
@@ -36,13 +36,13 @@ object FeedFilterPatch : BytecodePatch(
|
||||
addInstruction(
|
||||
returnFeedItemInstruction.location.index,
|
||||
"invoke-static { v$feedItemsRegister }, " +
|
||||
"Lapp/revanced/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V"
|
||||
"Lapp/revanced/integrations/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V"
|
||||
)
|
||||
} ?: throw FeedApiServiceLIZFingerprint.exception
|
||||
|
||||
SettingsStatusLoadFingerprint.result?.mutableMethod?.addInstruction(
|
||||
0,
|
||||
"invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableFeedFilter()V"
|
||||
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableFeedFilter()V"
|
||||
) ?: throw SettingsStatusLoadFingerprint.exception
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ object RememberClearDisplayPatch : BytecodePatch(
|
||||
it.addInstructions(
|
||||
isEnabledIndex,
|
||||
"invoke-static { v$isEnabledRegister }, " +
|
||||
"Lapp/revanced/tiktok/cleardisplay/RememberClearDisplayPatch;->rememberClearDisplayState(Z)V"
|
||||
"Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->rememberClearDisplayState(Z)V"
|
||||
)
|
||||
|
||||
// endregion
|
||||
@@ -55,7 +55,7 @@ object RememberClearDisplayPatch : BytecodePatch(
|
||||
# Create a new clearDisplayEvent and post it to the EventBus (https://github.com/greenrobot/EventBus)
|
||||
|
||||
# The state of clear display.
|
||||
invoke-static { }, Lapp/revanced/tiktok/cleardisplay/RememberClearDisplayPatch;->getClearDisplayState()Z
|
||||
invoke-static { }, Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->getClearDisplayState()Z
|
||||
move-result v3
|
||||
if-eqz v3, :clear_display_disabled
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ object DownloadsPatch : BytecodePatch(
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/tiktok/download/DownloadsPatch;->shouldRemoveWatermark()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->shouldRemoveWatermark()Z
|
||||
move-result v0
|
||||
if-eqz v0, :noremovewatermark
|
||||
const/4 v0, 0x1
|
||||
@@ -99,7 +99,7 @@ object DownloadsPatch : BytecodePatch(
|
||||
downloadUriMethod.addInstructions(
|
||||
secondIndex,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
"""
|
||||
)
|
||||
@@ -107,7 +107,7 @@ object DownloadsPatch : BytecodePatch(
|
||||
downloadUriMethod.addInstructions(
|
||||
firstIndex,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
"""
|
||||
)
|
||||
@@ -115,7 +115,7 @@ object DownloadsPatch : BytecodePatch(
|
||||
SettingsStatusLoadFingerprint to {
|
||||
addInstruction(
|
||||
0,
|
||||
"invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableDownload()V"
|
||||
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableDownload()V"
|
||||
)
|
||||
}
|
||||
).forEach { (fingerprint, patch) ->
|
||||
|
||||
@@ -1,49 +1,82 @@
|
||||
package app.revanced.patches.tiktok.interaction.speed
|
||||
|
||||
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.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.tiktok.interaction.speed.fingerprints.SpeedControlParentFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFingerprint
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
name = "Playback speed",
|
||||
description = "Enables the playback speed option for all videos.",
|
||||
description = "Enables the playback speed option for all videos and " +
|
||||
"retains the speed configurations in between videos.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"])
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object PlaybackSpeedPatch : BytecodePatch(setOf(SpeedControlParentFingerprint)) {
|
||||
object PlaybackSpeedPatch : BytecodePatch(
|
||||
setOf(
|
||||
GetSpeedFingerprint,
|
||||
OnRenderFirstFrameFingerprint,
|
||||
SetSpeedFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SpeedControlParentFingerprint.result?.mutableMethod?.apply {
|
||||
val targetMethodCallIndex = indexOfFirstInstruction {
|
||||
if (opcode == Opcode.INVOKE_STATIC) {
|
||||
val paramsTypes = ((this as Instruction35c).reference as MethodReference).parameterTypes
|
||||
paramsTypes.size == 1 && paramsTypes[0].contains("/Aweme;")
|
||||
} else false
|
||||
}
|
||||
SetSpeedFingerprint.result?.let { onVideoSwiped ->
|
||||
// Remember the playback speed of the current video.
|
||||
GetSpeedFingerprint.result?.mutableMethod?.apply {
|
||||
val injectIndex = indexOfFirstInstruction { getReference<MethodReference>()?.returnType == "F" } + 2
|
||||
val register = getInstruction<Instruction11x>(injectIndex - 1).registerA
|
||||
|
||||
val isSpeedEnableMethod = context
|
||||
.toMethodWalker(this)
|
||||
.nextMethod(targetMethodCallIndex, true)
|
||||
.getMethod() as MutableMethod
|
||||
addInstruction(
|
||||
injectIndex,
|
||||
"invoke-static { v$register }," +
|
||||
" Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->rememberPlaybackSpeed(F)V"
|
||||
)
|
||||
} ?: throw GetSpeedFingerprint.exception
|
||||
|
||||
isSpeedEnableMethod.addInstructions(
|
||||
// By default, the playback speed will reset to 1.0 at the start of each video.
|
||||
// Instead, override it with the desired playback speed.
|
||||
OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
# Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method.
|
||||
const/4 v0, 0x1
|
||||
invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String;
|
||||
move-result-object v0
|
||||
|
||||
# Model of current video retrieved using getCurrentAweme method.
|
||||
invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme;
|
||||
move-result-object v1
|
||||
|
||||
# Desired playback speed retrieved using getPlaybackSpeed method.
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->getPlaybackSpeed()F
|
||||
move-result-object v2
|
||||
invoke-static { v0, v1, v2 }, ${onVideoSwiped.method}
|
||||
"""
|
||||
) ?: throw OnRenderFirstFrameFingerprint.exception
|
||||
|
||||
// Force enable the playback speed option for all videos.
|
||||
onVideoSwiped.mutableClass.methods.find { method -> method.returnType == "Z" }?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
)
|
||||
} ?: throw SpeedControlParentFingerprint.exception
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
) ?: throw PatchException("Failed to force enable the playback speed option.")
|
||||
} ?: throw SetSpeedFingerprint.exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.tiktok.interaction.speed.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object GetSpeedFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onFeedSpeedSelectedEvent"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.tiktok.interaction.speed.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object OnRenderFirstFrameFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onRenderFirstFrame"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.tiktok.interaction.speed.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object SetSpeedFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
parameters = listOf(
|
||||
"Ljava/lang/String;",
|
||||
"Lcom/ss/android/ugc/aweme/feed/model/Aweme;",
|
||||
"F"
|
||||
),
|
||||
strings = listOf("enterFrom")
|
||||
)
|
||||
@@ -1,13 +0,0 @@
|
||||
package app.revanced.patches.tiktok.interaction.speed.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object SpeedControlParentFingerprint : MethodFingerprint(
|
||||
strings = listOf(
|
||||
"onStopTrackingTouch, hasTouchMove=",
|
||||
", isCurVideoPaused: ",
|
||||
"already_shown_edge_speed_guide"
|
||||
)
|
||||
)
|
||||
@@ -6,6 +6,5 @@ import app.revanced.patches.tiktok.misc.integrations.fingerprints.InitFingerprin
|
||||
|
||||
@Patch(requiresIntegrations = true)
|
||||
object IntegrationsPatch : AbstractIntegrationsPatch(
|
||||
"Lapp/revanced/tiktok/utils/ReVancedUtils;",
|
||||
setOf(InitFingerprint)
|
||||
)
|
||||
@@ -37,10 +37,10 @@ object SettingsPatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/tiktok/settingsmenu/SettingsMenu;"
|
||||
"Lapp/revanced/integrations/tiktok/settings/AdPersonalizationActivityHook;"
|
||||
|
||||
private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR =
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->initializeSettings(" +
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->initialize(" +
|
||||
"Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" +
|
||||
")Z"
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object SettingsStatusLoadFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("Lapp/revanced/tiktok/settingsmenu/SettingsStatus;") &&
|
||||
methodDef.definingClass.endsWith("Lapp/revanced/integrations/tiktok/settings/SettingsStatus;") &&
|
||||
methodDef.name == "load"
|
||||
}
|
||||
)
|
||||
@@ -85,7 +85,7 @@ object SpoofSimPatch : BytecodePatch() {
|
||||
with(SettingsStatusLoadFingerprint.result!!.mutableMethod) {
|
||||
addInstruction(
|
||||
0,
|
||||
"invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableSimSpoof()V"
|
||||
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableSimSpoof()V"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ object SpoofSimPatch : BytecodePatch() {
|
||||
addInstructions(
|
||||
index + 2,
|
||||
"""
|
||||
invoke-static {v$resultReg}, Lapp/revanced/tiktok/spoof/sim/SpoofSimPatch;->$replacement(Ljava/lang/String;)Ljava/lang/String;
|
||||
invoke-static {v$resultReg}, Lapp/revanced/integrations/tiktok/spoof/sim/SpoofSimPatch;->$replacement(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$resultReg
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
object ShowOnLockscreenPatch : BytecodePatch(
|
||||
setOf(BrightnessFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/tudortmund/lockscreen/ShowOnLockscreenPatch;"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/tudortmund/lockscreen/ShowOnLockscreenPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
BrightnessFingerprint.result?.mutableMethod?.apply {
|
||||
|
||||
@@ -60,7 +60,7 @@ object TimelineFilterPatch : BytecodePatch(
|
||||
fingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"invoke-static {p$timelineObjectsRegister}, " +
|
||||
"Lapp/revanced/tumblr/patches/TimelineFilterPatch;->" +
|
||||
"Lapp/revanced/integrations/tumblr/patches/TimelineFilterPatch;->" +
|
||||
"filterTimeline(Ljava/util/List;)V"
|
||||
) ?: throw fingerprint.exception
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ object AudioAdsPatch : BytecodePatch(
|
||||
mutableMethod.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, Lapp/revanced/twitch/patches/AudioAdsPatch;->shouldBlockAudioAds()Z
|
||||
invoke-static { }, Lapp/revanced/integrations/twitch/patches/AudioAdsPatch;->shouldBlockAudioAds()Z
|
||||
move-result v0
|
||||
if-eqz v0, :show_audio_ads
|
||||
return-void
|
||||
@@ -52,8 +52,7 @@ object AudioAdsPatch : BytecodePatch(
|
||||
StringResource(
|
||||
"revanced_block_audio_ads_off",
|
||||
"Audio ads are unblocked"
|
||||
),
|
||||
default = true,
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ object EmbeddedAdsPatch : BytecodePatch(
|
||||
result.mutableMethod.addInstructions(
|
||||
3,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/twitch/patches/EmbeddedAdsPatch;->createRequestInterceptor()Lapp/revanced/twitch/api/RequestInterceptor;
|
||||
invoke-static {}, Lapp/revanced/integrations/twitch/patches/EmbeddedAdsPatch;->createRequestInterceptor()Lapp/revanced/integrations/twitch/api/RequestInterceptor;
|
||||
move-result-object v2
|
||||
invoke-virtual {v0, v2}, Lokhttp3/OkHttpClient${"$"}Builder;->addInterceptor(Lokhttp3/Interceptor;)Lokhttp3/OkHttpClient${"$"}Builder;
|
||||
"""
|
||||
@@ -59,8 +59,7 @@ object EmbeddedAdsPatch : BytecodePatch(
|
||||
StringResource("key_revanced_proxy_luminous", "luminous"),
|
||||
StringResource("key_revanced_proxy_purpleadblock", "purpleadblock")
|
||||
)
|
||||
),
|
||||
default = "luminous"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import app.revanced.patches.twitch.misc.settings.SettingsPatch
|
||||
compatiblePackages = [CompatiblePackage("tv.twitch.android.app", ["15.4.1", "16.1.0", "16.9.1"])]
|
||||
)
|
||||
object VideoAdsPatch : AbstractAdPatch(
|
||||
"Lapp/revanced/twitch/patches/VideoAdsPatch;->shouldBlockVideoAds()Z",
|
||||
"Lapp/revanced/integrations/twitch/patches/VideoAdsPatch;->shouldBlockVideoAds()Z",
|
||||
"show_video_ads",
|
||||
setOf(
|
||||
ContentConfigShowAdsFingerprint,
|
||||
@@ -135,8 +135,7 @@ object VideoAdsPatch : AbstractAdPatch(
|
||||
StringResource(
|
||||
"revanced_block_video_ads_off",
|
||||
"Video ads are unblocked"
|
||||
),
|
||||
default = true
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ object ShowDeletedMessagesPatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
private fun createSpoilerConditionInstructions(register: String = "v0") = """
|
||||
invoke-static {}, Lapp/revanced/twitch/patches/ShowDeletedMessagesPatch;->shouldUseSpoiler()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/twitch/patches/ShowDeletedMessagesPatch;->shouldUseSpoiler()Z
|
||||
move-result $register
|
||||
if-eqz $register, :no_spoiler
|
||||
"""
|
||||
@@ -61,7 +61,7 @@ object ShowDeletedMessagesPatch : BytecodePatch(
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static {p2}, Lapp/revanced/twitch/patches/ShowDeletedMessagesPatch;->reformatDeletedMessage(Landroid/text/Spanned;)Landroid/text/Spanned;
|
||||
invoke-static {p2}, Lapp/revanced/integrations/twitch/patches/ShowDeletedMessagesPatch;->reformatDeletedMessage(Landroid/text/Spanned;)Landroid/text/Spanned;
|
||||
move-result-object v0
|
||||
if-eqz v0, :no_reformat
|
||||
return-object v0
|
||||
@@ -92,8 +92,7 @@ object ShowDeletedMessagesPatch : BytecodePatch(
|
||||
StringResource("key_revanced_deleted_messages_spoiler", "spoiler"),
|
||||
StringResource("key_revanced_deleted_messages_cross_out", "cross-out")
|
||||
)
|
||||
),
|
||||
default = "cross-out"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -38,8 +38,7 @@ object AutoClaimChannelPointPatch : BytecodePatch(
|
||||
StringResource(
|
||||
"revanced_auto_claim_channel_points_off",
|
||||
"Channel Points are not claimed automatically"
|
||||
),
|
||||
default = true
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -48,7 +47,7 @@ object AutoClaimChannelPointPatch : BytecodePatch(
|
||||
addInstructionsWithLabels(
|
||||
lastIndex, // place in front of return-void
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/twitch/patches/AutoClaimChannelPointsPatch;->shouldAutoClaim()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/twitch/patches/AutoClaimChannelPointsPatch;->shouldAutoClaim()Z
|
||||
move-result v0
|
||||
if-eqz v0, :auto_claim
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ object DebugModePatch : BytecodePatch(
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/twitch/patches/DebugModePatch;->isDebugModeEnabled()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/twitch/patches/DebugModePatch;->isDebugModeEnabled()Z
|
||||
move-result v0
|
||||
return v0
|
||||
"""
|
||||
@@ -49,20 +49,19 @@ object DebugModePatch : BytecodePatch(
|
||||
|
||||
SettingsPatch.PreferenceScreen.MISC.OTHER.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_debug_mode",
|
||||
"revanced_twitch_debug_mode",
|
||||
StringResource(
|
||||
"revanced_debug_mode_enable",
|
||||
"Enable debug mode"
|
||||
"revanced_twitch_debug_mode_title",
|
||||
"Enable Twitch debug mode"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_debug_mode_on",
|
||||
"Debug mode is enabled (not recommended)"
|
||||
"revanced_twitch_debug_mode_summary_on",
|
||||
"Twitch debug mode is enabled (not recommended)"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_debug_mode_off",
|
||||
"Debug mode is disabled"
|
||||
),
|
||||
default = false,
|
||||
"revanced_twitch_debug_mode_summary_off",
|
||||
"Twitch debug mode is disabled"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,5 @@ import app.revanced.patches.twitch.misc.integrations.fingerprints.InitFingerprin
|
||||
|
||||
@Patch(requiresIntegrations = true)
|
||||
object IntegrationsPatch : AbstractIntegrationsPatch(
|
||||
"Lapp/revanced/twitch/utils/ReVancedUtils;",
|
||||
setOf(InitFingerprint)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package app.revanced.patches.twitch.misc.settings
|
||||
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
@@ -14,12 +13,14 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMut
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.shared.settings.preference.impl.PreferenceCategory
|
||||
import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||
import app.revanced.patches.shared.settings.util.AbstractPreferenceScreen
|
||||
import app.revanced.patches.twitch.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.twitch.misc.settings.fingerprints.MenuGroupsOnClickFingerprint
|
||||
import app.revanced.patches.twitch.misc.settings.fingerprints.MenuGroupsUpdatedFingerprint
|
||||
import app.revanced.patches.twitch.misc.settings.fingerprints.SettingsActivityOnCreateFingerprint
|
||||
import app.revanced.patches.twitch.misc.settings.fingerprints.SettingsMenuItemEnumFingerprint
|
||||
import app.revanced.util.exception
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
||||
import java.io.Closeable
|
||||
@@ -46,12 +47,12 @@ object SettingsPatch : BytecodePatch(
|
||||
private const val REVANCED_SETTINGS_MENU_ITEM_TITLE_RES = "revanced_settings"
|
||||
private const val REVANCED_SETTINGS_MENU_ITEM_ICON_RES = "ic_settings"
|
||||
|
||||
private const val MENU_ITEM_ENUM_CLASS = "Ltv/twitch/android/feature/settings/menu/SettingsMenuItem;"
|
||||
private const val MENU_DISMISS_EVENT_CLASS = "Ltv/twitch/android/feature/settings/menu/SettingsMenuViewDelegate\$Event\$OnDismissClicked;"
|
||||
private const val MENU_ITEM_ENUM_CLASS_DESCRIPTOR = "Ltv/twitch/android/feature/settings/menu/SettingsMenuItem;"
|
||||
private const val MENU_DISMISS_EVENT_CLASS_DESCRIPTOR = "Ltv/twitch/android/feature/settings/menu/SettingsMenuViewDelegate\$Event\$OnDismissClicked;"
|
||||
|
||||
private const val INTEGRATIONS_PACKAGE = "app/revanced/twitch"
|
||||
private const val SETTINGS_HOOKS_CLASS = "L$INTEGRATIONS_PACKAGE/settingsmenu/SettingsHooks;"
|
||||
private const val REVANCED_UTILS_CLASS = "L$INTEGRATIONS_PACKAGE/utils/ReVancedUtils;"
|
||||
private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/twitch"
|
||||
private const val ACTIVITY_HOOKS_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/AppCompatActivityHook;"
|
||||
private const val UTILS_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/Utils;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
// Hook onCreate to handle fragment creation
|
||||
@@ -60,7 +61,7 @@ object SettingsPatch : BytecodePatch(
|
||||
mutableMethod.addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {p0}, $SETTINGS_HOOKS_CLASS->handleSettingsCreation(Landroidx/appcompat/app/AppCompatActivity;)Z
|
||||
invoke-static {p0}, $ACTIVITY_HOOKS_CLASS_DESCRIPTOR->handleSettingsCreation(Landroidx/appcompat/app/AppCompatActivity;)Z
|
||||
move-result v0
|
||||
if-eqz v0, :no_rv_settings_init
|
||||
return-void
|
||||
@@ -84,8 +85,8 @@ object SettingsPatch : BytecodePatch(
|
||||
mutableMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
sget-object v0, $MENU_ITEM_ENUM_CLASS->$REVANCED_SETTINGS_MENU_ITEM_NAME:$MENU_ITEM_ENUM_CLASS
|
||||
invoke-static {p1, v0}, $SETTINGS_HOOKS_CLASS->handleSettingMenuCreation(Ljava/util/List;Ljava/lang/Object;)Ljava/util/List;
|
||||
sget-object v0, $MENU_ITEM_ENUM_CLASS_DESCRIPTOR->$REVANCED_SETTINGS_MENU_ITEM_NAME:$MENU_ITEM_ENUM_CLASS_DESCRIPTOR
|
||||
invoke-static {p1, v0}, $ACTIVITY_HOOKS_CLASS_DESCRIPTOR->handleSettingMenuCreation(Ljava/util/List;Ljava/lang/Object;)Ljava/util/List;
|
||||
move-result-object p1
|
||||
"""
|
||||
)
|
||||
@@ -97,10 +98,10 @@ object SettingsPatch : BytecodePatch(
|
||||
mutableMethod.addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {p1}, $SETTINGS_HOOKS_CLASS->handleSettingMenuOnClick(Ljava/lang/Enum;)Z
|
||||
invoke-static {p1}, $ACTIVITY_HOOKS_CLASS_DESCRIPTOR->handleSettingMenuOnClick(Ljava/lang/Enum;)Z
|
||||
move-result p2
|
||||
if-eqz p2, :no_rv_settings_onclick
|
||||
sget-object p1, $MENU_DISMISS_EVENT_CLASS->INSTANCE:$MENU_DISMISS_EVENT_CLASS
|
||||
sget-object p1, $MENU_DISMISS_EVENT_CLASS_DESCRIPTOR->INSTANCE:$MENU_DISMISS_EVENT_CLASS_DESCRIPTOR
|
||||
invoke-virtual {p0, p1}, Ltv/twitch/android/core/mvp/viewdelegate/RxViewDelegate;->pushEvent(Ltv/twitch/android/core/mvp/viewdelegate/ViewDelegateEvent;)V
|
||||
return-void
|
||||
""",
|
||||
@@ -109,8 +110,15 @@ object SettingsPatch : BytecodePatch(
|
||||
} ?: throw MenuGroupsOnClickFingerprint.exception
|
||||
|
||||
addString("revanced_settings", "ReVanced Settings", false)
|
||||
addString("revanced_reboot_message", "Twitch needs to restart to apply your changes. Restart now?", false)
|
||||
addString("revanced_reboot", "Restart", false)
|
||||
|
||||
PreferenceScreen.MISC.OTHER.addPreferences(
|
||||
SwitchPreference(
|
||||
"revanced_debug",
|
||||
StringResource("revanced_debug_title", "Debug logging"),
|
||||
StringResource("revanced_debug_summary_on", "Debug logs are enabled"),
|
||||
StringResource("revanced_debug_summary_off", "Debug logs are disabled")
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun addString(identifier: String, value: String, formatted: Boolean = true) =
|
||||
@@ -130,7 +138,7 @@ object SettingsPatch : BytecodePatch(
|
||||
ImmutableField(
|
||||
mutableMethod.definingClass,
|
||||
name,
|
||||
MENU_ITEM_ENUM_CLASS,
|
||||
MENU_ITEM_ENUM_CLASS_DESCRIPTOR,
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.ENUM or AccessFlags.STATIC,
|
||||
null,
|
||||
null,
|
||||
@@ -142,17 +150,17 @@ object SettingsPatch : BytecodePatch(
|
||||
mutableMethod.addInstructions(
|
||||
mutableMethod.implementation!!.instructions.size - 4,
|
||||
"""
|
||||
new-instance v0, $MENU_ITEM_ENUM_CLASS
|
||||
new-instance v0, $MENU_ITEM_ENUM_CLASS_DESCRIPTOR
|
||||
const-string v1, "$titleResourceName"
|
||||
invoke-static {v1}, $REVANCED_UTILS_CLASS->getStringId(Ljava/lang/String;)I
|
||||
invoke-static {v1}, $UTILS_CLASS_DESCRIPTOR->getStringId(Ljava/lang/String;)I
|
||||
move-result v1
|
||||
const-string v3, "$iconResourceName"
|
||||
invoke-static {v3}, $REVANCED_UTILS_CLASS->getDrawableId(Ljava/lang/String;)I
|
||||
invoke-static {v3}, $UTILS_CLASS_DESCRIPTOR->getDrawableId(Ljava/lang/String;)I
|
||||
move-result v3
|
||||
const-string v4, "$name"
|
||||
const/4 v5, $value
|
||||
invoke-direct {v0, v4, v5, v1, v3}, $MENU_ITEM_ENUM_CLASS-><init>(Ljava/lang/String;III)V
|
||||
sput-object v0, $MENU_ITEM_ENUM_CLASS->$name:$MENU_ITEM_ENUM_CLASS
|
||||
invoke-direct {v0, v4, v5, v1, v3}, $MENU_ITEM_ENUM_CLASS_DESCRIPTOR-><init>(Ljava/lang/String;III)V
|
||||
sput-object v0, $MENU_ITEM_ENUM_CLASS_DESCRIPTOR->$name:$MENU_ITEM_ENUM_CLASS_DESCRIPTOR
|
||||
"""
|
||||
)
|
||||
}
|
||||
@@ -179,7 +187,7 @@ object SettingsPatch : BytecodePatch(
|
||||
key,
|
||||
StringResource("${key}_title", title),
|
||||
preferences.sortedBy { it.title.value },
|
||||
"app.revanced.twitch.settingsmenu.preference.CustomPreferenceCategory"
|
||||
"app.revanced.integrations.twitch.settings.preference.CustomPreferenceCategory"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.io.InvalidClassException
|
||||
object JsonHookPatch : BytecodePatch(
|
||||
setOf(LoganSquareFingerprint)
|
||||
), Closeable {
|
||||
private const val JSON_HOOK_CLASS_NAMESPACE = "app/revanced/twitter/patches/hook/json"
|
||||
private const val JSON_HOOK_CLASS_NAMESPACE = "app/revanced/integrations/twitter/patches/hook/json"
|
||||
private const val JSON_HOOK_PATCH_CLASS_DESCRIPTOR = "L$JSON_HOOK_CLASS_NAMESPACE/JsonHookPatch;"
|
||||
private const val BASE_PATCH_CLASS_NAME = "BaseJsonHook"
|
||||
private const val JSON_HOOK_CLASS_DESCRIPTOR = "L$JSON_HOOK_CLASS_NAMESPACE/$BASE_PATCH_CLASS_NAME;"
|
||||
|
||||
@@ -12,4 +12,4 @@ import app.revanced.patches.twitter.misc.hook.patch.BaseHookPatchPatch
|
||||
compatiblePackages = [CompatiblePackage("com.twitter.android")]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideAdsPatch : BaseHookPatchPatch("Lapp/revanced/twitter/patches/hook/patch/ads/AdsHook;")
|
||||
object HideAdsPatch : BaseHookPatchPatch("Lapp/revanced/integrations/twitter/patches/hook/patch/ads/AdsHook;")
|
||||
@@ -12,5 +12,5 @@ import app.revanced.patches.twitter.misc.hook.patch.BaseHookPatchPatch
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideRecommendedUsersPatch : BaseHookPatchPatch(
|
||||
"Lapp/revanced/twitter/patches/hook/patch/recommendation/RecommendedUsersHook;"
|
||||
"Lapp/revanced/integrations/twitter/patches/hook/patch/recommendation/RecommendedUsersHook;"
|
||||
)
|
||||
@@ -65,7 +65,7 @@ object HideAdsPatch : BytecodePatch() {
|
||||
.injectHideViewCall(
|
||||
insertIndex,
|
||||
viewRegister,
|
||||
"Lapp/revanced/integrations/patches/components/AdsFilter;",
|
||||
"Lapp/revanced/integrations/youtube/patches/components/AdsFilter;",
|
||||
"hideAdAttributionView"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch.PreferenceScreen
|
||||
)
|
||||
object HideAdsResourcePatch : ResourcePatch() {
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/AdsFilter;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/AdsFilter;"
|
||||
|
||||
internal var adAttributionId: Long = -1
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
)
|
||||
object HideGetPremiumPatch : BytecodePatch(setOf(GetPremiumViewFingerprint)) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/HideGetPremiumPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/HideGetPremiumPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SettingsPatch.PreferenceScreen.ADS.addPreferences(
|
||||
|
||||
@@ -53,7 +53,7 @@ object VideoAdsPatch : BytecodePatch(
|
||||
|
||||
loadVideoAdsFingerprintMethod.addInstructionsWithLabels(
|
||||
0, """
|
||||
invoke-static { }, Lapp/revanced/integrations/patches/VideoAdsPatch;->shouldShowAds()Z
|
||||
invoke-static { }, Lapp/revanced/integrations/youtube/patches/VideoAdsPatch;->shouldShowAds()Z
|
||||
move-result v0
|
||||
if-nez v0, :show_video_ads
|
||||
return-void
|
||||
|
||||
@@ -32,7 +32,7 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
)
|
||||
@Suppress("unused")
|
||||
object CopyVideoUrlBytecodePatch : BytecodePatch() {
|
||||
private const val INTEGRATIONS_PLAYER_PACKAGE = "Lapp/revanced/integrations/videoplayer"
|
||||
private const val INTEGRATIONS_PLAYER_PACKAGE = "Lapp/revanced/integrations/youtube/videoplayer"
|
||||
private val BUTTONS_DESCRIPTORS = listOf(
|
||||
"$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlButton;",
|
||||
"$INTEGRATIONS_PLAYER_PACKAGE/CopyVideoUrlTimestampButton;"
|
||||
|
||||
@@ -30,7 +30,7 @@ object RemoveViewerDiscretionDialogPatch : BytecodePatch(
|
||||
setOf(CreateDialogFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_METHOD_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/RemoveViewerDiscretionDialogPatch;->" +
|
||||
"Lapp/revanced/integrations/youtube/patches/RemoveViewerDiscretionDialogPatch;->" +
|
||||
"confirmDialog(Landroid/app/AlertDialog;)V"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
@@ -32,7 +32,7 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
)
|
||||
@Suppress("unused")
|
||||
object ExternalDownloadsBytecodePatch : BytecodePatch() {
|
||||
private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/videoplayer/ExternalDownloadButton;"
|
||||
private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
/*
|
||||
|
||||
@@ -38,7 +38,7 @@ object DisablePreciseSeekingGesturePatch : BytecodePatch(
|
||||
setOf(IsSwipingUpFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_METHOD_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/DisablePreciseSeekingGesturePatch;->" +
|
||||
"Lapp/revanced/integrations/youtube/patches/DisablePreciseSeekingGesturePatch;->" +
|
||||
"disableGesture(Landroid/view/VelocityTracker;Landroid/view/MotionEvent;)V"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
@@ -85,7 +85,7 @@ object EnableSeekbarTappingPatch : BytecodePatch(
|
||||
addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static { }, Lapp/revanced/integrations/patches/SeekbarTappingPatch;->seekbarTappingEnabled()Z
|
||||
invoke-static { }, Lapp/revanced/integrations/youtube/patches/SeekbarTappingPatch;->seekbarTappingEnabled()Z
|
||||
move-result v$freeRegister
|
||||
if-eqz v$freeRegister, :disabled
|
||||
${oMethod.toInvokeInstructionString()}
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Patch(
|
||||
name = "Enable slide to seek",
|
||||
description = "Adds an option to enable slide to seek instead of playing at 2x speed when pressing and holding in the video player.",
|
||||
description = "Adds an option to enable slide to seek instead of playing at 2x speed when pressing and holding in the video player. Including this patch may cause issues with tapping or double tapping the video player overlay.",
|
||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
@@ -29,7 +29,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
"18.45.43"
|
||||
]
|
||||
)
|
||||
]
|
||||
],
|
||||
use = false
|
||||
)
|
||||
@Suppress("unused")
|
||||
object EnableSlideToSeekPatch : BytecodePatch(
|
||||
@@ -38,7 +39,7 @@ object EnableSlideToSeekPatch : BytecodePatch(
|
||||
DoubleSpeedSeekNoticeFingerprint
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SlideToSeekPatch;"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/SlideToSeekPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
|
||||
|
||||
@@ -8,6 +8,6 @@ internal object SwipeControlsHostActivityFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
parameters = listOf(),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;"
|
||||
methodDef.definingClass == "Lapp/revanced/integrations/youtube/swipecontrols/SwipeControlsHostActivity;"
|
||||
}
|
||||
)
|
||||
|
||||
@@ -57,7 +57,7 @@ object AutoCaptionsPatch : BytecodePatch(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x$enabled
|
||||
sput-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z
|
||||
sput-boolean v0, Lapp/revanced/integrations/youtube/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z
|
||||
"""
|
||||
) ?: throw fingerprint.exception
|
||||
}
|
||||
@@ -65,10 +65,10 @@ object AutoCaptionsPatch : BytecodePatch(
|
||||
SubtitleTrackFingerprint.result?.mutableMethod?.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->autoCaptionsEnabled()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/youtube/patches/DisableAutoCaptionsPatch;->autoCaptionsEnabled()Z
|
||||
move-result v0
|
||||
if-eqz v0, :auto_captions_enabled
|
||||
sget-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z
|
||||
sget-boolean v0, Lapp/revanced/integrations/youtube/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z
|
||||
if-nez v0, :auto_captions_enabled
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
|
||||
@@ -93,7 +93,7 @@ object CustomBrandingPatch : ResourcePatch() {
|
||||
)
|
||||
}
|
||||
}
|
||||
} else resourceGroups.forEach { context.copyResources("branding", it) }
|
||||
} else resourceGroups.forEach { context.copyResources("custom-branding", it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
package app.revanced.patches.youtube.layout.branding.header
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import java.io.File
|
||||
|
||||
@Patch(
|
||||
name = "Change header",
|
||||
description = "Applies a custom header in the top left corner within the app. Defaults to the ReVanced header.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.google.android.youtube")
|
||||
],
|
||||
use = false
|
||||
)
|
||||
@Suppress("unused")
|
||||
object ChangeHeaderPatch : ResourcePatch() {
|
||||
private const val HEADER_NAME = "yt_wordmark_header"
|
||||
private const val PREMIUM_HEADER_NAME = "yt_premium_wordmark_header"
|
||||
private const val REVANCED_HEADER_NAME = "ReVanced"
|
||||
private const val REVANCED_BORDERLESS_HEADER_NAME = "ReVanced (borderless logo)"
|
||||
|
||||
private val targetResourceDirectoryNames = arrayOf(
|
||||
"xxxhdpi",
|
||||
"xxhdpi",
|
||||
"xhdpi",
|
||||
"mdpi",
|
||||
"hdpi",
|
||||
).map { dpi ->
|
||||
"drawable-$dpi"
|
||||
}
|
||||
|
||||
private val variants = arrayOf("light", "dark")
|
||||
|
||||
private val header by stringPatchOption(
|
||||
key = "header",
|
||||
default = REVANCED_BORDERLESS_HEADER_NAME,
|
||||
values = mapOf(
|
||||
"YouTube" to HEADER_NAME,
|
||||
"YouTube Premium" to PREMIUM_HEADER_NAME,
|
||||
"ReVanced" to REVANCED_HEADER_NAME,
|
||||
"ReVanced (borderless logo)" to REVANCED_BORDERLESS_HEADER_NAME,
|
||||
),
|
||||
title = "Header",
|
||||
description = """
|
||||
Either a header name or a path to a custom header folder to use in the top bar.
|
||||
The path to a folder must contain one or more of the following folders matching the DPI of your device:
|
||||
|
||||
${targetResourceDirectoryNames.joinToString("\n") { "- $it" }}
|
||||
|
||||
These folders must contain the following files:
|
||||
|
||||
${variants.joinToString("\n") { variant -> "- ${HEADER_NAME}_$variant.png" }}
|
||||
""".trimIndent(),
|
||||
required = true,
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
// The directories to copy the header to.
|
||||
val targetResourceDirectories = targetResourceDirectoryNames.mapNotNull {
|
||||
context["res"].resolve(it).takeIf(File::exists)
|
||||
}
|
||||
// The files to replace in the target directories.
|
||||
val targetResourceFiles = targetResourceDirectoryNames.map { directoryName ->
|
||||
ResourceGroup(
|
||||
directoryName,
|
||||
*variants.map { variant -> "${HEADER_NAME}_$variant.png" }.toTypedArray()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that overwrites both header variants from [from] to [to] in the target resource directories.
|
||||
*/
|
||||
val overwriteFromTo: (String, String) -> Unit = { from: String, to: String ->
|
||||
targetResourceDirectories.forEach { directory ->
|
||||
variants.forEach { variant ->
|
||||
val fromPath = directory.resolve("${from}_$variant.png")
|
||||
val toPath = directory.resolve("${to}_$variant.png")
|
||||
|
||||
fromPath.copyTo(toPath, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Functions to overwrite the header to the different variants.
|
||||
val toPremium = { overwriteFromTo(PREMIUM_HEADER_NAME, HEADER_NAME) }
|
||||
val toHeader = { overwriteFromTo(HEADER_NAME, PREMIUM_HEADER_NAME) }
|
||||
val toReVanced = {
|
||||
// Copy the ReVanced header to the resource directories.
|
||||
targetResourceFiles.forEach { context.copyResources("change-header/revanced", it) }
|
||||
|
||||
// Overwrite the premium with the custom header as well.
|
||||
toHeader()
|
||||
}
|
||||
val toReVancedBorderless = {
|
||||
// Copy the ReVanced borderless header to the resource directories.
|
||||
targetResourceFiles.forEach { context.copyResources("change-header/revanced-borderless", it) }
|
||||
|
||||
// Overwrite the premium with the custom header as well.
|
||||
toHeader()
|
||||
}
|
||||
val toCustom = {
|
||||
var copiedReplacementImages = false
|
||||
// For all the resource groups in the custom header folder, copy them to the resource directories.
|
||||
File(header!!).listFiles { file -> file.isDirectory }?.forEach { folder ->
|
||||
val targetDirectory = context["res"].resolve(folder.name)
|
||||
// Skip if the target directory (DPI) doesn't exist.
|
||||
if (!targetDirectory.exists()) return@forEach
|
||||
|
||||
folder.listFiles { file -> file.isFile }?.forEach {
|
||||
val targetResourceFile = targetDirectory.resolve(it.name)
|
||||
|
||||
it.copyTo(targetResourceFile, true)
|
||||
copiedReplacementImages = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!copiedReplacementImages) throw PatchException("Could not find any custom images resources in directory: $header")
|
||||
|
||||
// Overwrite the premium with the custom header as well.
|
||||
toHeader()
|
||||
}
|
||||
|
||||
when (header) {
|
||||
HEADER_NAME -> toHeader
|
||||
PREMIUM_HEADER_NAME -> toPremium
|
||||
REVANCED_HEADER_NAME -> toReVanced
|
||||
REVANCED_BORDERLESS_HEADER_NAME -> toReVancedBorderless
|
||||
else -> toCustom
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -1,62 +1,9 @@
|
||||
package app.revanced.patches.youtube.layout.branding.header
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption
|
||||
import kotlin.io.path.copyTo
|
||||
|
||||
@Patch(
|
||||
name = "Premium heading",
|
||||
description = "Adds or removes the YouTube Premium logo at the top of feeds.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.google.android.youtube")
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
@Deprecated("Use PremiumHeadingPatch instead.")
|
||||
object PremiumHeadingPatch : ResourcePatch() {
|
||||
private const val DEFAULT_HEADING_RES = "yt_wordmark_header"
|
||||
private const val PREMIUM_HEADING_RES = "yt_premium_wordmark_header"
|
||||
|
||||
private val usePremiumHeading by booleanPatchOption(
|
||||
key = "usePremiumHeading",
|
||||
default = true,
|
||||
title = "Use premium heading",
|
||||
description = "Whether to use the YouTube Premium logo.",
|
||||
required = true,
|
||||
)
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
val resDirectory = context["res"]
|
||||
|
||||
val (original, replacement) = if (usePremiumHeading!!)
|
||||
PREMIUM_HEADING_RES to DEFAULT_HEADING_RES
|
||||
else
|
||||
DEFAULT_HEADING_RES to PREMIUM_HEADING_RES
|
||||
|
||||
val variants = arrayOf("light", "dark")
|
||||
|
||||
arrayOf(
|
||||
"xxxhdpi",
|
||||
"xxhdpi",
|
||||
"xhdpi",
|
||||
"hdpi",
|
||||
"mdpi"
|
||||
).mapNotNull { dpi ->
|
||||
resDirectory.resolve("drawable-$dpi").takeIf { it.exists() }?.toPath()
|
||||
}.also {
|
||||
if (it.isEmpty())
|
||||
throw PatchException("The drawable folder can not be found. Therefore, the patch can not be applied.")
|
||||
}.forEach { path ->
|
||||
|
||||
variants.forEach { mode ->
|
||||
val fromPath = path.resolve("${original}_$mode.png")
|
||||
val toPath = path.resolve("${replacement}_$mode.png")
|
||||
|
||||
fromPath.copyTo(toPath, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun execute(context: ResourceContext) = ChangeHeaderPatch.execute(context)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
@Suppress("unused")
|
||||
object HideButtonsPatch : ResourcePatch() {
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/ButtonsFilter;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/ButtonsFilter;"
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
|
||||
@@ -78,7 +78,7 @@ object HideAutoplayButtonPatch : BytecodePatch(
|
||||
addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/youtube/patches/HideAutoplayButtonPatch;->isButtonShown()Z
|
||||
move-result v$clobberRegister
|
||||
if-eqz v$clobberRegister, :hidden
|
||||
""",
|
||||
|
||||
@@ -58,7 +58,7 @@ object HideCaptionsButtonPatch : BytecodePatch(
|
||||
subtitleButtonControllerMethod.addInstruction(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
|
||||
invoke-static {v0}, Lapp/revanced/integrations/youtube/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ object HideCastButtonPatch : BytecodePatch() {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static {p1}, Lapp/revanced/integrations/patches/HideCastButtonPatch;->getCastButtonOverrideV2(I)I
|
||||
invoke-static {p1}, Lapp/revanced/integrations/youtube/patches/HideCastButtonPatch;->getCastButtonOverrideV2(I)I
|
||||
move-result p1
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ object NavigationButtonsPatch : BytecodePatch(
|
||||
setOf(AddCreateButtonViewFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/NavigationButtonsPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/NavigationButtonsPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
|
||||
@@ -72,10 +72,10 @@ object HidePlayerButtonsPatch : BytecodePatch(
|
||||
mutableMethod.addInstructions(
|
||||
callIndex,
|
||||
"""
|
||||
invoke-static { v$hasNextParameterRegister }, Lapp/revanced/integrations/patches/HidePlayerButtonsPatch;->previousOrNextButtonIsVisible(Z)Z
|
||||
invoke-static { v$hasNextParameterRegister }, Lapp/revanced/integrations/youtube/patches/HidePlayerButtonsPatch;->previousOrNextButtonIsVisible(Z)Z
|
||||
move-result v$hasNextParameterRegister
|
||||
|
||||
invoke-static { v$hasPreviousParameterRegister }, Lapp/revanced/integrations/patches/HidePlayerButtonsPatch;->previousOrNextButtonIsVisible(Z)Z
|
||||
invoke-static { v$hasPreviousParameterRegister }, Lapp/revanced/integrations/youtube/patches/HidePlayerButtonsPatch;->previousOrNextButtonIsVisible(Z)Z
|
||||
move-result v$hasPreviousParameterRegister
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -48,7 +48,7 @@ object AlbumCardsPatch : BytecodePatch(
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static {v$albumCardViewRegister}, " +
|
||||
"Lapp/revanced/integrations/patches/HideAlbumCardsPatch;" +
|
||||
"Lapp/revanced/integrations/youtube/patches/HideAlbumCardsPatch;" +
|
||||
"->" +
|
||||
"hideAlbumCard(Landroid/view/View;)V"
|
||||
)
|
||||
|
||||
@@ -50,7 +50,7 @@ object BreakingNewsPatch : BytecodePatch(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {v$breakingNewsViewRegister},
|
||||
Lapp/revanced/integrations/patches/HideBreakingNewsPatch;
|
||||
Lapp/revanced/integrations/youtube/patches/HideBreakingNewsPatch;
|
||||
->
|
||||
hideBreakingNews(Landroid/view/View;)V
|
||||
"""
|
||||
|
||||
@@ -35,7 +35,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
@Suppress("unused")
|
||||
object CommentsPatch : ResourcePatch() {
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/CommentsFilter;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/CommentsFilter;"
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
@@ -38,7 +38,7 @@ object CrowdfundingBoxPatch : BytecodePatch(
|
||||
setOf(CrowdfundingBoxFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_METHOD_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V"
|
||||
"Lapp/revanced/integrations/youtube/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
CrowdfundingBoxFingerprint.result?.let {
|
||||
|
||||
@@ -53,7 +53,7 @@ object HideEndscreenCardsPatch : BytecodePatch(
|
||||
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideEndscreenCardsPatch;->hideEndscreen(Landroid/view/View;)V"
|
||||
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/youtube/patches/HideEndscreenCardsPatch;->hideEndscreen(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ object HideFilterBarPatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/HideFilterBarPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/HideFilterBarPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
FilterBarHeightFingerprint.patch<TwoRegisterInstruction> { register ->
|
||||
|
||||
@@ -34,7 +34,7 @@ object HideFloatingMicrophoneButtonPatch : BytecodePatch(
|
||||
setOf(ShowFloatingMicrophoneButtonFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/HideFloatingMicrophoneButtonPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/HideFloatingMicrophoneButtonPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
ShowFloatingMicrophoneButtonFingerprint.result?.let { result ->
|
||||
|
||||
@@ -34,7 +34,7 @@ object DisableFullscreenAmbientModePatch : BytecodePatch(
|
||||
setOf(InitializeAmbientModeFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/DisableFullscreenAmbientModePatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/DisableFullscreenAmbientModePatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
|
||||
@@ -48,9 +48,9 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint)
|
||||
) {
|
||||
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/LayoutComponentsFilter;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/LayoutComponentsFilter;"
|
||||
private const val DESCRIPTION_COMPONENTS_FILTER_CLASS_NAME =
|
||||
"Lapp/revanced/integrations/patches/components/DescriptionComponentsFilter;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
PreferenceScreen.LAYOUT.addPreferences(
|
||||
@@ -97,7 +97,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||
"revanced_hide_search_result_recommendations",
|
||||
StringResource(
|
||||
"revanced_hide_search_result_recommendations_title",
|
||||
"Hide search result recommendations (e.g People also watched)"
|
||||
"Hide \\\'People also watched\\\' recommendations"
|
||||
),
|
||||
StringResource(
|
||||
"revanced_hide_search_result_recommendations_summary_on",
|
||||
|
||||
@@ -48,7 +48,7 @@ object HideInfoCardsPatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/HideInfoCardsFilterPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/HideInfoCardsFilterPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
InfocardsIncognitoFingerprint.also {
|
||||
@@ -62,7 +62,7 @@ object HideInfoCardsPatch : BytecodePatch(
|
||||
addInstruction(
|
||||
invokeInstructionIndex,
|
||||
"invoke-static {v${getInstruction<FiveRegisterInstruction>(invokeInstructionIndex).registerC}}," +
|
||||
" Lapp/revanced/integrations/patches/HideInfoCardsPatch;->hideInfoCardsIncognito(Landroid/view/View;)V"
|
||||
" Lapp/revanced/integrations/youtube/patches/HideInfoCardsPatch;->hideInfoCardsIncognito(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ object HideInfoCardsPatch : BytecodePatch(
|
||||
hideInfoCardsCallMethod.addInstructionsWithLabels(
|
||||
invokeInterfaceIndex,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/patches/HideInfoCardsPatch;->hideInfoCardsMethodCall()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/youtube/patches/HideInfoCardsPatch;->hideInfoCardsMethodCall()Z
|
||||
move-result v$toggleRegister
|
||||
if-nez v$toggleRegister, :hide_info_cards
|
||||
""",
|
||||
|
||||
@@ -34,7 +34,7 @@ object HideLoadMoreButtonPatch : BytecodePatch(
|
||||
setOf(HideLoadMoreButtonFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/HideLoadMoreButtonPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/HideLoadMoreButtonPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
HideLoadMoreButtonFingerprint.result?.let {
|
||||
|
||||
@@ -44,7 +44,7 @@ object HideEmailAddressPatch : BytecodePatch(
|
||||
addInstructions(
|
||||
setVisibilityConstIndex,
|
||||
"""
|
||||
invoke-static {v$setVisibilityConstRegister}, Lapp/revanced/integrations/patches/HideEmailAddressPatch;->hideEmailAddress(I)I
|
||||
invoke-static {v$setVisibilityConstRegister}, Lapp/revanced/integrations/youtube/patches/HideEmailAddressPatch;->hideEmailAddress(I)I
|
||||
move-result v$setVisibilityConstRegister
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -36,7 +36,7 @@ object HidePlayerFlyoutMenuPatch : ResourcePatch() {
|
||||
private const val KEY = "revanced_hide_player_flyout"
|
||||
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/PlayerFlyoutMenuItemsFilter;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/PlayerFlyoutMenuItemsFilter;"
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
|
||||
@@ -38,7 +38,7 @@ object DisableRollingNumberAnimationPatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/DisableRollingNumberAnimationsPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/DisableRollingNumberAnimationsPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
|
||||
@@ -63,7 +63,7 @@ object HideSeekbarPatch : BytecodePatch(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
invoke-static { }, Lapp/revanced/integrations/patches/HideSeekbarPatch;->hideSeekbar()Z
|
||||
invoke-static { }, Lapp/revanced/integrations/youtube/patches/HideSeekbarPatch;->hideSeekbar()Z
|
||||
move-result v0
|
||||
if-eqz v0, :hide_seekbar
|
||||
return-void
|
||||
|
||||
@@ -51,7 +51,7 @@ object HideShortsComponentsPatch : BytecodePatch(
|
||||
SetPivotBarVisibilityParentFingerprint
|
||||
)
|
||||
) {
|
||||
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/ShortsFilter;"
|
||||
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
// region Hide the Shorts shelf.
|
||||
|
||||
@@ -33,7 +33,7 @@ object DisableSuggestedVideoEndScreenPatch : BytecodePatch(
|
||||
setOf(CreateEndScreenViewFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/DisableSuggestedVideoEndScreenPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/DisableSuggestedVideoEndScreenPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
CreateEndScreenViewFingerprint.result?.let {
|
||||
|
||||
@@ -48,7 +48,7 @@ object HideTimestampPatch : BytecodePatch(
|
||||
mutableMethod.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, Lapp/revanced/integrations/patches/HideTimestampPatch;->hideTimestamp()Z
|
||||
invoke-static { }, Lapp/revanced/integrations/youtube/patches/HideTimestampPatch;->hideTimestamp()Z
|
||||
move-result v0
|
||||
if-eqz v0, :hide_time
|
||||
return-void
|
||||
|
||||
@@ -50,7 +50,7 @@ object PlayerPopupPanelsPatch : BytecodePatch(
|
||||
engagementPanelControllerMethod.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, Lapp/revanced/integrations/patches/DisablePlayerPopupPanelsPatch;->disablePlayerPopupPanels()Z
|
||||
invoke-static { }, Lapp/revanced/integrations/youtube/patches/DisablePlayerPopupPanelsPatch;->disablePlayerPopupPanels()Z
|
||||
move-result v0
|
||||
if-eqz v0, :player_popup_panels
|
||||
if-eqz p4, :player_popup_panels
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
)
|
||||
@Suppress("unused")
|
||||
object CustomPlayerOverlayOpacityPatch : BytecodePatch(setOf(CreatePlayerOverviewFingerprint)) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/CustomPlayerOverlayOpacityPatch;"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/CustomPlayerOverlayOpacityPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
CreatePlayerOverviewFingerprint.result?.let { result ->
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike
|
||||
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
@@ -11,19 +8,39 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.*
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.ConversionContextFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.DislikeFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.DislikesOldLayoutTextViewFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.LikeFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RemoveLikeFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberMeasureAnimatedTextFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberMeasureStaticLabelFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberMeasureTextParentFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberSetterFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.RollingNumberTextViewFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.ShortsTextViewFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.TextComponentConstructorFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.TextComponentDataFingerprint
|
||||
import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.TextComponentLookupFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.shared.fingerprints.RollingNumberTextViewAnimationUpdateFingerprint
|
||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
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.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
|
||||
@Patch(
|
||||
name = "Return YouTube Dislike",
|
||||
@@ -38,6 +55,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.41",
|
||||
@@ -49,7 +67,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
@Suppress("unused")
|
||||
object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
setOf(
|
||||
ConversionContextFingerprint,
|
||||
TextComponentConstructorFingerprint,
|
||||
TextComponentDataFingerprint,
|
||||
ShortsTextViewFingerprint,
|
||||
DislikesOldLayoutTextViewFingerprint,
|
||||
LikeFingerprint,
|
||||
@@ -62,10 +82,12 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/ReturnYouTubeDislikePatch;"
|
||||
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/components/ReturnYouTubeDislikeFilterPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;"
|
||||
|
||||
private fun MethodFingerprint.resultOrThrow() = result ?: throw exception
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
// region Inject newVideoLoaded event handler to update dislikes when a new video is loaded.
|
||||
@@ -97,64 +119,132 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook creation of Spans and the cached lookup of them.
|
||||
// region Hook code for creation and cached lookup of text Spans.
|
||||
|
||||
// Alternatively the hook can be made at the creation of Spans in TextComponentSpec,
|
||||
// And it works in all situations except it fails to update the Span when the user dislikes,
|
||||
// since the underlying (likes only) text did not change.
|
||||
// This hook handles all situations, as it's where the created Spans are stored and later reused.
|
||||
TextComponentContextFingerprint.also {
|
||||
if (!it.resolve(context, TextComponentConstructorFingerprint.result!!.classDef))
|
||||
throw it.exception
|
||||
}.result?.also { result ->
|
||||
if (!TextComponentAtomicReferenceFingerprint.resolve(context, result.method, result.classDef))
|
||||
throw TextComponentAtomicReferenceFingerprint.exception
|
||||
}?.let { textComponentContextFingerprintResult ->
|
||||
val conversionContextIndex = textComponentContextFingerprintResult
|
||||
.scanResult.patternScanResult!!.endIndex
|
||||
val atomicReferenceStartIndex = TextComponentAtomicReferenceFingerprint.result!!
|
||||
.scanResult.patternScanResult!!.startIndex
|
||||
TextComponentConstructorFingerprint.result?.let { textConstructorResult ->
|
||||
// Find the field name of the conversion context.
|
||||
val conversionContextClassType = ConversionContextFingerprint.resultOrThrow().classDef.type
|
||||
val conversionContextField = textConstructorResult.classDef.fields.find {
|
||||
it.type == conversionContextClassType
|
||||
} ?: throw PatchException("Could not find conversion context field")
|
||||
|
||||
val insertIndex = atomicReferenceStartIndex + 9
|
||||
TextComponentLookupFingerprint.resolve(context, textConstructorResult.classDef)
|
||||
TextComponentLookupFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
// Find the instruction for creating the text data object.
|
||||
val textDataClassType = TextComponentDataFingerprint.resultOrThrow().classDef.type
|
||||
val insertIndex = indexOfFirstInstruction {
|
||||
opcode == Opcode.NEW_INSTANCE &&
|
||||
getReference<TypeReference>()?.type == textDataClassType
|
||||
}
|
||||
if (insertIndex < 0) throw PatchException("Could not find data creation instruction")
|
||||
val tempRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
textComponentContextFingerprintResult.mutableMethod.apply {
|
||||
// Get the conversion context obfuscated field name
|
||||
val conversionContextFieldReference =
|
||||
getInstruction<ReferenceInstruction>(conversionContextIndex).reference
|
||||
// Find the instruction that sets the span to an instance field.
|
||||
// The instruction is only a few lines after the creation of the instance.
|
||||
// The method has multiple iput-object instructions using a CharSequence,
|
||||
// so verify the found instruction is in the expected location.
|
||||
val putFieldInstruction = implementation!!.instructions
|
||||
.subList(insertIndex, insertIndex + 20)
|
||||
.find {
|
||||
it.opcode == Opcode.IPUT_OBJECT &&
|
||||
it.getReference<FieldReference>()?.type == "Ljava/lang/CharSequence;"
|
||||
} ?: throw PatchException("Could not find put object instruction")
|
||||
val charSequenceRegister = (putFieldInstruction as TwoRegisterInstruction).registerA
|
||||
|
||||
// Free register to hold the conversion context
|
||||
val freeRegister =
|
||||
getInstruction<TwoRegisterInstruction>(atomicReferenceStartIndex).registerB
|
||||
|
||||
val atomicReferenceRegister =
|
||||
getInstruction<FiveRegisterInstruction>(atomicReferenceStartIndex + 6).registerC
|
||||
|
||||
// Instruction that is replaced, and also has the CharacterSequence register.
|
||||
val moveCharSequenceInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
|
||||
val charSequenceSourceRegister = moveCharSequenceInstruction.registerB
|
||||
val charSequenceTargetRegister = moveCharSequenceInstruction.registerA
|
||||
|
||||
// Move the current instance to the free register, and get the conversion context from it.
|
||||
// Must replace the instruction to preserve the control flow label.
|
||||
replaceInstruction(insertIndex, "move-object/from16 v$freeRegister, p0")
|
||||
addInstructions(
|
||||
insertIndex + 1,
|
||||
"""
|
||||
# Move context to free register
|
||||
iget-object v$freeRegister, v$freeRegister, $conversionContextFieldReference
|
||||
invoke-static {v$freeRegister, v$atomicReferenceRegister, v$charSequenceSourceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$freeRegister
|
||||
# Replace the original instruction
|
||||
move-object v${charSequenceTargetRegister}, v${freeRegister}
|
||||
insertIndex,
|
||||
"""
|
||||
# Copy conversion context
|
||||
move-object/from16 v$tempRegister, p0
|
||||
iget-object v$tempRegister, v$tempRegister, $conversionContextField
|
||||
invoke-static {v$tempRegister, v$charSequenceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$charSequenceRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw TextComponentContextFingerprint.exception
|
||||
} ?: throw TextComponentConstructorFingerprint.exception
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook for non-litho Short videos.
|
||||
|
||||
ShortsTextViewFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val patternResult = it.scanResult.patternScanResult!!
|
||||
|
||||
// If the field is true, the TextView is for a dislike button.
|
||||
val isDisLikesBooleanReference = getInstruction<ReferenceInstruction>(patternResult.endIndex).reference
|
||||
|
||||
val textViewFieldReference = // Like/Dislike button TextView field
|
||||
getInstruction<ReferenceInstruction>(patternResult.endIndex - 1).reference
|
||||
|
||||
// Check if the hooked TextView object is that of the dislike button.
|
||||
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.
|
||||
// Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward.
|
||||
val insertIndex = patternResult.startIndex + 6
|
||||
addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
# Check, if the TextView is for a dislike button
|
||||
iget-boolean v0, p0, $isDisLikesBooleanReference
|
||||
if-eqz v0, :is_like
|
||||
|
||||
# Hook the TextView, if it is for the dislike button
|
||||
iget-object v0, p0, $textViewFieldReference
|
||||
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z
|
||||
move-result v0
|
||||
if-eqz v0, :ryd_disabled
|
||||
return-void
|
||||
|
||||
:is_like
|
||||
:ryd_disabled
|
||||
nop
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw ShortsTextViewFingerprint.exception
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook for litho Shorts
|
||||
|
||||
// Filter that parses the video id from the UI
|
||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
// Player response video id is needed to search for the video ids in Shorts litho components.
|
||||
VideoIdPatch.hookPlayerResponseVideoId("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V")
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook old UI layout dislikes, for the older app spoofs used with spoof-app-version.
|
||||
|
||||
DislikesOldLayoutTextViewFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
val resourceIdentifierRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
|
||||
val textViewRegister = getInstruction<OneRegisterInstruction>(startIndex + 4).registerA
|
||||
|
||||
addInstruction(
|
||||
startIndex + 4,
|
||||
"invoke-static {v$resourceIdentifierRegister, v$textViewRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setOldUILayoutDislikes(ILandroid/widget/TextView;)V"
|
||||
)
|
||||
}
|
||||
} ?: throw DislikesOldLayoutTextViewFingerprint.exception
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
// region Hook rolling numbers.
|
||||
|
||||
// Do this last to allow patching old unsupported versions (if the user really wants),
|
||||
// On older unsupported version this will fail to resolve and throw an exception,
|
||||
// but everything will still work correctly anyways.
|
||||
|
||||
RollingNumberSetterFingerprint.result?.let {
|
||||
val dislikesIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
@@ -164,7 +254,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
val charSequenceInstanceRegister =
|
||||
getInstruction<OneRegisterInstruction>(0).registerA
|
||||
val charSequenceFieldReference =
|
||||
getInstruction<ReferenceInstruction>(dislikesIndex).reference.toString()
|
||||
getInstruction<ReferenceInstruction>(dislikesIndex).reference
|
||||
|
||||
val registerCount = implementation!!.registerCount
|
||||
|
||||
@@ -268,73 +358,6 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook for non-litho Short videos.
|
||||
|
||||
ShortsTextViewFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val patternResult = it.scanResult.patternScanResult!!
|
||||
|
||||
// If the field is true, the TextView is for a dislike button.
|
||||
val isDisLikesBooleanReference = getInstruction<ReferenceInstruction>(patternResult.endIndex).reference
|
||||
|
||||
val textViewFieldReference = // Like/Dislike button TextView field
|
||||
getInstruction<ReferenceInstruction>(patternResult.endIndex - 1).reference
|
||||
|
||||
// Check if the hooked TextView object is that of the dislike button.
|
||||
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.
|
||||
// Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward.
|
||||
val insertIndex = patternResult.startIndex + 6
|
||||
addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
# Check, if the TextView is for a dislike button
|
||||
iget-boolean v0, p0, $isDisLikesBooleanReference
|
||||
if-eqz v0, :is_like
|
||||
|
||||
# Hook the TextView, if it is for the dislike button
|
||||
iget-object v0, p0, $textViewFieldReference
|
||||
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z
|
||||
move-result v0
|
||||
if-eqz v0, :ryd_disabled
|
||||
return-void
|
||||
|
||||
:is_like
|
||||
:ryd_disabled
|
||||
nop
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw ShortsTextViewFingerprint.exception
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook for litho Shorts
|
||||
|
||||
// Filter that parses the video id from the UI
|
||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
// Player response video id is needed to search for the video ids in Shorts litho components.
|
||||
VideoIdPatch.hookPlayerResponseVideoId("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V")
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook old UI layout dislikes, for the older app spoofs used with spoof-app-version.
|
||||
|
||||
DislikesOldLayoutTextViewFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
val resourceIdentifierRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
|
||||
val textViewRegister = getInstruction<OneRegisterInstruction>(startIndex + 4).registerA
|
||||
|
||||
addInstruction(
|
||||
startIndex + 4,
|
||||
"invoke-static {v$resourceIdentifierRegister, v$textViewRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setOldUILayoutDislikes(ILandroid/widget/TextView;)V"
|
||||
)
|
||||
}
|
||||
} ?: throw DislikesOldLayoutTextViewFingerprint.exception
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object ConversionContextFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
parameters = listOf(),
|
||||
strings = listOf(
|
||||
", widthConstraint=",
|
||||
", heightConstraint=",
|
||||
", templateLoggerFactory=",
|
||||
", rootDisposableContainer=",
|
||||
// 18.37.36 and after this String is: ConversionContext{containerInternal=
|
||||
// and before it is: ConversionContext{container=
|
||||
// Use a partial string to match both.
|
||||
"ConversionContext{container"
|
||||
)
|
||||
)
|
||||
@@ -1,33 +0,0 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.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
|
||||
|
||||
/**
|
||||
* Resolves against the same method that [TextComponentContextFingerprint] resolves to.
|
||||
*/
|
||||
internal object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE_OBJECT, // Register B is free register
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
null,
|
||||
Opcode.INVOKE_VIRTUAL, // Register C is atomic reference
|
||||
Opcode.MOVE_RESULT_OBJECT, // Register A is char sequence
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.MOVE_OBJECT, // Replace this instruction with patch code
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.GOTO
|
||||
)
|
||||
)
|
||||
@@ -1,6 +1,5 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.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
|
||||
|
||||
/**
|
||||
* Resolves against the same class that [TextComponentConstructorFingerprint] resolves to.
|
||||
*/
|
||||
internal object TextComponentContextFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
Opcode.MOVE_OBJECT_FROM16,
|
||||
Opcode.INVOKE_STATIC_RANGE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT, // conversion context field name
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object TextComponentDataFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
parameters = listOf("L", "L"),
|
||||
strings = listOf("text"),
|
||||
customFingerprint = { _, classDef ->
|
||||
val fields = classDef.fields
|
||||
fields.find { it.type == "Ljava/util/BitSet;" } != null &&
|
||||
fields.find { it.type == "[Ljava/lang/String;" } != null
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Resolves against the same class that [TextComponentConstructorFingerprint] resolves to.
|
||||
*/
|
||||
internal object TextComponentLookupFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
strings = listOf("…")
|
||||
)
|
||||
@@ -80,7 +80,7 @@ object WideSearchbarPatch : BytecodePatch(
|
||||
addInstructions(
|
||||
implementation!!.instructions.size - 1,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/patches/WideSearchbarPatch;->enableWideSearchbar()Z
|
||||
invoke-static {}, Lapp/revanced/integrations/youtube/patches/WideSearchbarPatch;->enableWideSearchbar()Z
|
||||
move-result p0
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -11,7 +11,6 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource
|
||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.FullscreenSeekbarThumbnailsFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
|
||||
@Patch(
|
||||
name = "Restore old seekbar thumbnails",
|
||||
@@ -35,7 +34,7 @@ object RestoreOldSeekbarThumbnailsPatch : BytecodePatch(
|
||||
setOf(FullscreenSeekbarThumbnailsFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/RestoreOldSeekbarThumbnailsPatch;"
|
||||
"Lapp/revanced/integrations/youtube/patches/RestoreOldSeekbarThumbnailsPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SeekbarPreferencesPatch.addPreferences(
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
internal object SeekbarColorBytecodePatch : BytecodePatch(
|
||||
setOf(PlayerSeekbarColorFingerprint, ShortsSeekbarColorFingerprint, SetSeekbarClickedColorFingerprint)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/theme/SeekbarColorPatch;"
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/theme/SeekbarColorPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
||||
|
||||
@@ -38,7 +38,7 @@ internal object SeekbarColorResourcePatch : ResourcePatch(){
|
||||
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
|
||||
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
|
||||
val replacementNode = editor.file.createElement(
|
||||
"app.revanced.integrations.patches.theme.ProgressBarDrawable")
|
||||
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable")
|
||||
scaleNode.replaceChild(replacementNode, shapeNode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,13 +69,13 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;"
|
||||
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
|
||||
private const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;"
|
||||
"Lapp/revanced/integrations/youtube/sponsorblock/ui/CreateSegmentButtonController;"
|
||||
private const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;"
|
||||
"Lapp/revanced/integrations/youtube/sponsorblock/ui/VotingButtonController;"
|
||||
private const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;"
|
||||
"Lapp/revanced/integrations/youtube/sponsorblock/ui/SponsorBlockViewController;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
LayoutConstructorFingerprint.result?.let {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user