diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt new file mode 100644 index 000000000..a0e22f736 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/annotations/AutoCaptionsCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.autocaptions.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.25.34", "17.26.35", "17.27.39", "17.28.34", "17.29.34", "17.32.35", "17.33.42") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class AutoCaptionsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt new file mode 100644 index 000000000..590b2839e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/StartVideoInformerFingerprint.kt @@ -0,0 +1,40 @@ +package app.revanced.patches.youtube.layout.autocaptions.fingerprints + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.layout.autocaptions.annotations.AutoCaptionsCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("start-video-informer-fingerprint") +@MatchingMethod("Laaxf;", "d") +@FuzzyPatternScanMethod(3) +@AutoCaptionsCompatibility +@Version("0.0.1") +object StartVideoInformerFingerprint : MethodFingerprint( + "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L", "L", "L"), listOf( + Opcode.INVOKE_STATIC, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.INVOKE_INTERFACE, + Opcode.IF_EQZ, + Opcode.CONST_STRING, + Opcode.INVOKE_INTERFACE, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.CONST_4, + Opcode.IF_EQ, + Opcode.GOTO, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt new file mode 100644 index 000000000..fec6f6c4b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleButtonControllerFingerprint.kt @@ -0,0 +1,28 @@ +package app.revanced.patches.youtube.layout.autocaptions.fingerprints + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.layout.autocaptions.annotations.AutoCaptionsCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("subtitle-button-controller-fingerprint") +@MatchingMethod("Lcom/google/android/apps/youtube/app/player/overlay/SubtitleButtonController;", "E") +@AutoCaptionsCompatibility +@Version("0.0.1") +object SubtitleButtonControllerFingerprint : MethodFingerprint( + "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.RETURN_VOID, + Opcode.IGET_BOOLEAN, + Opcode.CONST_4, + Opcode.IF_NEZ, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt new file mode 100644 index 000000000..a61000355 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/fingerprints/SubtitleTrackFingerprint.kt @@ -0,0 +1,26 @@ +package app.revanced.patches.youtube.layout.autocaptions.fingerprints + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.layout.autocaptions.annotations.AutoCaptionsCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("subtitle-track-fingerprint") +@MatchingMethod("Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleTrack;", "t") +@AutoCaptionsCompatibility +@Version("0.0.1") +object SubtitleTrackFingerprint : MethodFingerprint( + "Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( + Opcode.CONST_STRING, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.RETURN, + ), + strings = listOf("DISABLE_CAPTIONS_OPTION") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/patch/AutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/patch/AutoCaptionsPatch.kt new file mode 100644 index 000000000..612a5b536 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/patch/AutoCaptionsPatch.kt @@ -0,0 +1,80 @@ +package app.revanced.patches.youtube.layout.autocaptions.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.impl.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.impl.BytecodePatch +import app.revanced.patches.youtube.layout.autocaptions.annotations.AutoCaptionsCompatibility +import app.revanced.patches.youtube.layout.autocaptions.fingerprints.StartVideoInformerFingerprint +import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleButtonControllerFingerprint +import app.revanced.patches.youtube.layout.autocaptions.fingerprints.SubtitleTrackFingerprint +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch +import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource +import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference + +@Patch +@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) +@Name("disable-auto-captions") +@Description("Disable forced captions from being automatically enabled.") +@AutoCaptionsCompatibility +@Version("0.0.1") +class AutoCaptionsPatch : BytecodePatch( + listOf( + StartVideoInformerFingerprint, SubtitleButtonControllerFingerprint, SubtitleTrackFingerprint + ) +) { + override fun execute(data: BytecodeData): PatchResult { + SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( + SwitchPreference( + "revanced_autocaptions_enabled", + StringResource("revanced_autocaptions_enabled_title", "Disable auto-captions"), + false, + StringResource("revanced_autocaptions_summary_on", "Auto-captions are enabled"), + StringResource("revanced_autocaptions_summary_off", "Auto-captions are disabled") + ) + ) + + val startVideoInformerMethod = StartVideoInformerFingerprint.result!!.mutableMethod + + startVideoInformerMethod.addInstructions( + 0, """ + const/4 v0, 0x0 + sput-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z + """ + ) + + val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod + + subtitleButtonControllerMethod.addInstructions( + 0, """ + const/4 v0, 0x1 + sput-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z + """ + ) + + val subtitleTrackMethod = SubtitleTrackFingerprint.result!!.mutableMethod + + subtitleTrackMethod.addInstructions( + 0, """ + invoke-static {}, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->autoCaptionsEnabled()Z + move-result v0 + if-eqz v0, :auto_captions_enabled + sget-boolean v0, Lapp/revanced/integrations/patches/DisableAutoCaptionsPatch;->captionsButtonDisabled:Z + if-nez v0, :auto_captions_enabled + const/4 v0, 0x1 + return v0 + :auto_captions_enabled + nop + """ + ) + + return PatchResultSuccess() + } +} \ No newline at end of file