mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-04 16:44:29 +02:00
feat(Hide ads): add Close fullscreen ads
settings https://github.com/inotia00/ReVanced_Extended/issues/2017
This commit is contained in:
parent
4aa18cce25
commit
c003ad99bc
@ -3,9 +3,8 @@ package app.revanced.patches.music.ads.general
|
|||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
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.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patches.music.ads.general.MusicAdsPatch.hookLithoFullscreenAds
|
||||||
import app.revanced.patches.music.ads.general.fingerprints.AccountMenuFooterFingerprint
|
import app.revanced.patches.music.ads.general.fingerprints.AccountMenuFooterFingerprint
|
||||||
import app.revanced.patches.music.ads.general.fingerprints.FloatingLayoutFingerprint
|
import app.revanced.patches.music.ads.general.fingerprints.FloatingLayoutFingerprint
|
||||||
import app.revanced.patches.music.ads.general.fingerprints.GetPremiumTextViewFingerprint
|
import app.revanced.patches.music.ads.general.fingerprints.GetPremiumTextViewFingerprint
|
||||||
@ -25,6 +24,7 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Interst
|
|||||||
import app.revanced.patches.music.utils.settings.CategoryType
|
import app.revanced.patches.music.utils.settings.CategoryType
|
||||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
import app.revanced.patches.music.utils.settings.SettingsPatch
|
||||||
import app.revanced.patches.shared.litho.LithoFilterPatch
|
import app.revanced.patches.shared.litho.LithoFilterPatch
|
||||||
|
import app.revanced.patches.youtube.ads.general.VideoAdsPatch.hookNonLithoFullscreenAds
|
||||||
import app.revanced.util.getTargetIndex
|
import app.revanced.util.getTargetIndex
|
||||||
import app.revanced.util.getTargetIndexWithReference
|
import app.revanced.util.getTargetIndexWithReference
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
@ -58,11 +58,11 @@ object AdsPatch : BaseBytecodePatch(
|
|||||||
ShowDialogCommandFingerprint
|
ShowDialogCommandFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
private const val ADS_FILTER_CLASS_DESCRIPTOR =
|
||||||
"$COMPONENTS_PATH/AdsFilter;"
|
"$COMPONENTS_PATH/AdsFilter;"
|
||||||
|
|
||||||
private const val FULLSCREEN_ADS_CLASS_DESCRIPTOR =
|
private const val FULLSCREEN_ADS_FILTER_CLASS_DESCRIPTOR =
|
||||||
"$ADS_PATH/FullscreenAdsPatch;"
|
"${app.revanced.patches.shared.integrations.Constants.COMPONENTS_PATH}/FullscreenAdsFilter;"
|
||||||
|
|
||||||
private const val PREMIUM_PROMOTION_POP_UP_CLASS_DESCRIPTOR =
|
private const val PREMIUM_PROMOTION_POP_UP_CLASS_DESCRIPTOR =
|
||||||
"$ADS_PATH/PremiumPromotionPatch;"
|
"$ADS_PATH/PremiumPromotionPatch;"
|
||||||
@ -71,72 +71,18 @@ object AdsPatch : BaseBytecodePatch(
|
|||||||
"$ADS_PATH/PremiumRenewalPatch;"
|
"$ADS_PATH/PremiumRenewalPatch;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
|
||||||
|
|
||||||
// region patch for hide fullscreen ads
|
// region patch for hide fullscreen ads
|
||||||
|
|
||||||
// non-litho view, used in some old clients
|
// non-litho view, used in some old clients
|
||||||
InterstitialsContainerFingerprint.resultOrThrow().let {
|
InterstitialsContainerFingerprint
|
||||||
it.mutableMethod.apply {
|
.resultOrThrow()
|
||||||
val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2
|
.hookNonLithoFullscreenAds(InterstitialsContainer)
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
targetIndex + 1,
|
|
||||||
"invoke-static {v$targetRegister}, $FULLSCREEN_ADS_CLASS_DESCRIPTOR->hideFullscreenAds(Landroid/view/View;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
// litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
||||||
ShowDialogCommandFingerprint.resultOrThrow().let {
|
ShowDialogCommandFingerprint
|
||||||
it.mutableMethod.apply {
|
.resultOrThrow()
|
||||||
// In this method, custom dialog is created and shown.
|
.hookLithoFullscreenAds(context)
|
||||||
// There were no issues despite adding “return-void” to the first index.
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
0,
|
|
||||||
"""
|
|
||||||
invoke-static/range {p2 .. p2}, $FULLSCREEN_ADS_CLASS_DESCRIPTOR->hideFullscreenAds(Ljava/lang/Object;)Z
|
|
||||||
move-result v0
|
|
||||||
if-eqz v0, :show
|
|
||||||
return-void
|
|
||||||
""", ExternalLabel("show", getInstruction(0))
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// val dialogIndex = getTargetIndexWithMethodReferenceName("show")
|
|
||||||
// val dialogReference = getInstruction<ReferenceInstruction>(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<FiveRegisterInstruction>(dialogIndex).registerC
|
|
||||||
// val freeIndex = getTargetIndex(dialogIndex, Opcode.IF_EQZ)
|
|
||||||
// val freeRegister = getInstruction<OneRegisterInstruction>(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
|
|
||||||
// """
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@ -227,11 +173,20 @@ object AdsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
LithoFilterPatch.addFilter(ADS_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
LithoFilterPatch.addFilter(FULLSCREEN_ADS_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ADS,
|
CategoryType.ADS,
|
||||||
"revanced_hide_fullscreen_ads",
|
"revanced_hide_fullscreen_ads",
|
||||||
"true"
|
"true"
|
||||||
)
|
)
|
||||||
|
SettingsPatch.addSwitchPreference(
|
||||||
|
CategoryType.ADS,
|
||||||
|
"revanced_hide_fullscreen_ads_type",
|
||||||
|
"true",
|
||||||
|
"revanced_hide_fullscreen_ads"
|
||||||
|
)
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.ADS,
|
CategoryType.ADS,
|
||||||
"revanced_hide_general_ads",
|
"revanced_hide_general_ads",
|
||||||
|
@ -2,9 +2,16 @@ package app.revanced.patches.music.ads.general.fingerprints
|
|||||||
|
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object ShowDialogCommandFingerprint : LiteralValueFingerprint(
|
internal object ShowDialogCommandFingerprint : LiteralValueFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
parameters = listOf("[B", "L"),
|
parameters = listOf("[B", "L"),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IF_EQ,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.IGET, // get dialog code
|
||||||
|
),
|
||||||
literalSupplier = { SlidingDialogAnimation }
|
literalSupplier = { SlidingDialogAnimation }
|
||||||
)
|
)
|
@ -1,18 +1,28 @@
|
|||||||
package app.revanced.patches.shared.ads
|
package app.revanced.patches.shared.ads
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprintResult
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.shared.ads.fingerprints.MusicAdsFingerprint
|
import app.revanced.patches.shared.ads.fingerprints.MusicAdsFingerprint
|
||||||
import app.revanced.patches.shared.ads.fingerprints.VideoAdsFingerprint
|
import app.revanced.patches.shared.ads.fingerprints.VideoAdsFingerprint
|
||||||
|
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
|
||||||
|
import app.revanced.util.getTargetIndex
|
||||||
|
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
abstract class BaseAdsPatch(
|
abstract class BaseAdsPatch(
|
||||||
@ -59,4 +69,77 @@ abstract class BaseAdsPatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun MethodFingerprintResult.hookNonLithoFullscreenAds(literal: Long) {
|
||||||
|
mutableMethod.apply {
|
||||||
|
val targetIndex = getWideLiteralInstructionIndex(literal) + 2
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
targetIndex + 1,
|
||||||
|
"invoke-static {v$targetRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->hideFullscreenAds(Landroid/view/View;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun MethodFingerprintResult.hookLithoFullscreenAds(context: BytecodeContext) {
|
||||||
|
mutableMethod.apply {
|
||||||
|
val dialogCodeIndex = scanResult.patternScanResult!!.endIndex
|
||||||
|
val dialogCodeField = getInstruction<ReferenceInstruction>(dialogCodeIndex).reference as FieldReference
|
||||||
|
if (dialogCodeField.type != "I")
|
||||||
|
throw PatchException("Invalid dialogCodeField: $dialogCodeField")
|
||||||
|
|
||||||
|
// Disable fullscreen ads
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
move-object v0, p2
|
||||||
|
|
||||||
|
# In the latest version of YouTube and YouTube Music, it is used after being cast
|
||||||
|
|
||||||
|
check-cast v0, ${dialogCodeField.definingClass}
|
||||||
|
iget v0, v0, $dialogCodeField
|
||||||
|
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->disableFullscreenAds(I)Z
|
||||||
|
move-result v0
|
||||||
|
if-eqz v0, :show
|
||||||
|
return-void
|
||||||
|
""", ExternalLabel("show", getInstruction(0))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Close fullscreen ads
|
||||||
|
|
||||||
|
// 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])
|
||||||
|
val dialogIndex = getTargetIndexWithMethodReferenceName("show")
|
||||||
|
val dialogReference = getInstruction<ReferenceInstruction>(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<FiveRegisterInstruction>(dialogIndex).registerC
|
||||||
|
val freeIndex = getTargetIndex(dialogIndex, Opcode.IF_EQZ)
|
||||||
|
val freeRegister = getInstruction<OneRegisterInstruction>(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, v$freeRegister}, $getButtonCall
|
||||||
|
move-result-object v$freeRegister
|
||||||
|
invoke-static {v$freeRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setCloseButton(Landroid/widget/Button;)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
|
"$PATCHES_PATH/FullscreenAdsPatch;"
|
||||||
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ import app.revanced.patches.shared.gms.fingerprints.GmsCoreSupportFingerprint.GE
|
|||||||
import app.revanced.patches.shared.gms.fingerprints.GooglePlayUtilityFingerprint
|
import app.revanced.patches.shared.gms.fingerprints.GooglePlayUtilityFingerprint
|
||||||
import app.revanced.patches.shared.gms.fingerprints.PrimeMethodFingerprint
|
import app.revanced.patches.shared.gms.fingerprints.PrimeMethodFingerprint
|
||||||
import app.revanced.patches.shared.gms.fingerprints.ServiceCheckFingerprint
|
import app.revanced.patches.shared.gms.fingerprints.ServiceCheckFingerprint
|
||||||
import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_PATH
|
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
|
||||||
import app.revanced.patches.shared.packagename.PackageNamePatch
|
import app.revanced.patches.shared.packagename.PackageNamePatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
@ -106,7 +106,7 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
|
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
|
||||||
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
||||||
1, // Hack to not disturb other patches (such as the YTMusic integrations patch).
|
1, // Hack to not disturb other patches (such as the YTMusic integrations patch).
|
||||||
"invoke-static/range { p0 .. p0 }, $INTEGRATIONS_PATH/patches/GmsCoreSupport;->" +
|
"invoke-static/range { p0 .. p0 }, $PATCHES_PATH/GmsCoreSupport;->" +
|
||||||
"checkGmsCore(Landroid/app/Activity;)V",
|
"checkGmsCore(Landroid/app/Activity;)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package app.revanced.patches.shared.integrations
|
package app.revanced.patches.shared.integrations
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate", "SpellCheckingInspection")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
object Constants {
|
object Constants {
|
||||||
const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/shared"
|
const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/shared"
|
||||||
const val COMPONENTS_PATH = "$INTEGRATIONS_PATH/patches/components"
|
const val PATCHES_PATH = "$INTEGRATIONS_PATH/patches"
|
||||||
|
const val COMPONENTS_PATH = "$PATCHES_PATH/components"
|
||||||
|
|
||||||
const val INTEGRATIONS_SETTING_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/settings/Setting;"
|
const val INTEGRATIONS_SETTING_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/settings/Setting;"
|
||||||
const val INTEGRATIONS_UTILS_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/utils/Utils;"
|
const val INTEGRATIONS_UTILS_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/utils/Utils;"
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package app.revanced.patches.youtube.ads.general
|
package app.revanced.patches.youtube.ads.general
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
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.addInstructionsWithLabels
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
|
import app.revanced.patches.music.ads.general.MusicAdsPatch.hookLithoFullscreenAds
|
||||||
|
import app.revanced.patches.youtube.ads.general.VideoAdsPatch.hookNonLithoFullscreenAds
|
||||||
import app.revanced.patches.youtube.ads.general.fingerprints.CompactYpcOfferModuleViewFingerprint
|
import app.revanced.patches.youtube.ads.general.fingerprints.CompactYpcOfferModuleViewFingerprint
|
||||||
import app.revanced.patches.youtube.ads.general.fingerprints.InterstitialsContainerFingerprint
|
import app.revanced.patches.youtube.ads.general.fingerprints.InterstitialsContainerFingerprint
|
||||||
import app.revanced.patches.youtube.ads.general.fingerprints.ShowDialogCommandFingerprint
|
import app.revanced.patches.youtube.ads.general.fingerprints.ShowDialogCommandFingerprint
|
||||||
@ -15,11 +16,9 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
|||||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AdAttribution
|
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AdAttribution
|
||||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer
|
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer
|
||||||
import app.revanced.util.findMutableMethodOf
|
import app.revanced.util.findMutableMethodOf
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
|
||||||
import app.revanced.util.injectHideViewCall
|
import app.revanced.util.injectHideViewCall
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
@ -37,34 +36,14 @@ object AdsBytecodePatch : BytecodePatch(
|
|||||||
// region patch for hide fullscreen ads
|
// region patch for hide fullscreen ads
|
||||||
|
|
||||||
// non-litho view, used in some old clients.
|
// non-litho view, used in some old clients.
|
||||||
InterstitialsContainerFingerprint.resultOrThrow().let {
|
InterstitialsContainerFingerprint
|
||||||
it.mutableMethod.apply {
|
.resultOrThrow()
|
||||||
val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2
|
.hookNonLithoFullscreenAds(InterstitialsContainer)
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
|
||||||
|
|
||||||
addInstruction(
|
|
||||||
targetIndex + 1,
|
|
||||||
"invoke-static {v$targetRegister}, $ADS_CLASS_DESCRIPTOR->hideFullscreenAds(Landroid/view/View;)V"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
// litho view, used in 'ShowDialogCommandOuterClass' in innertube
|
||||||
ShowDialogCommandFingerprint.resultOrThrow().let {
|
ShowDialogCommandFingerprint
|
||||||
it.mutableMethod.apply {
|
.resultOrThrow()
|
||||||
// In this method, custom dialog is created and shown.
|
.hookLithoFullscreenAds(context)
|
||||||
// There were no issues despite adding “return-void” to the first index.
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
0,
|
|
||||||
"""
|
|
||||||
invoke-static/range {p2 .. p2}, $ADS_CLASS_DESCRIPTOR->hideFullscreenAds(Ljava/lang/Object;)Z
|
|
||||||
move-result v0
|
|
||||||
if-eqz v0, :show
|
|
||||||
return-void
|
|
||||||
""", ExternalLabel("show", getInstruction(0))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
@ -47,11 +47,15 @@ object AdsPatch : BaseResourcePatch(
|
|||||||
"Top"
|
"Top"
|
||||||
)
|
)
|
||||||
|
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
private const val ADS_FILTER_CLASS_DESCRIPTOR =
|
||||||
"$COMPONENTS_PATH/AdsFilter;"
|
"$COMPONENTS_PATH/AdsFilter;"
|
||||||
|
|
||||||
|
private const val FULLSCREEN_ADS_FILTER_CLASS_DESCRIPTOR =
|
||||||
|
"${app.revanced.patches.shared.integrations.Constants.COMPONENTS_PATH}/FullscreenAdsFilter;"
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
LithoFilterPatch.addFilter(ADS_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
LithoFilterPatch.addFilter(FULLSCREEN_ADS_FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
context.forEach {
|
context.forEach {
|
||||||
|
|
||||||
|
@ -1,9 +1,28 @@
|
|||||||
package app.revanced.patches.youtube.ads.general.fingerprints
|
package app.revanced.patches.youtube.ads.general.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
|
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
internal object ShowDialogCommandFingerprint : LiteralValueFingerprint(
|
internal object ShowDialogCommandFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
literalSupplier = { SlidingDialogAnimation }
|
opcodes = listOf(
|
||||||
|
Opcode.IF_EQ,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.IGET, // get dialog code
|
||||||
|
),
|
||||||
|
// 18.43 and earlier has a different first parameter.
|
||||||
|
// Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures.
|
||||||
|
customFingerprint = custom@{ methodDef, _ ->
|
||||||
|
if (!methodDef.containsWideLiteralInstructionIndex(SlidingDialogAnimation)) {
|
||||||
|
return@custom false
|
||||||
|
}
|
||||||
|
// 18.43 and earlier parameters are: "L", "L"
|
||||||
|
// 18.44+ parameters are "[B", "L"
|
||||||
|
val parameterTypes = methodDef.parameterTypes
|
||||||
|
|
||||||
|
parameterTypes.size == 2 && parameterTypes[1].startsWith("L")
|
||||||
|
},
|
||||||
)
|
)
|
@ -58,6 +58,11 @@ Please download %2$s from the website."</string>
|
|||||||
|
|
||||||
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
|
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
|
||||||
<string name="revanced_hide_fullscreen_ads_summary">Hides fullscreen ads.</string>
|
<string name="revanced_hide_fullscreen_ads_summary">Hides fullscreen ads.</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_type_title">Close fullscreen ads</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_type_summary">"If it is enabled, fullscreen ads are closed through the Close button.
|
||||||
|
If it is disabled, fullscreen ads are blocked. (there may be side effects)"</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_blocked_success">Fullscreen ads have been blocked. (DialogType: %s)</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_closed_success">Fullscreen ads have been closed.</string>
|
||||||
<string name="revanced_hide_general_ads_title">Hide general ads</string>
|
<string name="revanced_hide_general_ads_title">Hide general ads</string>
|
||||||
<string name="revanced_hide_general_ads_summary">Hides general ads.</string>
|
<string name="revanced_hide_general_ads_summary">Hides general ads.</string>
|
||||||
<string name="revanced_hide_music_ads_title">Hide media ads</string>
|
<string name="revanced_hide_music_ads_title">Hide media ads</string>
|
||||||
|
@ -21,6 +21,13 @@
|
|||||||
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
|
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
|
||||||
<string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden.</string>
|
<string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden.</string>
|
||||||
<string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown.</string>
|
<string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown.</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_type_title">Close fullscreen ads</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_type_summary_on">Fullscreen ads are closed through the Close button.</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_type_summary_off">"Fullscreen ads are blocked.
|
||||||
|
|
||||||
|
Limitation: Community post image on the fullscreen may be blocked."</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_blocked_success">Fullscreen ads have been blocked. (DialogType: %s)</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_closed_success">Fullscreen ads have been closed.</string>
|
||||||
<string name="revanced_hide_general_ads_title">Hide general ads</string>
|
<string name="revanced_hide_general_ads_title">Hide general ads</string>
|
||||||
<string name="revanced_hide_general_ads_summary_on">General ads are hidden.</string>
|
<string name="revanced_hide_general_ads_summary_on">General ads are hidden.</string>
|
||||||
<string name="revanced_hide_general_ads_summary_off">General ads are shown.</string>
|
<string name="revanced_hide_general_ads_summary_off">General ads are shown.</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user