From a71d1870c4f202f78232e1b9b2e742d5edd0a4c2 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:33:13 +0900 Subject: [PATCH] feat(Reddit): restrict support version --- .../patches/reddit/ad/general/AdsPatch.kt | 16 +- .../RecentlyVisitedShelfPatch.kt | 9 +- .../subredditdialog/SubRedditDialogPatch.kt | 6 +- .../reddit/utils/compatibility/Constants.kt | 8 +- .../reddit/utils/fix/BrokenResourcePatch.kt | 162 ++++++++++++++++++ .../utils/resourceid/SharedResourceIdPatch.kt | 3 +- .../utils/settings/SettingsBytecodePatch.kt | 30 +++- .../reddit/utils/settings/SettingsPatch.kt | 4 +- .../ResourceProviderFingerprint.kt | 11 ++ .../reddit/fix/host/values/attrs.xml | 63 +++++++ 10 files changed, 291 insertions(+), 21 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/reddit/utils/fix/BrokenResourcePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/ResourceProviderFingerprint.kt create mode 100644 src/main/resources/reddit/fix/host/values/attrs.xml diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/general/AdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/general/AdsPatch.kt index 7da7a8da3..be7f9945d 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/general/AdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/general/AdsPatch.kt @@ -2,9 +2,8 @@ package app.revanced.patches.reddit.ad.general import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patches.reddit.ad.banner.BannerAdsPatch import app.revanced.patches.reddit.ad.comments.CommentAdsPatch import app.revanced.patches.reddit.ad.general.fingerprints.AdPostFingerprint @@ -61,15 +60,12 @@ object AdsPatch : BaseBytecodePatch( NewAdPostFingerprint.resultOrThrow().let { it.mutableMethod.apply { val targetIndex = getTargetIndexWithMethodReferenceName("add") - val targetRegister = - getInstruction(targetIndex).registerD + 1 + val targetInstruction = getInstruction(targetIndex) - addInstructionsWithLabels( - targetIndex, """ - invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideNewPostAds()Z - move-result v$targetRegister - if-nez v$targetRegister, :show - """, ExternalLabel("show", getInstruction(targetIndex + 1)) + replaceInstruction( + targetIndex, + "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + + "$INTEGRATIONS_CLASS_DESCRIPTOR->hideNewPostAds(Ljava/util/ArrayList;Ljava/lang/Object;)V" ) } } diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt index 7f340813a..0d9a95a39 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt @@ -40,14 +40,17 @@ object RecentlyVisitedShelfPatch : BaseBytecodePatch( it.mutableClass.methods.find { method -> method.name == "" } ?.apply { - val recentlyVisitedFieldIndex = getTargetIndexWithFieldReferenceName("RECENTLY_VISITED") - val recentlyVisitedObjectIndex = getTargetIndex(recentlyVisitedFieldIndex, Opcode.IPUT_OBJECT) + val recentlyVisitedFieldIndex = + getTargetIndexWithFieldReferenceName("RECENTLY_VISITED") + val recentlyVisitedObjectIndex = + getTargetIndex(recentlyVisitedFieldIndex, Opcode.IPUT_OBJECT) recentlyVisitedReference = getInstruction(recentlyVisitedObjectIndex).reference } ?: throw PatchException("Constructor method not found!") it.mutableMethod.apply { - val recentlyVisitedObjectIndex = getTargetIndexWithReference(recentlyVisitedReference.toString()) + val recentlyVisitedObjectIndex = + getTargetIndexWithReference(recentlyVisitedReference.toString()) arrayOf( getTargetIndex(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC), getTargetIndexReversed(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC) diff --git a/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt index d120774e4..ebc2f2e65 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt @@ -40,7 +40,8 @@ object SubRedditDialogPatch : BaseBytecodePatch( FrequentUpdatesSheetScreenFingerprint.resultOrThrow().let { it.mutableMethod.apply { val cancelButtonViewIndex = getWideLiteralInstructionIndex(CancelButton) + 2 - val cancelButtonViewRegister = getInstruction(cancelButtonViewIndex).registerA + val cancelButtonViewRegister = + getInstruction(cancelButtonViewIndex).registerA addInstruction( cancelButtonViewIndex + 1, @@ -51,7 +52,8 @@ object SubRedditDialogPatch : BaseBytecodePatch( RedditAlertDialogsFingerprint.resultOrThrow().let { it.mutableMethod.apply { - val insertIndex = getWideLiteralInstructionIndex(TextAppearanceRedditBaseOldButtonColored) + 1 + val insertIndex = + getWideLiteralInstructionIndex(TextAppearanceRedditBaseOldButtonColored) + 1 val insertRegister = getInstruction(insertIndex).registerC addInstruction( diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt index b21b0c095..5f213c369 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt @@ -5,6 +5,12 @@ import app.revanced.patcher.patch.Patch object Constants { val COMPATIBLE_PACKAGE = setOf( - Patch.CompatiblePackage("com.reddit.frontpage") + Patch.CompatiblePackage( + "com.reddit.frontpage", + setOf( + "2023.12.0", + "2024.16.0" + ) + ) ) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/fix/BrokenResourcePatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/fix/BrokenResourcePatch.kt new file mode 100644 index 000000000..4ed344d1c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/fix/BrokenResourcePatch.kt @@ -0,0 +1,162 @@ +package app.revanced.patches.reddit.utils.fix + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.util.copyXmlNode +import app.revanced.util.doRecursively +import org.w3c.dom.Element + +@Patch( + description = "Replace resource formats that APKTool does not yet support decoding with hardcoded values.\n" + + "This method is not ideal, please remove this patch if APKTool will support decoding." +) +@Suppress("DEPRECATION", "unused") +object BrokenResourcePatch : ResourcePatch() { + private val attrsName = arrayOf( + "cornerFamily", + "cornerFamilyBottomLeft", + "cornerFamilyBottomRight", + "cornerFamilyTopLeft", + "labelBehavior", + "labelVisibilityMode", + "layout_constraintHorizontal_chainStyle", + "layout_constraintVertical_chainStyle", + "redditBaseTheme", + "showAsAction", + "surface_type" + ) + + private val styleMap = mapOf( + "redditBaseTheme\">0<" to "redditBaseTheme\">AlienBlue<", + "cornerFamilyBottomRight\">1<" to "cornerFamilyBottomRight\">cut<", + "cornerFamily\">1<" to "cornerFamily\">cut<", + "cornerFamilyTopLeft\">1<" to "cornerFamilyTopLeft\">cut<" + ) + + private val layoutXml = arrayOf( + "award_sheet_footer.xml", + "bottom_nav_item_normal.xml", + "comment_header.xml", + "comment_header_two_line.xml", + "custom_feed_community_list_item.xml", + "custom_feed_user_list_item.xml", + "dialog_award_info.xml", + "dialog_edit_overlay_text.xml", + "dialog_user_modal.xml", + "home_empty.xml", + "include_edit_ugc_custom_actions.xml", + "item_carousel_large.xml", + "item_comment_two_line_header.xml", + "item_community.xml", + "item_create_community.xml", + "item_pick_community.xml", + "item_subreddit.xml", + "item_topic.xml", + "layout_community_type.xml", + "layout_webembed_error.xml", + "legacy_comment_header.xml", + "link_carousel_item_subreddit_header.xml", + "link_carousel_subreddit_header.xml", + "listitem_community.xml", + "listitem_modtools_user_v2.xml", + "listitem_subreddit_with_status.xml", + "listitem_user_flair.xml", + "merge_button_wear_all.xml", + "merge_equipped_fab.xml", + "merge_link_footer.xml", + "merge_link_header_metadata.xml", + "merge_link_header_minimized_metadata.xml", + "post_header_card.xml", + "premium_marketing_perk_list_item.xml", + "premium_marketing_perk_tile.xml", + "premium_marketing_perk_tile_wide_highlighted.xml", + "promoted_user_post_list_item.xml", + "question_input_slider.xml", + "reddit_video_controls.xml", + "screen_confirm_recommended_snoovatar.xml", + "screen_copy_snoovatar.xml", + "screen_custom_feed.xml", + "screen_default_two_button_dialog.xml", + "screen_fullbleed_video.xml", + "screen_ratingsurvey_tag.xml", + "screen_share_and_download.xml", + "screen_vault_feed_empty_content.xml", + "setting_subredditnotiflevel.xml", + "toast.xml", + "trophy_item.xml", + "vault_toast.xml", + "video_user_profile_card.xml", + "view_video_controls.xml" + ) + private lateinit var context: ResourceContext + + override fun execute(context: ResourceContext) { + this.context = context + } + + internal fun fixBrokenResource() { + try { + styleMap.forEach { (from, to) -> + context["res/values/styles.xml"].apply { + writeText( + readText() + .replace( + from, + to + ) + ) + } + } + + layoutXml.forEach { file -> + val targetXml = context["res"].resolve("layout").resolve(file) + if (targetXml.exists()) { + context["res/layout/$file"].apply { + writeText( + readText() + .replace( + "chainStyle=\"2\"", + "chainStyle=\"packed\"" + ) + ) + } + } + } + + arrayOf( + "experiments_override_menu.xml", + "menu_protect_vault.xml" + ).forEach { file -> + val targetXml = context["res"].resolve("menu").resolve(file) + if (targetXml.exists()) { + context.xmlEditor["res/menu/$file"].use { editor -> + editor.file.doRecursively loop@{ + if (it !is Element) return@loop + + it.getAttributeNode("app:showAsAction")?.let { attribute -> + attribute.textContent = "ifRoom|withText" + } + } + } + } + } + + context.xmlEditor["res/values/attrs.xml"].use { editor -> + editor.file.doRecursively loop@{ + if (it !is Element) return@loop + + it.getAttributeNode("name")?.let { attribute -> + if (attrsName.indexOf(attribute.textContent) >= 0) { + it.parentNode?.removeChild(it) + } + } + } + } + } catch (_: Exception) { + } + + context.copyXmlNode("reddit/fix/host", "values/attrs.xml", "resources") + } + +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt index 1698293be..c431e709b 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt @@ -22,7 +22,8 @@ object SharedResourceIdPatch : ResourcePatch() { CancelButton = getId(ID, "cancel_button") LabelAcknowledgements = getId(STRING, "label_acknowledgements") ScreenShotShareBanner = getId(STRING, "screenshot_share_banner_title") - TextAppearanceRedditBaseOldButtonColored = getId(STYLE, "TextAppearance.RedditBase.OldButton.Colored") + TextAppearanceRedditBaseOldButtonColored = + getId(STYLE, "TextAppearance.RedditBase.OldButton.Colored") ToolBarNavSearchCtaContainer = getId(ID, "toolbar_nav_search_cta_container") } diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsBytecodePatch.kt index 238ee14ca..85593adac 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsBytecodePatch.kt @@ -8,24 +8,34 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.reddit.utils.fix.BrokenResourcePatch import app.revanced.patches.reddit.utils.integrations.Constants.INTEGRATIONS_PATH import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.LabelAcknowledgements import app.revanced.patches.reddit.utils.settings.fingerprints.AcknowledgementsLabelBuilderFingerprint import app.revanced.patches.reddit.utils.settings.fingerprints.OssLicensesMenuActivityOnCreateFingerprint +import app.revanced.patches.reddit.utils.settings.fingerprints.ResourceProviderFingerprint import app.revanced.patches.reddit.utils.settings.fingerprints.SettingsStatusLoadFingerprint import app.revanced.patches.shared.settings.fingerprints.SharedSettingFingerprint import app.revanced.util.getTargetIndex import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -@Patch(dependencies = [SharedResourceIdPatch::class]) +@Patch( + dependencies = [ + BrokenResourcePatch::class, + SharedResourceIdPatch::class + ] +) object SettingsBytecodePatch : BytecodePatch( setOf( AcknowledgementsLabelBuilderFingerprint, OssLicensesMenuActivityOnCreateFingerprint, + ResourceProviderFingerprint, SharedSettingFingerprint, SettingsStatusLoadFingerprint ) @@ -94,5 +104,23 @@ object SettingsBytecodePatch : BytecodePatch( settingsStatusLoadMethod = SettingsStatusLoadFingerprint.resultOrThrow().mutableMethod + /** + * Check version + */ + ResourceProviderFingerprint.result?.mutableMethod?.apply { + val versionIndex = indexOfFirstInstruction { + opcode == Opcode.CONST_STRING + && (this as? BuilderInstruction21c)?.reference.toString().startsWith("202") + } + if (versionIndex > -1) { + val versionNumber = getInstruction(versionIndex).reference.toString().replace(".", "").toInt() + val upward2024180 = versionNumber >= 2024180 + + if (upward2024180) { + BrokenResourcePatch.fixBrokenResource() + } + } + } + } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt index f73734a5f..4af6edaac 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt @@ -13,13 +13,12 @@ object SettingsPatch : BaseResourcePatch( description = "Adds ReVanced Extended settings to Reddit.", dependencies = setOf( IntegrationsPatch::class, - SettingsBytecodePatch::class + SettingsBytecodePatch::class, ), compatiblePackages = COMPATIBLE_PACKAGE, requiresIntegrations = true ) { override fun execute(context: ResourceContext) { - /** * Replace settings icon and label */ @@ -40,6 +39,5 @@ object SettingsPatch : BaseResourcePatch( ) ) } - } } diff --git a/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/ResourceProviderFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/ResourceProviderFingerprint.kt new file mode 100644 index 000000000..e3b890bfd --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/utils/settings/fingerprints/ResourceProviderFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.reddit.utils.settings.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object ResourceProviderFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + customFingerprint = { _, classDef -> classDef.sourceFile == "RedditInternalFeatures.kt" } +) \ No newline at end of file diff --git a/src/main/resources/reddit/fix/host/values/attrs.xml b/src/main/resources/reddit/fix/host/values/attrs.xml new file mode 100644 index 000000000..f8885be8d --- /dev/null +++ b/src/main/resources/reddit/fix/host/values/attrs.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +