feat(Hide ads): add Close fullscreen ads settings https://github.com/inotia00/ReVanced_Extended/issues/2017

This commit is contained in:
inotia00 2024-06-11 03:01:50 +09:00
parent 4aa18cce25
commit c003ad99bc
10 changed files with 163 additions and 103 deletions

View File

@ -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",

View File

@ -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 }
) )

View File

@ -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;"
}
} }

View File

@ -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",
) )

View File

@ -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;"

View File

@ -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

View File

@ -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 {

View File

@ -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")
},
) )

View File

@ -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>

View File

@ -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>