From 68fdbbb9129387dd3a9d2c5bfa5bbc5aaa695766 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 30 Dec 2023 23:06:30 +0900 Subject: [PATCH] feat(YouTube): add `Remove viewer discretion dialog` patch --- .../dialog/CreateDialogFingerprint.kt | 22 +++++++ ...stractRemoveViewerDiscretionDialogPatch.kt | 53 +++++++++++++++ .../RemoveViewerDiscretionDialogPatch.kt | 64 +++++++++++++++++++ .../fingerprints/AgeRestrictionFingerprint.kt | 26 ++++++++ .../youtube/settings/host/values/strings.xml | 3 + .../youtube/settings/xml/revanced_prefs.xml | 4 ++ 6 files changed, 172 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/shared/fingerprints/dialog/CreateDialogFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/shared/patch/dialog/AbstractRemoveViewerDiscretionDialogPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/general/dialog/RemoveViewerDiscretionDialogPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/general/dialog/fingerprints/AgeRestrictionFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/shared/fingerprints/dialog/CreateDialogFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/dialog/CreateDialogFingerprint.kt new file mode 100644 index 000000000..a7b0f0bd9 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/fingerprints/dialog/CreateDialogFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.shared.fingerprints.dialog + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object CreateDialogFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PROTECTED.value, + parameters = listOf("L", "L", "Ljava/lang/String;"), + opcodes = 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() + ) +) diff --git a/src/main/kotlin/app/revanced/patches/shared/patch/dialog/AbstractRemoveViewerDiscretionDialogPatch.kt b/src/main/kotlin/app/revanced/patches/shared/patch/dialog/AbstractRemoveViewerDiscretionDialogPatch.kt new file mode 100644 index 000000000..5b5938850 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/patch/dialog/AbstractRemoveViewerDiscretionDialogPatch.kt @@ -0,0 +1,53 @@ +package app.revanced.patches.shared.patch.dialog + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.shared.fingerprints.dialog.CreateDialogFingerprint +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +abstract class AbstractRemoveViewerDiscretionDialogPatch( + private val classDescriptor: String, + private val additionalFingerprints: Set = emptySet() +) : BytecodePatch( + buildSet { + add(CreateDialogFingerprint) + additionalFingerprints.let(::addAll) + } +) { + private fun MutableMethod.invoke() { + val showDialogIndex = implementation!!.instructions.indexOfFirst { instruction -> + ((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "show" + } + val dialogRegister = getInstruction(showDialogIndex).registerC + + addInstruction( + showDialogIndex + 1, + "invoke-static { v$dialogRegister }, $classDescriptor->confirmDialog(Landroid/app/AlertDialog;)V", + ) + } + + override fun execute(context: BytecodeContext) { + CreateDialogFingerprint.result?.mutableMethod?.invoke() + ?: throw CreateDialogFingerprint.exception + + if (additionalFingerprints.isNotEmpty()) { + additionalFingerprints.forEach { fingerprint -> + fingerprint.result?.let { + val targetMethod = context.toMethodWalker(it.method) + .nextMethod(it.scanResult.patternScanResult!!.endIndex - 1, true) + .getMethod() as MutableMethod + + targetMethod.invoke() + } ?: throw fingerprint.exception + } + } + + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/dialog/RemoveViewerDiscretionDialogPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/dialog/RemoveViewerDiscretionDialogPatch.kt new file mode 100644 index 000000000..be5fb45cf --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/general/dialog/RemoveViewerDiscretionDialogPatch.kt @@ -0,0 +1,64 @@ +package app.revanced.patches.youtube.general.dialog + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.patch.dialog.AbstractRemoveViewerDiscretionDialogPatch +import app.revanced.patches.youtube.general.dialog.fingerprints.AgeRestrictionFingerprint +import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL +import app.revanced.patches.youtube.utils.settings.SettingsPatch + +@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 = [SettingsPatch::class], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", + [ + "18.25.40", + "18.27.36", + "18.29.38", + "18.30.37", + "18.31.40", + "18.32.39", + "18.33.40", + "18.34.38", + "18.35.36", + "18.36.39", + "18.37.36", + "18.38.44", + "18.39.41", + "18.40.34", + "18.41.39", + "18.42.41", + "18.43.45", + "18.44.41", + "18.45.43" + ] + ) + ] +) +@Suppress("unused") +object RemoveViewerDiscretionDialogPatch : AbstractRemoveViewerDiscretionDialogPatch( + GENERAL, + setOf(AgeRestrictionFingerprint) +) { + override fun execute(context: BytecodeContext) { + super.execute(context) + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE: GENERAL_SETTINGS", + "SETTINGS: REMOVE_VIEWER_DISCRETION_DIALOG" + ) + ) + + SettingsPatch.updatePatchStatus("Remove viewer discretion dialog") + + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/dialog/fingerprints/AgeRestrictionFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/dialog/fingerprints/AgeRestrictionFingerprint.kt new file mode 100644 index 000000000..e2ed0cff7 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/general/dialog/fingerprints/AgeRestrictionFingerprint.kt @@ -0,0 +1,26 @@ +package app.revanced.patches.youtube.general.dialog.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +object AgeRestrictionFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "Ljava/util/Map;"), + opcodes = listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_VIRTUAL, + Opcode.RETURN_VOID + ), + strings = listOf( + "com.google.android.libraries.youtube.rendering.elements.sender_view", + "com.google.android.libraries.youtube.innertube.endpoint.tag", + "com.google.android.libraries.youtube.innertube.bundle", + "com.google.android.libraries.youtube.logging.interaction_logger" + ) +) \ No newline at end of file diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 4a5e83593..4e173e124 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -729,6 +729,9 @@ Tap and hold to set playback speed to 1.0x." Quick actions top margin Quick actions top margin must be between 0-64. Reset to default values. Quick actions + "Remove viewer discretion dialog. +This does not bypass the age restriction, it just accepts it automatically." + Remove viewer discretion dialog Restart to load the layout normally Refresh and restart About diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index dc14abf3d..c2082ad2e 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -244,6 +244,9 @@ + +