From 230ab2fa590c01ee9d2b3b0f522712547612d771 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 24 Jan 2026 19:55:54 +0100 Subject: [PATCH] suppress and other migratios --- .../CustomCertificatesPatch.kt | 37 ++++++-------- .../packagename/ChangePackageNamePatch.kt | 7 +-- .../mifitness/misc/login/FixLoginPatch.kt | 1 + .../BackgroundPlaybackPatch.kt | 1 + .../shared/layout/theme/Fingerprints.kt | 4 ++ .../patches/shared/misc/gms/Fingerprints.kt | 16 +++---- .../tiktok/misc/settings/Fingerprints.kt | 28 ++++++----- .../tiktok/misc/settings/SettingsPatch.kt | 31 +++++------- .../patches/twitch/ad/audio/AudioAdsPatch.kt | 1 + .../twitch/ad/embedded/EmbeddedAdsPatch.kt | 1 + .../patches/twitch/ad/video/VideoAdsPatch.kt | 1 + .../antidelete/ShowDeletedMessagesPatch.kt | 3 +- .../autoclaim/AutoClaimChannelPointsPatch.kt | 1 + .../patches/twitch/debug/DebugModePatch.kt | 1 + .../twitch/misc/settings/SettingsPatch.kt | 42 ++++++++-------- .../patches/youtube/ad/video/VideoAdsPatch.kt | 1 + .../RemoveViewerDiscretionDialogPatch.kt | 1 + .../interaction/seekbar/Fingerprints.kt | 18 ++++--- .../layout/autocaptions/AutoCaptionsPatch.kt | 1 + .../layout/buttons/action/HideButtonsPatch.kt | 15 +++--- .../layout/buttons/navigation/Fingerprints.kt | 8 ++-- .../navigation/NavigationButtonsPatch.kt | 25 +++++----- .../DisableFullscreenAmbientModePatch.kt | 1 + .../hide/general/HideLayoutComponentsPatch.kt | 1 + .../HidePlayerFlyoutMenuPatch.kt | 5 +- .../DisableRollingNumberAnimationPatch.kt | 1 + .../DisableSignInToTvPatchPopup.kt | 1 + .../youtube/layout/hide/time/Fingerprints.kt | 28 ++--------- .../layout/hide/time/HideTimestampPatch.kt | 1 + .../layout/panels/popup/Fingerprints.kt | 13 +++-- .../panels/popup/PlayerPopupPanelsPatch.kt | 1 + .../layout/player/fullscreen/Fingerprints.kt | 21 ++------ .../ReturnYouTubeDislikePatch.kt | 1 + .../layout/searchbar/WideSearchbarPatch.kt | 1 + .../layout/shortsautoplay/Fingerprints.kt | 32 +++++++------ .../shortsautoplay/ShortsAutoplayPatch.kt | 20 ++++---- .../layout/spoofappversion/Fingerprints.kt | 37 +++++--------- .../spoofappversion/SpoofAppVersionPatch.kt | 1 + .../layout/startpage/ChangeStartPagePatch.kt | 1 + .../DisableResumingShortsOnStartupPatch.kt | 1 + .../thumbnails/AlternativeThumbnailsPatch.kt | 13 ++--- .../BypassImageRegionRestrictionsPatch.kt | 5 +- .../BackgroundPlaybackPatch.kt | 1 + .../spoof/SpoofDeviceDimensionsPatch.kt | 1 + .../FIxContentProviderPatch.kt | 6 +-- .../misc/fix/contentprovider/Fingerprints.kt | 16 ++----- .../misc/links/BypassURLRedirectsPatch.kt | 25 +++++----- .../youtube/misc/links/Fingerprints.kt | 8 ++-- .../misc/links/OpenLinksExternallyPatch.kt | 3 +- .../youtube/misc/litho/filter/Fingerprints.kt | 48 +++++++------------ .../youtube/misc/loopvideo/LoopVideoPatch.kt | 1 + .../patches/youtube/shared/Fingerprints.kt | 2 +- 52 files changed, 257 insertions(+), 283 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/customcertificates/CustomCertificatesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/customcertificates/CustomCertificatesPatch.kt index abe9c2d04..b368b4001 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/customcertificates/CustomCertificatesPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/customcertificates/CustomCertificatesPatch.kt @@ -9,23 +9,24 @@ import app.revanced.util.getNode import org.w3c.dom.Element import java.io.File +@Suppress("unused", "ObjectPropertyName") val `Custom network security` = creatingResourcePatch( description = "Allows trusting custom certificate authorities for a specific domain.", - use = false + use = false, ) { val targetDomains by stringsOption( name = "Target domains", description = "List of domains to which the custom trust configuration will be applied (one domain per entry).", default = listOf("example.com"), - required = true + required = true, ) val includeSubdomains by booleanOption( name = "Include subdomains", description = "Applies the configuration to all subdomains of the target domains.", default = false, - required = true + required = true, ) val customCAFilePaths by stringsOption( @@ -40,35 +41,35 @@ val `Custom network security` = creatingResourcePatch( CA files will be bundled in res/raw/ of resulting APK """.trimIndentMultiline(), default = null, - required = false + required = false, ) val allowUserCerts by booleanOption( name = "Trust user added CAs", description = "Makes an app trust certificates from the Android user store for the specified domains, and if the option \"Include Subdomains\" is enabled then also the subdomains.", default = false, - required = true + required = true, ) val allowSystemCerts by booleanOption( name = "Trust system CAs", description = "Makes an app trust certificates from the Android system store for the specified domains, and and if the option \"Include Subdomains\" is enabled then also the subdomains.", default = true, - required = true + required = true, ) val allowCleartextTraffic by booleanOption( name = "Allow cleartext traffic (HTTP)", description = "Allows unencrypted HTTP traffic for the specified domains, and if \"Include Subdomains\" is enabled then also the subdomains.", default = false, - required = true + required = true, ) val overridePins by booleanOption( name = "Override certificate pinning", description = "Overrides certificate pinning for the specified domains and their subdomains if the option \"Include Subdomains\" is enabled to allow inspecting app traffic via a proxy.", default = false, - required = true + required = true, ) fun generateNetworkSecurityConfig(): String { @@ -113,55 +114,47 @@ ${trustAnchorsXML.trimEnd()} - """.trimIndent() + """.trimIndent() } - apply { val nscFileNameBare = "network_security_config" val resXmlDir = "res/xml" val resRawDir = "res/raw" val nscFileNameWithSuffix = "$nscFileNameBare.xml" - document("AndroidManifest.xml").use { document -> val applicationNode = document.getNode("application") as Element applicationNode.setAttribute("android:networkSecurityConfig", "@xml/$nscFileNameBare") } - File(get(resXmlDir), nscFileNameWithSuffix).apply { writeText(generateNetworkSecurityConfig()) } - - for (customCAFilePath in customCAFilePaths ?: emptyList()) { val file = File(customCAFilePath) if (!file.exists()) { throw PatchException( "The custom CA file path cannot be found: " + - file.absolutePath + file.absolutePath, ) } if (!file.isFile) { throw PatchException( - "The custom CA file path must be a file: " - + file.absolutePath + "The custom CA file path must be a file: " + + file.absolutePath, ) } val caFileNameWithoutSuffix = customCAFilePath.substringAfterLast('/').substringBefore('.') val caFile = File(customCAFilePath) File( get(resRawDir), - caFileNameWithoutSuffix + caFileNameWithoutSuffix, ).writeText( - caFile.readText() + caFile.readText(), ) - } - - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt index f25b46d3e..e3f50eade 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/packagename/ChangePackageNamePatch.kt @@ -26,9 +26,10 @@ fun setOrGetFallbackPackageName(fallbackPackageName: String): String { } } +@Suppress("ObjectPropertyName") val `Change package name` = creatingResourcePatch( description = "Appends \".revanced\" to the package name by default. " + - "Changing the package name of the app can lead to unexpected issues.", + "Changing the package name of the app can lead to unexpected issues.", use = false, ) { packageNameOption = stringOption( @@ -45,14 +46,14 @@ val `Change package name` = creatingResourcePatch( default = false, name = "Update permissions", description = "Update compatibility receiver permissions. " + - "Enabling this can fix installation errors, but this can also break features in certain apps.", + "Enabling this can fix installation errors, but this can also break features in certain apps.", ) val updateProviders by booleanOption( default = false, name = "Update providers", description = "Update provider names declared by the app. " + - "Enabling this can fix installation errors, but this can also break features in certain apps.", + "Enabling this can fix installation errors, but this can also break features in certain apps.", ) afterDependents { diff --git a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt index e7b40f62f..4f228c1ae 100644 --- a/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt @@ -3,6 +3,7 @@ package app.revanced.patches.mifitness.misc.login import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.patch.creatingBytecodePatch +@Suppress("ObjectPropertyName") val `Fix login` by creatingBytecodePatch( description = "Fixes login for uncertified Mi Fitness app", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt index 7c7b12ca9..08bda5684 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt @@ -5,6 +5,7 @@ import app.revanced.patches.music.misc.extension.sharedExtensionPatch import app.revanced.patches.music.misc.settings.settingsPatch import app.revanced.util.returnEarly +@Suppress("unused", "ObjectPropertyName") val `Remove background playback restrictions` by creatingBytecodePatch( description = "Removes restrictions on background playback, including playing kids videos in the background.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt index 7e7446384..38ff79c69 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/Fingerprints.kt @@ -1,9 +1,12 @@ package app.revanced.patches.shared.layout.theme import app.revanced.patcher.accessFlags +import app.revanced.patcher.allOf +import app.revanced.patcher.field import app.revanced.patcher.fieldAccess import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.instructions +import app.revanced.patcher.invoke import app.revanced.patcher.methodCall import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext @@ -16,6 +19,7 @@ internal val BytecodePatchContext.lithoOnBoundsChangeMethod by gettingFirstMetho returnType("V") parameterTypes("Landroid/graphics/Rect;") instructions( + allOf(Opcode.IPUT_OBJECT(), field { definingClass type == "Landroid/graphics/Path;" }), fieldAccess( opcode = Opcode.IPUT_OBJECT, definingClass = "this", diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt index c23e40bc5..e47d0d490 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt @@ -7,22 +7,22 @@ import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags -internal val BytecodePatchContext.googlePlayUtilityMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.googlePlayUtilityMethod by gettingFirstMethodDeclaratively( + "This should never happen.", + "MetadataValueReader", + "com.google.android.gms", +) { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returnType("I") parameterTypes("L", "I") - strings( - "This should never happen.", - "MetadataValueReader", - "com.google.android.gms", - ) } -internal val BytecodePatchContext.serviceCheckMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.serviceCheckMethod by gettingFirstMethodDeclaratively( + "Google Play Services not available", +) { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returnType("V") parameterTypes("L", "I") - strings("Google Play Services not available") } internal val BytecodePatchContext.gmsCoreSupportMethod by gettingFirstMethodDeclaratively { diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt index 0e89e1293..aa35b7ad6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt @@ -1,22 +1,24 @@ package app.revanced.patches.tiktok.misc.settings -internal val BytecodePatchContext.addSettingsEntryMethod by gettingFirstMethodDeclaratively { - custom { method, classDef -> - classDef.endsWith("/SettingNewVersionFragment;") && - method.name == "initUnitManger" - } +import app.revanced.patcher.definingClass +import app.revanced.patcher.gettingFirstMethodDeclaratively +import app.revanced.patcher.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.name +import app.revanced.patcher.patch.BytecodePatchContext + +internal val BytecodePatchContext.addSettingsEntryMethod by gettingFirstMutableMethodDeclaratively { + name("initUnitManger") + definingClass { endsWith("/SettingNewVersionFragment;") } } -internal val BytecodePatchContext.adPersonalizationActivityOnCreateMethod by gettingFirstMethodDeclaratively { - custom { method, classDef -> - classDef.endsWith("/AdPersonalizationActivity;") && - method.name == "onCreate" - } +internal val BytecodePatchContext.adPersonalizationActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively { + name("onCreate") + definingClass { endsWith("/AdPersonalizationActivity;") } } -internal val BytecodePatchContext.settingsEntryMethod by gettingFirstMethodDeclaratively { - strings("pls pass item or extends the EventUnit") -} +internal val BytecodePatchContext.settingsEntryMethod by gettingFirstMethodDeclaratively( + "pls pass item or extends the EventUnit", +) internal val BytecodePatchContext.settingsEntryInfoMethod by gettingFirstMethodDeclaratively { strings( diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt index ea72f61e2..f528c456f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/SettingsPatch.kt @@ -1,16 +1,13 @@ package app.revanced.patches.tiktok.misc.settings -import app.revanced.patcher.extensions.ExternalLabel -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.extensions.* +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.shared.layout.branding.addBrandLicensePatch import app.revanced.patches.tiktok.misc.extension.sharedExtensionPatch +import app.revanced.util.indexOfFirstInstruction import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c -import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/tiktok/settings/TikTokActivityHook;" @@ -37,16 +34,16 @@ val Settings by creatingBytecodePatch( "Ljava/lang/String;" + ")Ljava/lang/Object;" - fun String.toClassName(): String = substring(1, this.length - 1).replace("/", ".") + fun String.toClassName() = substring(1, this.length - 1).replace("/", ".") // Find the class name of classes which construct a settings entry - val settingsButtonClass = settingsEntryMethod.originalClassDef.type.toClassName() - val settingsButtonInfoClass = settingsEntryInfoMethod.originalClassDef.type.toClassName() + val settingsButtonClass = settingsEntryMethod.immutableClassDef.type.toClassName() + val settingsButtonInfoClass = settingsEntryInfoMethod.immutableClassDef.type.toClassName() // Create a settings entry for 'revanced settings' and add it to settings fragment addSettingsEntryMethod.apply { - val markIndex = implementation!!.instructions.indexOfFirst { - it.opcode == Opcode.IGET_OBJECT && ((it as Instruction22c).reference as FieldReference).name == "headerUnit" + val markIndex = indexOfFirstInstruction { + opcode == Opcode.IGET_OBJECT && fieldReference?.name == "headerUnit" } val getUnitManager = getInstruction(markIndex + 2) @@ -67,24 +64,22 @@ val Settings by creatingBytecodePatch( const-string v1, "$settingsButtonInfoClass" invoke-static {v0, v1}, $createSettingsEntryMethodDescriptor move-result-object v0 - check-cast v0, ${settingsEntryMethod.originalClassDef.type} + check-cast v0, ${settingsEntryMethod.immutableClassDef.type} """, ) } // Initialize the settings menu once the replaced setting entry is clicked. adPersonalizationActivityOnCreateMethod.apply { - val initializeSettingsIndex = implementation!!.instructions.indexOfFirst { - it.opcode == Opcode.INVOKE_SUPER - } + 1 + val initializeSettingsIndex = indexOfFirstInstruction(Opcode.INVOKE_SUPER) + 1 - val thisRegister = getInstruction(initializeSettingsIndex - 1).registerC + val thisRegister = getInstruction(initializeSettingsIndex - 1).registerC val usableRegister = implementation!!.registerCount - parameters.size - 2 addInstructionsWithLabels( initializeSettingsIndex, """ - invoke-static {v$thisRegister}, $initializeSettingsMethodDescriptor + invoke-static { v$thisRegister }, $initializeSettingsMethodDescriptor move-result v$usableRegister if-eqz v$usableRegister, :do_not_open return-void diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/AudioAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/AudioAdsPatch.kt index 45d5e17f7..58b2f2d35 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/AudioAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/audio/AudioAdsPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.Settings +@Suppress("unused", "ObjectPropertyName") val `Block audio ads` by creatingBytecodePatch( description = "Blocks audio ads in streams and VODs.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/EmbeddedAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/EmbeddedAdsPatch.kt index 4757e189f..5fd7e5d0e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/EmbeddedAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/embedded/EmbeddedAdsPatch.kt @@ -9,6 +9,7 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.Settings +@Suppress("unused", "ObjectPropertyName") val `Block embedded ads` by creatingBytecodePatch( description = "Blocks embedded stream ads using services like Luminous or PurpleAdBlocker.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/VideoAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/VideoAdsPatch.kt index 3ea81ce17..cd9828699 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/VideoAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/video/VideoAdsPatch.kt @@ -14,6 +14,7 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.Settings +@Suppress("ObjectPropertyName") val `Block video ads` by creatingBytecodePatch( description = "Blocks video ads in streams and VODs.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/ShowDeletedMessagesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/ShowDeletedMessagesPatch.kt index 6b615c89f..418636827 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/ShowDeletedMessagesPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/ShowDeletedMessagesPatch.kt @@ -12,6 +12,7 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.Settings +@Suppress("unused", "ObjectPropertyName") val `Show deleted messages` by creatingBytecodePatch( description = "Shows deleted chat messages behind a clickable spoiler.", ) { @@ -33,7 +34,7 @@ val `Show deleted messages` by creatingBytecodePatch( addResources("twitch", "chat.antidelete.showDeletedMessagesPatch") PreferenceScreen.CHAT.GENERAL.addPreferences( - ListPreference("revanced_show_deleted_messages") + ListPreference("revanced_show_deleted_messages"), ) // Spoiler mode: Force set hasModAccess member to true in constructor diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/AutoClaimChannelPointsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/AutoClaimChannelPointsPatch.kt index c97c78aa5..178997012 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/AutoClaimChannelPointsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/chat/autoclaim/AutoClaimChannelPointsPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.Settings +@Suppress("unused", "ObjectPropertyName") val `Auto claim channel points` by creatingBytecodePatch( description = "Automatically claim Channel Points.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/debug/DebugModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/debug/DebugModePatch.kt index 7f946d6be..f8adc81c1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/debug/DebugModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/debug/DebugModePatch.kt @@ -9,6 +9,7 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch import app.revanced.patches.twitch.misc.settings.PreferenceScreen import app.revanced.patches.twitch.misc.settings.Settings +@Suppress("ObjectPropertyName") val `Debug mode` by creatingBytecodePatch( description = "Enables Twitch's internal debugging mode.", use = false, diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt index 21785aaf6..6c2c048f3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt @@ -1,9 +1,11 @@ package app.revanced.patches.twitch.misc.settings +import app.revanced.patcher.classDef import app.revanced.patcher.extensions.ExternalLabel import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructionsWithLabels import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.extensions.instructions import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch @@ -13,6 +15,7 @@ import app.revanced.patches.twitch.misc.extension.sharedExtensionPatch import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.immutable.ImmutableField import com.android.tools.smali.dexlib2.mutable.MutableField.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableMethod private const val REVANCED_SETTINGS_MENU_ITEM_NAME = "RevancedSettings" private const val REVANCED_SETTINGS_MENU_ITEM_ID = 0x7 @@ -68,23 +71,22 @@ val Settings by creatingBytecodePatch( ) // Hook onCreate to handle fragment creation. - val insertIndex = settingsActivityOnCreateFingerprint.method.implementation!!.instructions.size - 2 - settingsActivityOnCreateFingerprint.method.addInstructionsWithLabels( - insertIndex, - """ - 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 - """, - ExternalLabel( - "no_rv_settings_init", - settingsActivityOnCreateFingerprint.method.getInstruction(insertIndex), - ), - ) + settingsActivityOnCreateMethod.apply { + val insertIndex = instructions.size - 2 + addInstructionsWithLabels( + insertIndex, + """ + 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 + """, + ExternalLabel("no_rv_settings_init", getInstruction(insertIndex)), + ) + } // Create new menu item for settings menu. - fun Fingerprint.injectMenuItem( + fun MutableMethod.injectMenuItem( name: String, value: Int, titleResourceName: String, @@ -93,7 +95,7 @@ val Settings by creatingBytecodePatch( // Add new static enum member field classDef.staticFields.add( ImmutableField( - method.definingClass, + definingClass, name, MENU_ITEM_ENUM_CLASS_DESCRIPTOR, AccessFlags.PUBLIC.value or @@ -107,8 +109,8 @@ val Settings by creatingBytecodePatch( ) // Add initializer for the new enum member - method.addInstructions( - method.implementation!!.instructions.size - 4, + addInstructions( + instructions.size - 4, """ new-instance v0, $MENU_ITEM_ENUM_CLASS_DESCRIPTOR const-string v1, "$titleResourceName" @@ -125,7 +127,7 @@ val Settings by creatingBytecodePatch( ) } - settingsMenuItemEnumFingerprint.injectMenuItem( + settingsMenuItemEnumMethod.injectMenuItem( REVANCED_SETTINGS_MENU_ITEM_NAME, REVANCED_SETTINGS_MENU_ITEM_ID, REVANCED_SETTINGS_MENU_ITEM_TITLE_RES, @@ -133,7 +135,7 @@ val Settings by creatingBytecodePatch( ) // Intercept settings menu creation and add new menu item. - menuGroupsUpdatedFingerprint.method.addInstructions( + menuGroupsUpdatedMethod.addInstructions( 0, """ sget-object v0, $MENU_ITEM_ENUM_CLASS_DESCRIPTOR->$REVANCED_SETTINGS_MENU_ITEM_NAME:$MENU_ITEM_ENUM_CLASS_DESCRIPTOR diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt index 6bced697f..ccde361f9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch +@Suppress("ObjectPropertyName") val `Video ads` by creatingBytecodePatch( description = "Adds an option to remove ads in the video player.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt index 23e284848..910c6b507 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt @@ -14,6 +14,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/RemoveViewerDiscretionDialogPatch;" +@Suppress("unused", "ObjectPropertyName") val `Remove viewer discretion dialog` by creatingBytecodePatch( description = "Adds an option to remove the dialog that appears when opening a video that has been age-restricted " + "by accepting it automatically. This does not bypass the age restriction.", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt index cceba6128..5da5f272c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt @@ -3,6 +3,9 @@ package app.revanced.patches.youtube.interaction.seekbar import app.revanced.patcher.accessFlags import app.revanced.patcher.after import app.revanced.patcher.afterAtMost +import app.revanced.patcher.allOf +import app.revanced.patcher.custom +import app.revanced.patcher.field import app.revanced.patcher.fieldAccess import app.revanced.patcher.firstMethodComposite import app.revanced.patcher.firstMutableMethodDeclaratively @@ -10,13 +13,16 @@ import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.gettingFirstMutableMethodDeclaratively import app.revanced.patcher.instructions import app.revanced.patcher.invoke +import app.revanced.patcher.method import app.revanced.patcher.methodCall +import app.revanced.patcher.name import app.revanced.patcher.newInstance import app.revanced.patcher.opcode import app.revanced.patcher.opcodes import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.returnType +import app.revanced.patcher.type import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_19_or_greater @@ -126,24 +132,22 @@ internal val BytecodePatchContext.onTouchEventHandlerMethod by gettingFirstMetho } internal val BytecodePatchContext.seekbarTappingMethod by gettingFirstMethodDeclaratively { + name("onTouchEvent") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("Z") parameterTypes("Landroid/view/MotionEvent;") instructions( - Int.MAX_VALUE(), - - newInstance("Landroid/graphics/Point;"), - methodCall(smali = "Landroid/graphics/Point;->(II)V", after()), + Int.MAX_VALUE.toLong()(), + allOf(Opcode.NEW_INSTANCE, type("Landroid/graphics/Point;")), + after(method { toString() == "Landroid/graphics/Point;->(II)V" }), methodCall( smali = "Lj\$/util/Optional;->of(Ljava/lang/Object;)Lj\$/util/Optional;", after(), ), after(Opcode.MOVE_RESULT_OBJECT()), - fieldAccess(opcode = Opcode.IPUT_OBJECT, type = "Lj\$/util/Optional;", after()), - + after(allOf(Opcode.IPUT_OBJECT(), field { type == "Lj\$/util/Optional;" })), afterAtMost(10, Opcode.INVOKE_VIRTUAL()), ) - custom { method, _ -> method.name == "onTouchEvent" } } internal val BytecodePatchContext.slideToSeekMethod by gettingFirstMethodDeclaratively { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt index da4012184..3bf3f340f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt @@ -12,6 +12,7 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableAutoCaptionsPatch;" +@Suppress("unused", "ObjectPropertyName") val `Disable auto captions` by creatingBytecodePatch( description = "Adds an option to disable captions from being automatically enabled.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt index 3972b3e2d..6ed433706 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt @@ -13,6 +13,7 @@ import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import java.util.logging.Logger +@Suppress("unused", "ObjectPropertyName") val `Hide video action buttons` by creatingResourcePatch( description = "Adds options to hide action buttons (such as the Download button) under videos.", ) { @@ -29,7 +30,7 @@ val `Hide video action buttons` by creatingResourcePatch( "20.14.43", "20.21.37", // 20.22+ does not yet support hiding all player buttons. - ) + ), ) apply { @@ -48,9 +49,9 @@ val `Hide video action buttons` by creatingResourcePatch( // the buffer is the same for all buttons. Logger.getLogger(this::class.java.name).warning( "\n!!!" + - "\n!!! Not all player action buttons can be set hidden when patching 20.22+" + - "\n!!! Patch 20.21.37 or lower if you want to hide player action buttons" + - "\n!!!" + "\n!!! Not all player action buttons can be set hidden when patching 20.22+" + + "\n!!! Patch 20.21.37 or lower if you want to hide player action buttons" + + "\n!!!", ) } else { preferences.addAll( @@ -65,15 +66,15 @@ val `Hide video action buttons` by creatingResourcePatch( SwitchPreference("revanced_hide_shop_button"), SwitchPreference("revanced_hide_stop_ads_button"), SwitchPreference("revanced_hide_thanks_button"), - ) + ), ) } PreferenceScreen.PLAYER.addPreferences( PreferenceScreenPreference( "revanced_hide_buttons_screen", - preferences = preferences - ) + preferences = preferences, + ), ) addLithoFilter("Lapp/revanced/extension/youtube/patches/components/ButtonsFilter;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt index 7fe350a9d..ca5df570b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt @@ -1,23 +1,23 @@ package app.revanced.patches.youtube.layout.buttons.navigation import app.revanced.patcher.accessFlags -import app.revanced.patcher.addString +import app.revanced.patcher.after +import app.revanced.patcher.firstMethodComposite import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.instructions import app.revanced.patcher.invoke import app.revanced.patcher.methodCall -import app.revanced.patcher.opcode import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val BytecodePatchContext.addCreateButtonViewMethod by gettingFirstMethodDeclaratively { +internal val addCreateButtonViewMethodMatch = firstMethodComposite { instructions( "Android Wear"(), Opcode.IF_EQZ(), - addString("Android Automotive", after()), + after("Android Automotive"()), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt index b12c1463a..1b4e8bf46 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt @@ -24,6 +24,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/NavigationButtonsPatch;" +@Suppress("ObjectPropertyName") val `Navigation buttons` by creatingBytecodePatch( description = "Adds options to hide and change navigation buttons (such as the Shorts button).", ) { @@ -81,20 +82,18 @@ val `Navigation buttons` by creatingBytecodePatch( ) // Switch create with notifications button. - addCreateButtonViewMethod.let { - it.method.apply { - val conditionalCheckIndex = it.instructionMatches[1].index - val conditionRegister = - getInstruction(conditionalCheckIndex).registerA + addCreateButtonViewMethodMatch.method.apply { + val conditionalCheckIndex = addCreateButtonViewMethodMatch.indices[1] + val conditionRegister = + getInstruction(conditionalCheckIndex).registerA - addInstructions( - conditionalCheckIndex, - """ - invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->switchCreateWithNotificationButton()Z - move-result v$conditionRegister - """, - ) - } + addInstructions( + conditionalCheckIndex, + """ + invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->switchCreateWithNotificationButton()Z + move-result v$conditionRegister + """, + ) } // Hide navigation button labels. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt index c985ae2a8..13be827da 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt @@ -17,6 +17,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableFullscreenAmbientModePatch;" +@Suppress("unused", "ObjectPropertyName") val `Disable fullscreen ambient mode` by creatingBytecodePatch( description = "Adds an option to disable the ambient mode when in fullscreen.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index 6fe144116..c90f0c7cd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -79,6 +79,7 @@ private const val CUSTOM_FILTER_CLASS_NAME = private const val KEYWORD_FILTER_CLASS_NAME = "Lapp/revanced/extension/youtube/patches/components/KeywordContentFilter;" +@Suppress("unused", "ObjectPropertyName") val `Hide layout components` by creatingBytecodePatch( description = "Adds options to hide general layout components.", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt index a033e9002..360514736 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch +@Suppress("unused", "ObjectPropertyName") val `Hide player flyout menu items` by creatingBytecodePatch( description = "Adds options to hide menu items that appear when pressing the gear icon in the video player.", ) { @@ -27,7 +28,7 @@ val `Hide player flyout menu items` by creatingBytecodePatch( "20.14.43", "20.21.37", "20.31.40", - ) + ), ) apply { @@ -50,7 +51,7 @@ val `Hide player flyout menu items` by creatingBytecodePatch( SwitchPreference("revanced_hide_player_flyout_lock_screen"), SwitchPreference( key = "revanced_hide_player_flyout_audio_track", - tag = "app.revanced.extension.youtube.settings.preference.HideAudioFlyoutMenuPreference" + tag = "app.revanced.extension.youtube.settings.preference.HideAudioFlyoutMenuPreference", ), SwitchPreference("revanced_hide_player_flyout_watch_in_vr"), SwitchPreference("revanced_hide_player_flyout_sleep_timer"), diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt index 0fe8993b4..5cac53d57 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt @@ -17,6 +17,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableRollingNumberAnimationsPatch;" +@Suppress("unused", "ObjectPropertyName") val `Disable rolling number animations` by creatingBytecodePatch( description = "Adds an option to disable rolling number animations of video view count, user likes, and upload time.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt index 63809b5a1..780e01202 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt @@ -13,6 +13,7 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableSignInToTvPopupPatch;" +@Suppress("unused", "ObjectPropertyName") val `Disable sign in to TV popup` by creatingBytecodePatch( description = "Adds an option to disable the popup asking to sign into a TV on the same local network.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt index 7ce772e4e..f641db414 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/Fingerprints.kt @@ -1,16 +1,7 @@ package app.revanced.patches.youtube.layout.hide.time -import app.revanced.patcher.accessFlags -import app.revanced.patcher.after -import app.revanced.patcher.fieldAccess -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.instructions -import app.revanced.patcher.invoke -import app.revanced.patcher.methodCall -import app.revanced.patcher.opcode -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -20,20 +11,11 @@ internal val BytecodePatchContext.timeCounterMethod by gettingFirstMethodDeclara parameterTypes() instructions( Opcode.SUB_LONG_2ADDR(), - methodCall( - opcode = Opcode.INVOKE_STATIC, - returnType = "Ljava/lang/CharSequence;", - after(), - ), + after(allOf(Opcode.INVOKE_STATIC(), method { returnType == "Ljava/lang/CharSequence;" })), after(Opcode.MOVE_RESULT_OBJECT()), - fieldAccess(opcode = Opcode.IGET_WIDE, type = "J", after()), - fieldAccess(opcode = Opcode.IGET_WIDE, type = "J", after()), + after(allOf(Opcode.IGET_WIDE(), field { type == "J" })), + after(allOf(Opcode.IGET_WIDE(), field { type == "J" })), after(Opcode.SUB_LONG_2ADDR()), - - methodCall( - opcode = Opcode.INVOKE_STATIC, - returnType = "Ljava/lang/CharSequence;", - afterAtMost(5), - ), + afterAtMost(5, allOf(Opcode.INVOKE_STATIC(), method { returnType == "Ljava/lang/CharSequence;" })), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt index 4569bd697..9d352fc5e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/HideTimestampPatch;" +@Suppress("unused", "ObjectPropertyName") val `Hide timestamp` by creatingBytecodePatch( description = "Adds an option to hide the timestamp in the bottom left of the video player.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt index 58bd75c8d..98277e264 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/Fingerprints.kt @@ -1,9 +1,12 @@ package app.revanced.patches.youtube.layout.panels.popup -internal val BytecodePatchContext.engagementPanelControllerMethod by gettingFirstMethodDeclaratively { +import app.revanced.patcher.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.returnType + +internal val BytecodePatchContext.engagementPanelControllerMethod by gettingFirstMutableMethodDeclaratively( + "EngagementPanelController: cannot show EngagementPanel before EngagementPanelController.init() has been called.", + "[EngagementPanel] Cannot show EngagementPanel before EngagementPanelController.init() has been called.", +) { returnType("L") - strings( - "EngagementPanelController: cannot show EngagementPanel before EngagementPanelController.init() has been called.", - "[EngagementPanel] Cannot show EngagementPanel before EngagementPanelController.init() has been called.", - ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt index 7f1e1d758..26d94bd55 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisablePlayerPopupPanelsPatch;" +@Suppress("unused", "ObjectPropertyName") val `Disable player popup panels` by creatingBytecodePatch( description = "Adds an option to disable panels (such as live chat) from opening automatically.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt index 95a783b50..690ec2f39 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/Fingerprints.kt @@ -1,17 +1,7 @@ package app.revanced.patches.youtube.layout.player.fullscreen -import app.revanced.patcher.accessFlags -import app.revanced.patcher.after -import app.revanced.patcher.afterAtMost -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.instructions -import app.revanced.patcher.invoke -import app.revanced.patcher.literal -import app.revanced.patcher.opcode -import app.revanced.patcher.opcodes -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -24,7 +14,7 @@ internal val BytecodePatchContext.openVideosFullscreenPortraitMethod by gettingF instructions( Opcode.MOVE_RESULT(), // Conditional check to modify. // Open videos fullscreen portrait feature flag. - literal(45666112L, afterAtMost(5)), // Cannot be more than 5. + afterAtMost(5, 45666112L()), // Cannot be more than 5. afterAtMost(10, Opcode.MOVE_RESULT()), ) } @@ -51,11 +41,10 @@ internal val BytecodePatchContext.openVideosFullscreenPortraitLegacyMethod by ge ) } -internal val BytecodePatchContext.openVideosFullscreenHookPatchExtensionMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.openVideosFullscreenHookPatchExtensionMethod by gettingFirstMutableMethodDeclaratively { + name("isFullScreenPatchIncluded") + definingClass(EXTENSION_CLASS_DESCRIPTOR) accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returnType("Z") parameterTypes() - custom { methodDef, classDef -> - methodDef.name == "isFullScreenPatchIncluded" && classDef.type == EXTENSION_CLASS_DESCRIPTOR - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt index 4460c13cf..48990d27a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt @@ -40,6 +40,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/ReturnYouTubeDislikeFilter;" +@Suppress("ObjectPropertyName") val `Return YouTube Dislike` by creatingBytecodePatch( description = "Adds an option to show the dislike count of videos with Return YouTube Dislike.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt index 1e381416c..1d2e6a405 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt @@ -24,6 +24,7 @@ import java.util.logging.Logger private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/WideSearchbarPatch;" +@Suppress("unused", "ObjectPropertyName") val `Wide search bar` by creatingBytecodePatch( description = "Adds an option to replace the search icon with a wide search bar. " + "This will hide the YouTube logo when active.", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt index 22b483eed..c67b52a7f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/Fingerprints.kt @@ -1,10 +1,13 @@ package app.revanced.patches.youtube.layout.shortsautoplay import app.revanced.patcher.accessFlags -import app.revanced.patcher.addString -import app.revanced.patcher.fieldAccess +import app.revanced.patcher.afterAtMost +import app.revanced.patcher.field +import app.revanced.patcher.firstMethodComposite import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.instructions +import app.revanced.patcher.invoke +import app.revanced.patcher.method import app.revanced.patcher.methodCall import app.revanced.patcher.opcode import app.revanced.patcher.parameterTypes @@ -13,7 +16,7 @@ import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val BytecodePatchContext.reelEnumConstructorMethod by gettingFirstMethodDeclaratively { +internal val reelEnumConstructorMethodMatch = firstMethodComposite { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) instructions( "REEL_LOOP_BEHAVIOR_UNKNOWN"(), @@ -38,24 +41,23 @@ internal val BytecodePatchContext.reelPlaybackRepeatParentMethod by gettingFirst internal val BytecodePatchContext.reelPlaybackRepeatMethod by gettingFirstMethodDeclaratively { returnType("V") parameterTypes("L") - instructions( - methodCall(smali = "Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z"), - ) + instructions(method { toString() == "Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z" }) } -internal val BytecodePatchContext.reelPlaybackMethod by gettingFirstMethodDeclaratively { +internal val reelPlaybackMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameterTypes("J") returnType("V") + + val methodParametersPrefix = listOf("I", "L", "L") instructions( - fieldAccess( - definingClass = "Ljava/util/concurrent/TimeUnit;", - name = "MILLISECONDS", - ), - methodCall( - name = "", - parameters = listOf("I", "L", "L"), - afterAtMost(15), + field { definingClass == "Ljava/util/concurrent/TimeUnit;" && name == "MILLISECONDS" }, + afterAtMost( + 15, + method { + name == "" && + parameterTypes.zip(methodParametersPrefix).all { (a, b) -> a.startsWith(b) } + }, ), methodCall( opcode = Opcode.INVOKE_VIRTUAL, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt index 4daca3918..0303a3afe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt @@ -4,6 +4,8 @@ import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructionsWithLabels import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.extensions.methodReference +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.shared.misc.mapping.resourceMappingPatch @@ -72,11 +74,11 @@ val `Shorts autoplay` by creatingBytecodePatch( var reelEnumClass: String - reelEnumConstructorMethod.let { - reelEnumClass = it.originalClassDef.type + reelEnumConstructorMethodMatch.apply { + reelEnumClass = immutableClassDef.type - it.method.addInstructions( - it.indices.last(), + method.addInstructions( + indices.last(), """ # Pass the first enum value to extension. # Any enum value of this type will work. @@ -87,7 +89,7 @@ val `Shorts autoplay` by creatingBytecodePatch( } reelPlaybackRepeatMethod.match( - reelPlaybackRepeatParentMethod.originalClassDef, + reelPlaybackRepeatParentMethod.immutableClassDef, ).method.apply { // The behavior enums are looked up from an ordinal value to an enum type. findInstructionIndicesReversedOrThrow { @@ -112,10 +114,10 @@ val `Shorts autoplay` by creatingBytecodePatch( // Manually restore the removed 'Autoplay' code. if (is_20_09_or_greater) { // Variable names are only a rough guess of what these methods do. - val userActionMethodReference = reelPlaybackMethod.instructionMatches[1] - .getInstruction().reference as MethodReference - val reelSequenceControllerMethodReference = reelPlaybackMethod.instructionMatches[2] - .getInstruction().reference as MethodReference + val userActionMethodReference = + reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch.indices[1]).methodReference + val reelSequenceControllerMethodReference = + reelPlaybackMethodMatch.method.getInstruction(reelPlaybackMethodMatch.indices[2]).methodReference reelPlaybackRepeatMethod.apply { // Find the first call modified by extension code above. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt index fe0e6fd20..b27ba7362 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/Fingerprints.kt @@ -1,15 +1,7 @@ package app.revanced.patches.youtube.layout.spoofappversion -import app.revanced.patcher.accessFlags -import app.revanced.patcher.fieldAccess -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.instructions -import app.revanced.patcher.methodCall -import app.revanced.patcher.opcode -import app.revanced.patcher.opcodes -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import app.revanced.patches.shared.misc.mapping.ResourceType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -19,21 +11,22 @@ internal val BytecodePatchContext.toolBarButtonMethod by gettingFirstMethodDecla returnType("V") instructions( ResourceType.ID("menu_item_view"), - methodCall(returnType = "I", opcode = Opcode.INVOKE_INTERFACE), + allOf(Opcode.INVOKE_VIRTUAL(), method { returnType == "I" }), after(Opcode.MOVE_RESULT()), - fieldAccess(type = "Landroid/widget/ImageView;", opcode = Opcode.IGET_OBJECT, afterAtMost(6)), - methodCall("Landroid/content/res/Resources;", "getDrawable", afterAtMost(8)), - methodCall("Landroid/widget/ImageView;", "setImageDrawable", afterAtMost(4)), + afterAtMost(6, allOf(Opcode.IGET_OBJECT(), field { type == "Landroid/widget/ImageView;" })), + afterAtMost(8, method { name == "getDrawable" && definingClass == "Landroid/content/res/Resources;" }), + afterAtMost(4, method { name == "setImageDrawable" && definingClass == "Landroid/widget/ImageView;" }), ) - custom { method, _ -> - // 20.37+ has second parameter of "Landroid/content/Context;" - val parameterCount = method.parameterTypes.count() - (parameterCount == 1 || parameterCount == 2) && - method.parameterTypes.firstOrNull() == "Landroid/view/MenuItem;" - } + // 20.37+ has second parameter of "Landroid/content/Context;" + custom { parameterTypes.count() in 1..2 && parameterTypes.first() == "Landroid/view/MenuItem;" } } -internal val BytecodePatchContext.spoofAppVersionMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.spoofAppVersionMethod by gettingFirstMethodDeclaratively( + // Instead of applying a bytecode patch, it might be possible to only rely on code from the extension and + // manually set the desired version string as this keyed value in the SharedPreferences. + // But, this bytecode patch is simple and it works. + "pref_override_build_version_name", +) { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returnType("L") parameterTypes("L") @@ -42,8 +35,4 @@ internal val BytecodePatchContext.spoofAppVersionMethod by gettingFirstMethodDec Opcode.GOTO, Opcode.CONST_STRING, ) - // Instead of applying a bytecode patch, it might be possible to only rely on code from the extension and - // manually set the desired version string as this keyed value in the SharedPreferences. - // But, this bytecode patch is simple and it works. - strings("pref_override_build_version_name") } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt index d88a6548a..3898396c5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt @@ -23,6 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/spoof/SpoofAppVersionPatch;" +@Suppress("ObjectPropertyName") val `Spoof app version` by creatingBytecodePatch( description = "Adds an option to trick YouTube into thinking you are running an older version of the app. " + "This can be used to restore old UI elements and features.", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt index 8da6349f2..4f561a391 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt @@ -17,6 +17,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/ChangeStartPagePatch;" +@Suppress("unused", "ObjectPropertyName") val `Change start page` by creatingBytecodePatch( description = "Adds an option to set which page the app opens in instead of the homepage.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt index 2c24ca152..f9ca0c061 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt @@ -21,6 +21,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableResumingStartupShortsPlayerPatch;" +@Suppress("unused", "ObjectPropertyName") val `Disable resuming Shorts on startup` by creatingBytecodePatch( description = "Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt index 6a6199580..14534c41a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt @@ -19,6 +19,7 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/AlternativeThumbnailsPatch;" +@Suppress("unused", "ObjectPropertyName") val `Alternative thumbnails` by creatingBytecodePatch( description = "Adds options to replace video thumbnails using the DeArrow API or image captures from the video.", ) { @@ -36,7 +37,7 @@ val `Alternative thumbnails` by creatingBytecodePatch( "20.14.43", "20.21.37", "20.31.40", - ) + ), ) apply { @@ -48,27 +49,27 @@ val `Alternative thumbnails` by creatingBytecodePatch( ListPreference( key = "revanced_alt_thumbnail_home", entriesKey = entries, - entryValuesKey = values + entryValuesKey = values, ), ListPreference( key = "revanced_alt_thumbnail_subscription", entriesKey = entries, - entryValuesKey = values + entryValuesKey = values, ), ListPreference( key = "revanced_alt_thumbnail_library", entriesKey = entries, - entryValuesKey = values + entryValuesKey = values, ), ListPreference( key = "revanced_alt_thumbnail_player", entriesKey = entries, - entryValuesKey = values + entryValuesKey = values, ), ListPreference( key = "revanced_alt_thumbnail_search", entriesKey = entries, - entryValuesKey = values + entryValuesKey = values, ), NonInteractivePreference( "revanced_alt_thumbnail_dearrow_about", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt index a5792fcef..eaef4528e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt @@ -13,9 +13,10 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/BypassImageRegionRestrictionsPatch;" +@Suppress("unused", "ObjectPropertyName") val `Bypass image region restrictions` by creatingBytecodePatch( description = "Adds an option to use a different host for user avatar and channel images " + - "and can fix missing images that are blocked in some countries.", + "and can fix missing images that are blocked in some countries.", ) { dependsOn( sharedExtensionPatch, @@ -30,7 +31,7 @@ val `Bypass image region restrictions` by creatingBytecodePatch( "20.14.43", "20.21.37", "20.31.40", - ) + ), ) apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt index 77bc454de..e0c86058c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt @@ -26,6 +26,7 @@ internal var prefBackgroundAndOfflineCategoryId = -1L private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/BackgroundPlaybackPatch;" +@Suppress("unused", "ObjectPropertyName") val `Remove background playback restrictions` by creatingBytecodePatch( description = "Removes restrictions on background playback, including playing kids videos in the background.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt index d9091b4de..dc3f91e97 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt @@ -12,6 +12,7 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/spoof/SpoofDeviceDimensionsPatch;" +@Suppress("unused", "ObjectPropertyName") val `Spoof device dimensions` by creatingBytecodePatch( description = "Adds an option to spoof the device dimensions which can unlock higher video qualities.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt index 28bdf0007..4ae2e5eec 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt @@ -19,13 +19,13 @@ internal val fixContentProviderPatch = bytecodePatch { ) apply { - unstableContentProviderMethod.let { - val insertIndex = it.instructionMatches.first().index + unstableContentProviderMethodMatch.let { + val insertIndex = it.indices.first() it.method.apply { val register = getInstruction(insertIndex).registerD - it.method.addInstruction( + addInstruction( insertIndex, "invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->removeNullMapEntries(Ljava/util/Map;)V", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt index c600fd778..abac7f64a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt @@ -1,25 +1,15 @@ package app.revanced.patches.youtube.misc.fix.contentprovider -import app.revanced.patcher.accessFlags -import app.revanced.patcher.addString -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.instructions -import app.revanced.patcher.methodCall -import app.revanced.patcher.parameterTypes -import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType +import app.revanced.patcher.* import com.android.tools.smali.dexlib2.AccessFlags -internal val BytecodePatchContext.unstableContentProviderMethod by gettingFirstMethodDeclaratively { +internal val unstableContentProviderMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") parameterTypes("Landroid/content/ContentResolver;", "[Ljava/lang/String;") instructions( // Early targets use HashMap and later targets use ConcurrentMap. - methodCall( - name = "putAll", - parameters = listOf("Ljava/util/Map;"), - ), + method { name == "putAll" && parameterTypes.count() == 1 && parameterTypes.first() == "Ljava/util/Map;" }, "ContentProvider query returned null cursor"(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt index 02899bffb..f1c8a5ed2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt @@ -14,6 +14,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/BypassURLRedirectsPatch;" +@Suppress("unused", "ObjectPropertyName") val `Bypass URL redirects` by creatingBytecodePatch( description = "Adds an option to bypass URL redirects and open the original URL directly.", ) { @@ -41,22 +42,20 @@ val `Bypass URL redirects` by creatingBytecodePatch( arrayOf( if (is_20_37_or_greater) { - (abUriParserMethod to 2) + (abUriParserMethodMatch to 2) } else { - (abUriParserLegacyMethod to 2) + (abUriParserLegacyMethodMatch to 2) }, - httpUriParserMethod to 0, - ).forEach { (fingerprint, index) -> - fingerprint.method.apply { - val insertIndex = fingerprint.instructionMatches[index].index - val uriStringRegister = getInstruction(insertIndex).registerC + httpUriParserMethodMatch to 0, + ).forEach { (match, index) -> + val insertIndex = match.indices[index] + val uriStringRegister = match.method.getInstruction(insertIndex).registerC - replaceInstruction( - insertIndex, - "invoke-static { v$uriStringRegister }, $EXTENSION_CLASS_DESCRIPTOR->" + - "parseRedirectUri(Ljava/lang/String;)Landroid/net/Uri;", - ) - } + match.method.replaceInstruction( + insertIndex, + "invoke-static { v$uriStringRegister }, $EXTENSION_CLASS_DESCRIPTOR->" + + "parseRedirectUri(Ljava/lang/String;)Landroid/net/Uri;", + ) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt index 8ee6b26da..59fa513a9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt @@ -3,18 +3,18 @@ package app.revanced.patches.youtube.misc.links import app.revanced.patcher.StringComparisonType import app.revanced.patcher.accessFlags import app.revanced.patcher.addString +import app.revanced.patcher.firstMethodComposite import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.instructions import app.revanced.patcher.methodCall import app.revanced.patcher.parameterTypes -import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags /** * 20.36 and lower. */ -internal val BytecodePatchContext.abUriParserLegacyMethod by gettingFirstMethodDeclaratively { +internal val abUriParserLegacyMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("Ljava/lang/Object;") parameterTypes("Ljava/lang/Object;") @@ -28,7 +28,7 @@ internal val BytecodePatchContext.abUriParserLegacyMethod by gettingFirstMethodD /** * 20.37+ */ -internal val BytecodePatchContext.abUriParserMethod by gettingFirstMethodDeclaratively { +internal val abUriParserMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("Ljava/lang/Object;") parameterTypes("Ljava/lang/Object;") @@ -42,7 +42,7 @@ internal val BytecodePatchContext.abUriParserMethod by gettingFirstMethodDeclara ) } -internal val BytecodePatchContext.httpUriParserMethod by gettingFirstMethodDeclaratively { +internal val httpUriParserMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returnType("Landroid/net/Uri;") parameterTypes("Ljava/lang/String;") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt index c048bca39..1a4725025 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt @@ -10,6 +10,7 @@ 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.reference.StringReference +@Suppress("unused", "ObjectPropertyName") val `Open links externally` by creatingBytecodePatch( description = "Adds an option to always open links in your browser instead of the in-app browser.", ) { @@ -44,7 +45,7 @@ val `Open links externally` by creatingBytecodePatch( "20.14.43", "20.21.37", "20.31.40", - ) + ), ) apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt index a13eba09a..f878a9f0b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt @@ -1,16 +1,7 @@ package app.revanced.patches.youtube.misc.litho.filter -import app.revanced.patcher.accessFlags -import app.revanced.patcher.addString -import app.revanced.patcher.fieldAccess -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.instructions -import app.revanced.patcher.invoke -import app.revanced.patcher.methodCall -import app.revanced.patcher.opcodes -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import app.revanced.util.containsLiteralInstruction import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -23,26 +14,27 @@ internal val BytecodePatchContext.componentCreateMethod by gettingFirstMethodDec } internal val BytecodePatchContext.lithoFilterMethod by gettingFirstMethodDeclaratively { + definingClass { endsWith("/LithoFilterPatch;") } accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) - custom { _, classDef -> - classDef.endsWith("/LithoFilterPatch;") - } } internal val BytecodePatchContext.protobufBufferReferenceMethod by gettingFirstMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") parameterTypes("[B") + + var methodDefiningClass = "" + custom { + methodDefiningClass = definingClass + true + } + instructions( - fieldAccess( - opcode = Opcode.IGET_OBJECT, - definingClass = "this", - type = "Lcom/google/android/libraries/elements/adl/UpbMessage;", - ), - methodCall( - definingClass = "Lcom/google/android/libraries/elements/adl/UpbMessage;", - name = "jniDecode", + allOf( + Opcode.IGET_OBJECT(), + field { definingClass == methodDefiningClass && type == "Lcom/google/android/libraries/elements/adl/UpbMessage;" }, ), + method { definingClass == "Lcom/google/android/libraries/elements/adl/UpbMessage;" && name == "jniDecode" }, ) } @@ -61,20 +53,16 @@ internal val BytecodePatchContext.protobufBufferReferenceLegacyMethod by getting internal val BytecodePatchContext.emptyComponentMethod by gettingFirstMethodDeclaratively { accessFlags(AccessFlags.PRIVATE, AccessFlags.CONSTRUCTOR) parameterTypes() - instructions( - "EmptyComponent"(), - ) - custom { _, classDef -> - classDef.methods.filter { AccessFlags.STATIC.isSet(it.accessFlags) }.size == 1 - } + instructions("EmptyComponent"()) + custom { immutableClassDef.methods.filter { AccessFlags.STATIC.isSet(it.accessFlags) }.size == 1 } } internal val BytecodePatchContext.lithoThreadExecutorMethod by gettingFirstMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameterTypes("I", "I", "I") - custom { method, classDef -> - classDef.superclass == "Ljava/util/concurrent/ThreadPoolExecutor;" && - method.containsLiteralInstruction(1L) // 1L = default thread timeout. + custom { + immutableClassDef.superclass == "Ljava/util/concurrent/ThreadPoolExecutor;" && + containsLiteralInstruction(1L) // 1L = default thread timeout. } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt index 7a44dadbd..afe8ad9e5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/loopvideo/LoopVideoPatch.kt @@ -15,6 +15,7 @@ import com.android.tools.smali.dexlib2.Opcode private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/LoopVideoPatch;" +@Suppress("ObjectPropertyName") val `Loop video` by creatingBytecodePatch( description = "Adds an option to loop videos and display loop video button in the video player.", ) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt index ea38fa541..00ebe58ca 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt @@ -122,7 +122,7 @@ internal fun getSeekbarOnDrawMethodMatch() = firstMethodComposite { ) } -internal val BytecodePatchContext.subtitleButtonControllerMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.subtitleButtonControllerMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") parameterTypes("Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleTrack;")