diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt index e8ac32dc3..6f040ac24 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt @@ -1,5 +1,6 @@ package app.revanced.patches.reddit.layout.navigation +import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -8,6 +9,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.TypeReference internal val bottomNavScreenFingerprint = legacyFingerprint( name = "bottomNavScreenFingerprint", @@ -62,13 +64,32 @@ internal val bottomNavScreenOnGlobalLayoutFingerprint = legacyFingerprint( } ) +private const val CHAT_BUTTON_MAGIC_NUMBER = 1906671695L + internal val bottomNavScreenSetupBottomNavigationFingerprint = legacyFingerprint( name = "bottomNavScreenSetupBottomNavigationFingerprint", - returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, opcodes = listOf(Opcode.FILLED_NEW_ARRAY), customFingerprint = { method, classDef -> - classDef.type.startsWith("Lcom/reddit/launch/bottomnav/BottomNavScreen${'$'}setupBottomNavigation${'$'}") && - method.name == "invoke" + method.containsLiteralInstruction(CHAT_BUTTON_MAGIC_NUMBER) && + method.name == "invoke" && + indexOfButtonsArrayInstruction(method) >= 0 } ) + +internal val composeBottomNavScreenFingerprint = legacyFingerprint( + name = "composeBottomNavScreenFingerprint", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Landroid/content/res/Resources;"), + opcodes = listOf(Opcode.FILLED_NEW_ARRAY), + customFingerprint = { method, classDef -> + classDef.type == "Lcom/reddit/launch/bottomnav/ComposeBottomNavScreen;" && + indexOfButtonsArrayInstruction(method) >= 0 + } +) + +internal fun indexOfButtonsArrayInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.FILLED_NEW_ARRAY && + getReference()?.type?.startsWith("[Lcom/reddit/widget/bottomnav/") == true + } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt index dc86d0e56..473e2498d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt @@ -8,12 +8,12 @@ import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACK import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.HIDE_NAVIGATION_BUTTONS import app.revanced.patches.reddit.utils.settings.is_2024_26_or_greater +import app.revanced.patches.reddit.utils.settings.is_2025_06_or_greater import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.fingerprint.resolvable import app.revanced.util.indexOfFirstInstructionOrThrow -import app.revanced.util.indexOfFirstInstructionReversedOrThrow 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 @@ -34,17 +34,23 @@ val navigationButtonsPatch = bytecodePatch( execute { if (is_2024_26_or_greater) { - bottomNavScreenSetupBottomNavigationFingerprint.methodOrThrow().apply { - val arrayIndex = indexOfFirstInstructionReversedOrThrow(Opcode.FILLED_NEW_ARRAY) - val arrayRegister = - getInstruction(arrayIndex + 1).registerA + val fingerprints = mutableListOf(bottomNavScreenSetupBottomNavigationFingerprint) - addInstructions( - arrayIndex + 2, """ - invoke-static {v$arrayRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons([Ljava/lang/Object;)[Ljava/lang/Object; - move-result-object v$arrayRegister - """ - ) + if (is_2025_06_or_greater) fingerprints += composeBottomNavScreenFingerprint + + fingerprints.forEach { fingerprint -> + fingerprint.methodOrThrow().apply { + val arrayIndex = indexOfButtonsArrayInstruction(this) + val arrayRegister = + getInstruction(arrayIndex + 1).registerA + + addInstructions( + arrayIndex + 2, """ + invoke-static {v$arrayRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons([Ljava/lang/Object;)[Ljava/lang/Object; + move-result-object v$arrayRegister + """ + ) + } } } else { if (bottomNavScreenFingerprint.resolvable()) { diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt index 13767b47b..13cc83e84 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt @@ -1,9 +1,32 @@ package app.revanced.patches.reddit.layout.screenshotpopup +import app.revanced.patches.reddit.utils.resourceid.screenShotShareBanner +import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint +import com.android.tools.smali.dexlib2.Opcode +/** + * Reddit 2025.06.0 ~ + */ internal val screenshotTakenBannerFingerprint = legacyFingerprint( name = "screenshotTakenBannerFingerprint", + returnType = "L", + opcodes = listOf( + Opcode.CONST_4, + Opcode.IF_NE, + ), + customFingerprint = { method, classDef -> + method.containsLiteralInstruction(screenShotShareBanner) && + classDef.type.startsWith("Lcom/reddit/sharing/screenshot/composables/") && + method.name == "invoke" + } +) + +/** + * ~ Reddit 2025.05.1 + */ +internal val screenshotTakenBannerLegacyFingerprint = legacyFingerprint( + name = "screenshotTakenBannerLegacyFingerprint", returnType = "V", parameters = listOf("Landroidx/compose/runtime/", "I"), customFingerprint = { method, classDef -> diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt index 48f009c59..a8ceffdb9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt @@ -7,9 +7,17 @@ import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.DISABLE_SCREENSHOT_POPUP +import app.revanced.patches.reddit.utils.resourceid.screenShotShareBanner +import app.revanced.patches.reddit.utils.resourceid.sharedResourceIdPatch +import app.revanced.patches.reddit.utils.settings.is_2025_06_or_greater import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import app.revanced.util.indexOfFirstLiteralInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction private const val EXTENSION_METHOD_DESCRIPTOR = "$PATCHES_PATH/ScreenshotPopupPatch;->disableScreenshotPopup()Z" @@ -21,18 +29,39 @@ val screenshotPopupPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn(settingsPatch) + dependsOn( + settingsPatch, + sharedResourceIdPatch, + ) execute { - screenshotTakenBannerFingerprint.methodOrThrow().apply { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR - move-result v0 - if-eqz v0, :dismiss - return-void - """, ExternalLabel("dismiss", getInstruction(0)) - ) + + if (is_2025_06_or_greater) { + screenshotTakenBannerFingerprint.methodOrThrow().apply { + val literalIndex = indexOfFirstLiteralInstructionOrThrow(screenShotShareBanner) + val insertIndex = indexOfFirstInstructionReversedOrThrow(literalIndex, Opcode.CONST_4) + val insertRegister = getInstruction(insertIndex).registerA + val jumpIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.SGET_OBJECT) + + addInstructionsWithLabels( + insertIndex, """ + invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR + move-result v$insertRegister + if-nez v$insertRegister, :hidden + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + } + } else { + screenshotTakenBannerLegacyFingerprint.methodOrThrow().apply { + addInstructionsWithLabels( + 0, """ + invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR + move-result v0 + if-eqz v0, :dismiss + return-void + """, ExternalLabel("dismiss", getInstruction(0)) + ) + } } updatePatchStatus( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt new file mode 100644 index 000000000..8fcffa95d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt @@ -0,0 +1,23 @@ +package app.revanced.patches.reddit.utils.resourceid + +import app.revanced.patcher.patch.resourcePatch +import app.revanced.patches.shared.mapping.ResourceType.STRING +import app.revanced.patches.shared.mapping.get +import app.revanced.patches.shared.mapping.resourceMappingPatch +import app.revanced.patches.shared.mapping.resourceMappings + +var screenShotShareBanner = -1L + private set + +internal val sharedResourceIdPatch = resourcePatch( + description = "sharedResourceIdPatch" +) { + dependsOn(resourceMappingPatch) + + execute { + screenShotShareBanner = resourceMappings[ + STRING, + "screenshot_share_banner_title", + ] + } +} \ No newline at end of file