diff --git a/api/revanced-patches.api b/api/revanced-patches.api index af672207fb..9a086a7838 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -1088,6 +1088,12 @@ public final class app/revanced/patches/youtube/interaction/copyvideourl/CopyVid public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt new file mode 100644 index 0000000000..1492ea970e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt @@ -0,0 +1,69 @@ +package app.revanced.patches.youtube.interaction.dialog + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.interaction.dialog.fingerprints.CreateDialogFingerprint +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.SettingsPatch +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction + +@Patch( + name = "Remove viewer discretion dialog", + description = "Removes the dialog that appears when you try to watch a video that has been age-restricted " + + "by accepting it automatically. This does not bypass the age restriction.", + dependencies = [IntegrationsPatch::class, SettingsPatch::class], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube" + ) + ] +) +@Suppress("unused") +object RemoveViewerDiscretionDialogPatch : BytecodePatch( + setOf(CreateDialogFingerprint) +) { + private const val INTEGRATIONS_METHOD_DESCRIPTOR = + "Lapp/revanced/integrations/patches/RemoveViewerDiscretionDialogPatch;->" + + "confirmDialog(Landroid/app/AlertDialog;)V" + + override fun execute(context: BytecodeContext) { + SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( + SwitchPreference( + "revanced_remove_viewer_discretion_dialog", + StringResource( + "revanced_remove_viewer_discretion_dialog_title", + "Remove viewer discretion dialog" + ), + StringResource( + "revanced_remove_viewer_discretion_dialog_summary_on", + "Dialog will be removed" + ), + StringResource( + "revanced_remove_viewer_discretion_dialog_summary_off", + "Dialog will be shown" + ), + StringResource( + "revanced_remove_viewer_discretion_dialog_user_dialog_message", + "This does not bypass the age restriction, it just accepts it automatically." + ) + ) + ) + + CreateDialogFingerprint.result?.mutableMethod?.apply { + val showDialogIndex = implementation!!.instructions.lastIndex - 2 + val dialogRegister = getInstruction(showDialogIndex).registerC + + replaceInstructions( + showDialogIndex, + "invoke-static { v$dialogRegister }, $INTEGRATIONS_METHOD_DESCRIPTOR", + ) + } ?: throw CreateDialogFingerprint.exception + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/fingerprints/CreateDialogFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/fingerprints/CreateDialogFingerprint.kt new file mode 100644 index 0000000000..232e65e6a9 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/fingerprints/CreateDialogFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.youtube.interaction.dialog.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object CreateDialogFingerprint : MethodFingerprint( + "V", + AccessFlags.PROTECTED.value, + listOf("L", "L", "Ljava/lang/String;"), + listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL // dialog.show() + ) +)