From b25413cb3b3e96779af80aa5cd08f5da5718c7a8 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:26:10 +0900 Subject: [PATCH] feat(YouTube/Hide general ads): add `Hide fullscreen ads` settings --- .../ads/fullscreen/FullscreenAdsPatch.kt | 102 ++++++++++++++++++ .../InterstitialsContainerFingerprint.kt | 10 ++ .../ShowDialogCommandFingerprint.kt | 9 ++ .../youtube/ads/general/GeneralAdsPatch.kt | 2 + .../ads/getpremium/HideGetPremiumPatch.kt | 6 +- .../utils/resourceid/SharedResourceIdPatch.kt | 5 + .../youtube/settings/host/values/strings.xml | 3 + .../youtube/settings/xml/revanced_prefs.xml | 1 + 8 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/FullscreenAdsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/InterstitialsContainerFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/ShowDialogCommandFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/FullscreenAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/FullscreenAdsPatch.kt new file mode 100644 index 000000000..43536c819 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/FullscreenAdsPatch.kt @@ -0,0 +1,102 @@ +package app.revanced.patches.youtube.ads.fullscreen + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.youtube.ads.fullscreen.fingerprints.InterstitialsContainerFingerprint +import app.revanced.patches.youtube.ads.fullscreen.fingerprints.ShowDialogCommandFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer +import app.revanced.util.exception +import app.revanced.util.getWideLiteralInstructionIndex +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch(dependencies = [SharedResourceIdPatch::class]) +object FullscreenAdsPatch : BytecodePatch( + setOf( + InterstitialsContainerFingerprint, + ShowDialogCommandFingerprint + ) +) { + private const val FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/AdsFilter;" + + override fun execute(context: BytecodeContext) { + /** + * Hides fullscreen ads + * Non-litho view, used in some old clients. + */ + InterstitialsContainerFingerprint.result?.let { + it.mutableMethod.apply { + val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2 + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $FILTER_CLASS_DESCRIPTOR->hideFullscreenAds(Landroid/view/View;)V" + ) + } + } ?: throw InterstitialsContainerFingerprint.exception + + /** + * Hides fullscreen ads + * Litho view, used in 'ShowDialogCommandOuterClass' in innertube + */ + ShowDialogCommandFingerprint.result?.let { + it.mutableMethod.apply { + // In this method, custom dialog is created and shown. + // There were no issues despite adding “return-void” to the first index. + // + // If an issue occurs due to patching due to server-side changes in the future, + // Find the instruction whose name is "show" in [MethodReference] and click the 'AlertDialog.BUTTON_POSITIVE' button. + // + // In this case, an instruction for 'getButton' must be added to smali, not in integrations + // (This custom dialog cannot be cast to [AlertDialog] or [Dialog]) + // + // See the comments below. + addInstructionsWithLabels( + 0, + """ + invoke-static {}, $FILTER_CLASS_DESCRIPTOR->hideFullscreenAds()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + + /* + val dialogIndex = getTargetIndexWithMethodReferenceName("show") + val dialogReference = getInstruction(dialogIndex).reference + val dialogDefiningClass = (dialogReference as MethodReference).definingClass + val getButtonMethod = context.findClass(dialogDefiningClass)!! + .mutableClass.methods.first { method -> + method.parameters == listOf("I") + && method.returnType == "Landroid/widget/Button;" + } + val getButtonCall = dialogDefiningClass + "->" + getButtonMethod.name + "(I)Landroid/widget/Button;" + + val dialogRegister = getInstruction(dialogIndex).registerC + val freeIndex = getTargetIndex(dialogIndex, Opcode.IF_EQZ) + val freeRegister = getInstruction(freeIndex).registerA + + addInstructions( + dialogIndex + 1, """ + # Get the 'AlertDialog.BUTTON_POSITIVE' from custom dialog + # Since this custom dialog cannot be cast to AlertDialog or Dialog, + # It should come from smali, not integrations. + const/4 v$freeRegister, -0x1 + invoke-virtual {v$dialogRegister, $freeRegister}, $getButtonCall + move-result-object $freeRegister + invoke-static {$freeRegister}, $FULLSCREEN_ADS_CLASS_DESCRIPTOR->confirmDialog(Landroid/widget/Button;)V + """ + ) + */ + } + } ?: throw ShowDialogCommandFingerprint.exception + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/InterstitialsContainerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/InterstitialsContainerFingerprint.kt new file mode 100644 index 000000000..deed3788d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/InterstitialsContainerFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.youtube.ads.fullscreen.fingerprints + +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer +import app.revanced.util.fingerprint.LiteralValueFingerprint + +object InterstitialsContainerFingerprint : LiteralValueFingerprint( + returnType = "V", + strings= listOf("overlay_controller_param"), + literalSupplier = { InterstitialsContainer } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/ShowDialogCommandFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/ShowDialogCommandFingerprint.kt new file mode 100644 index 000000000..0cccaf22a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/fullscreen/fingerprints/ShowDialogCommandFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.youtube.ads.fullscreen.fingerprints + +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation +import app.revanced.util.fingerprint.LiteralValueFingerprint + +object ShowDialogCommandFingerprint : LiteralValueFingerprint( + returnType = "V", + literalSupplier = { SlidingDialogAnimation } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt index 06029277f..c3812799c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.youtube.ads.fullscreen.FullscreenAdsPatch import app.revanced.patches.youtube.ads.getpremium.HideGetPremiumPatch import app.revanced.patches.youtube.utils.fix.doublebacktoclose.DoubleBackToClosePatch import app.revanced.patches.youtube.utils.fix.swiperefresh.SwipeRefreshPatch @@ -20,6 +21,7 @@ import org.w3c.dom.Element description = "Adds options to hide general ads.", dependencies = [ DoubleBackToClosePatch::class, + FullscreenAdsPatch::class, GeneralAdsBytecodePatch::class, HideGetPremiumPatch::class, LithoFilterPatch::class, diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/HideGetPremiumPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/HideGetPremiumPatch.kt index 0921519fa..89526b004 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/HideGetPremiumPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/getpremium/HideGetPremiumPatch.kt @@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.music.utils.integrations.Constants import app.revanced.patches.youtube.ads.getpremium.fingerprints.CompactYpcOfferModuleViewFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.util.exception @@ -13,6 +14,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction object HideGetPremiumPatch : BytecodePatch( setOf(CompactYpcOfferModuleViewFingerprint) ) { + private const val FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/AdsFilter;" + override fun execute(context: BytecodeContext) { CompactYpcOfferModuleViewFingerprint.result?.let { @@ -27,7 +31,7 @@ object HideGetPremiumPatch : BytecodePatch( addInstructionsWithLabels( startIndex + 2, """ - invoke-static {}, $COMPONENTS_PATH/AdsFilter;->hideGetPremium()Z + invoke-static {}, $FILTER_CLASS_DESCRIPTOR->hideGetPremium()Z move-result v$tempRegister if-eqz v$tempRegister, :show const/4 v$measuredWidthRegister, 0x0 diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index 4bc01390f..5a8cdb4d6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -12,6 +12,7 @@ import app.revanced.patches.shared.patch.mapping.ResourceType.ID import app.revanced.patches.shared.patch.mapping.ResourceType.INTEGER import app.revanced.patches.shared.patch.mapping.ResourceType.LAYOUT import app.revanced.patches.shared.patch.mapping.ResourceType.STRING +import app.revanced.patches.shared.patch.mapping.ResourceType.STYLE @Patch(dependencies = [ResourceMappingPatch::class]) object SharedResourceIdPatch : ResourcePatch() { @@ -53,6 +54,7 @@ object SharedResourceIdPatch : ResourcePatch() { var InlineTimeBarColorizedBarPlayedColorDark: Long = -1 var InlineTimeBarPlayedNotHighlightedColor: Long = -1 var InsetOverlayViewLayout: Long = -1 + var InterstitialsContainer: Long = -1 var LiveChatButton: Long = -1 var MenuItemView: Long = -1 var MusicAppDeeplinkButtonView: Long = -1 @@ -77,6 +79,7 @@ object SharedResourceIdPatch : ResourcePatch() { var Scrubbing: Long = -1 var SeekUndoEduOverlayStub: Long = -1 var SettingsBooleanTimeRangeDialog: Long = -1 + var SlidingDialogAnimation: Long = -1 var SubtitleMenuSettingsFooterInfo: Long = -1 var SuggestedAction: Long = -1 var TabsBarTextTabView: Long = -1 @@ -139,6 +142,7 @@ object SharedResourceIdPatch : ResourcePatch() { InlineTimeBarPlayedNotHighlightedColor = find(COLOR, "inline_time_bar_played_not_highlighted_color") InsetOverlayViewLayout = find(ID, "inset_overlay_view_layout") + InterstitialsContainer = find(ID, "interstitials_container") LiveChatButton = find(ID, "live_chat_overlay_button") MenuItemView = find(ID, "menu_item_view") MusicAppDeeplinkButtonView = find(ID, "music_app_deeplink_button_view") @@ -163,6 +167,7 @@ object SharedResourceIdPatch : ResourcePatch() { Scrubbing = find(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing") SeekUndoEduOverlayStub = find(ID, "seek_undo_edu_overlay_stub") SettingsBooleanTimeRangeDialog = find(LAYOUT, "setting_boolean_time_range_dialog") + SlidingDialogAnimation = find(STYLE, "SlidingDialogAnimation") SubtitleMenuSettingsFooterInfo = find(STRING, "subtitle_menu_settings_footer_info") SuggestedAction = find(LAYOUT, "suggested_action") TabsBarTextTabView = find(ID, "tabs_bar_text_tab_view") diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 8c7d3c3c7..e8bfcd235 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -429,6 +429,9 @@ Some components may not be hidden." "'For You' shelves are shown." "'For You' shelves are hidden." "Hide 'For You' shelf" + Fullscreen ads are shown. + Fullscreen ads are hidden. + Hide fullscreen ads Fullscreen button is shown. Fullscreen button is hidden. Hide fullscreen button diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index c65844cd5..92e277586 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -7,6 +7,7 @@ PREFERENCE: ADS_SETTINGS -->